2014-01-07 58 views
-1

下面的代碼最初由Dominic Kexel發佈。我修改了一些代碼,試圖讓玩家按鼠標方向旋轉。但它似乎給了一個奇怪的行爲(調整播放器和旋轉)。Pygame玩家旋轉鼠標相機

WIN_WIDTH = 800 
WIN_HEIGHT = 640 
HALF_WIDTH = int(WIN_WIDTH/2) 
HALF_HEIGHT = int(WIN_HEIGHT/2) 

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) 
DEPTH = 32 
FLAGS = 0 
CAMERA_SLACK = 30 

def main(): 
    global cameraX, cameraY 
    pygame.init() 
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
    pygame.display.set_caption("Use arrows to move!") 
    timer = pygame.time.Clock() 

    up = down = left = right = running = False 
    bg = Surface((32,32)) 
    bg.convert() 
    bg.fill(Color("#000000")) 
    entities = pygame.sprite.Group() 
    player = Player(32, 32) 
    platforms = [] 

    x = y = 0 
    level = [ 
     "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P     PPPPPPPPPPP   P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P PPPPPPPP        P", 
     "P           P", 
     "P       PPPPPPP   P", 
     "P     PPPPPP     P", 
     "P           P", 
     "P   PPPPPPP       P", 
     "P           P", 
     "P      PPPPPP    P", 
     "P           P", 
     "P PPPPPPPPPPP       P", 
     "P           P", 
     "P     PPPPPPPPPPP    P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",] 
    # build the level 
    for row in level: 
     for col in row: 
      if col == "P": 
       p = Platform(x, y) 
       platforms.append(p) 
       entities.add(p) 
      if col == "E": 
       e = ExitBlock(x, y) 
       platforms.append(e) 
       entities.add(e) 
      x += 32 
     y += 32 
     x = 0 

    total_level_width = len(level[0])*32 
    total_level_height = len(level)*32 
    camera = Camera(complex_camera, total_level_width, total_level_height) 
    entities.add(player) 

    while 1: 
     timer.tick(60) 

     for e in pygame.event.get(): 
      if e.type == QUIT: raise SystemExit, "QUIT" 
      if e.type == KEYDOWN and e.key == K_ESCAPE: 
       raise SystemExit, "ESCAPE" 
      if e.type == KEYDOWN and e.key == K_UP: 
       up = True 
      if e.type == KEYDOWN and e.key == K_DOWN: 
       down = True 
      if e.type == KEYDOWN and e.key == K_LEFT: 
       left = True 
      if e.type == KEYDOWN and e.key == K_RIGHT: 
       right = True 
      if e.type == KEYDOWN and e.key == K_SPACE: 
       running = True 

      if e.type == KEYUP and e.key == K_UP: 
       up = False 
      if e.type == KEYUP and e.key == K_DOWN: 
       down = False 
      if e.type == KEYUP and e.key == K_RIGHT: 
       right = False 
      if e.type == KEYUP and e.key == K_LEFT: 
       left = False 

     # draw background 
     for y in range(32): 
      for x in range(32): 
       screen.blit(bg, (x * 32, y * 32)) 

     camera.update(player) 

     # update player, draw everything else 
     player.update(up, down, left, right, running, platforms) 
     for e in entities: 
      screen.blit(e.image, camera.apply(e)) 

     pygame.display.update() 

class Camera(object): 
    def __init__(self, camera_func, width, height): 
     self.camera_func = camera_func 
     self.state = Rect(0, 0, width, height) 

    def apply(self, target): 
     return target.rect.move(self.state.topleft) 

    def update(self, target): 
     self.state = self.camera_func(self.state, target.rect) 

def simple_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h) 

def complex_camera(camera, target_rect): 
    l, t, _, _ = target_rect 
    _, _, w, h = camera 
    l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h 

    l = min(0, l)       # stop scrolling at the left edge 
    l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge 
    t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom 
    t = min(0, t)       # stop scrolling at the top 
    return Rect(l, t, w, h) 

class Entity(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 

class Player(Entity): 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.xvel = 0 
     self.yvel = 0 
     self.onGround = False 
     self.oimage = Surface((32,32)) 
     #self.image.fill(Color("#0000FF")) 
     pygame.draw.circle(self.oimage, Color("#ffff00"), (x-16, y-16), 16, 0) 
     pygame.draw.circle(self.oimage, Color("#0000FF"), (x-16, y-24), 4, 0) 
     self.oimage.convert() 
     self.image ="" 
     self.rect = Rect(x, y, 32, 32) 

    def update(self, up, down, left, right, running, platforms): 
     if up: 
      # only jump if on the ground 
      if self.onGround: self.yvel -= 10 
     if down: 
      pass 
     if running: 
      self.xvel = 12 
     if left: 
      self.xvel = -8 
     if right: 
      self.xvel = 8 
     if not self.onGround: 
      # only accelerate with gravity if in the air 
      self.yvel += 0.3 
      # max falling speed 
      if self.yvel > 100: self.yvel = 100 
     if not(left or right): 
      self.xvel = 0 
     # increment in x direction 
     self.rect.left += self.xvel 
     # do x-axis collisions 
     self.collide(self.xvel, 0, platforms) 
     # increment in y direction 
     self.rect.top += self.yvel 
     # assuming we're in the air 
     self.onGround = False; 
     # do y-axis collisions 
     self.collide(0, self.yvel, platforms) 


     #Rotate code 
     position = pygame.mouse.get_pos() 
     PlayerCent = self.rect.center 
     angle = math.atan2(position[1]-(PlayerCent[1]+ self.rect.width/2),position[0]-(PlayerCent[0]+ self.rect.height/2)) 
     self.image= pygame.transform.rotate(self.oimage, 360-angle*57.29) 



    def collide(self, xvel, yvel, platforms): 
     for p in platforms: 
      if pygame.sprite.collide_rect(self, p): 
       if isinstance(p, ExitBlock): 
        pygame.event.post(pygame.event.Event(QUIT)) 
       if xvel > 0: 
        self.rect.right = p.rect.left 
        print "collide right" 
       if xvel < 0: 
        self.rect.left = p.rect.right 
        print "collide left" 
       if yvel > 0: 
        self.rect.bottom = p.rect.top 
        self.onGround = True 
        self.yvel = 0 
       if yvel < 0: 
        self.rect.top = p.rect.bottom 


class Platform(Entity): 
    def __init__(self, x, y): 
     Entity.__init__(self) 
     self.image = Surface((32, 32)) 
     self.image.convert() 
     self.image.fill(Color("#DDDDDD")) 
     self.rect = Rect(x, y, 32, 32) 

    def update(self): 
     pass 

class ExitBlock(Platform): 
    def __init__(self, x, y): 
     Platform.__init__(self, x, y) 
     self.image.fill(Color("#0033FF")) 

if __name__ == "__main__": 
    main() 
+0

「但好像給一個奇怪的行爲」可能提供的這一關行爲的描述,輸入/輸出/預期輸出/錯誤/堆棧跟蹤的東西來幫助你,這不只是你的代碼轉儲。 –

+0

奇怪的行爲是「(調整播放器大小和旋轉)」 – DomaNitro

回答

0

這是正常行爲。從pygame的文檔:

pygame.transform.rotate() 
rotate an image 
rotate(Surface, angle) -> Surface 

未過濾逆時針旋轉。角度參數表示 度,可以是任何浮點值。負角度量 將順時針旋轉。

除非以90度遞增旋轉,否則圖像將被填充較大以保持新的尺寸。如果圖像具有像素alpha,則填充的 區域將是透明的。否則,pygame會選擇一個顏色, 匹配表面顏色鍵或像素值。

如果你想保持相同的圖像尺寸旋轉之後就可以做一些沿着這些路線:

def rot_center(image, angle): 
    """rotate an image while keeping its center and size""" 
    orig_rect = image.get_rect() 
    rot_image = pygame.transform.rotate(image, angle) 
    rot_rect = orig_rect.copy() 
    rot_rect.center = rot_image.get_rect().center 
    rot_image = rot_image.subsurface(rot_rect).copy() 
    return rot_image