2015-10-23 57 views
0

我正在開始一個角色扮演遊戲,當角色對着牆壁跑向任何一邊時,我無法讓玩家順利地上下移動。此外,在按住上下鍵並向北或向南跑牆時,角色無法平穩地向左或向右移動。左右移動時無法上下移動

我試過不同配置的'移動'功能沒有成功。我知道爲什麼算法不起作用,我只是不知道如何構建分支,以便在向右運行時設置'self.rect.right = p.rect.left'而不設置'self .rect.bottom = p.rect.top'在下一次調用'move()'的時候,當我開始在牆上跑時按下按鈕。

def move(self, x, y, platforms): 
     self.rect.left += x 
     self.rect.top += y 

     for p in platforms: 
      if pygame.sprite.collide_rect(self, p): 
       if isinstance(p, ExitBlock): 
        pygame.event.post(pygame.event.Event(QUIT)) 

       if self.x > 0: # Moving right 
        self.rect.right = p.rect.left 
       if self.x < 0: # Moving left 
        self.rect.left = p.rect.right 

       if self.y > 0: # Moving down 
        self.rect.bottom = p.rect.top 
       if self.y < 0: # Moving up 
        self.rect.top = p.rect.bottom 

這裏展示的代碼可以運行看不受歡迎的行爲:

#! /usr/bin/python 

import pygame, platform, sys 
platform.architecture() 

from pygame import * 

import spritesheet 
from sprite_strip_anim import SpriteStripAnim 

WIN_W = 1400 
WIN_H = 800 
HALF_W = int(WIN_W/2) 
HALF_H = int(WIN_H/2) 

DEPTH = 32 
FLAGS = 0 
CAMERA_SLACK = 30 

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.x = 0 
     self.y = 0 
     self.onGround = False 
     self.image = Surface((32,32)) 
     self.image.fill(Color("#0000FF")) 
     self.image.convert() 
     self.rect = Rect(x, y, 32, 32) 

    def update(self, up, down, left, right, running, platforms): 
     if up: 
      self.y = -5 
     if down: 
      self.y = 5 
     if left: 
      self.x = -5 
     if right: 
      self.x = 5 
     if not(left or right): 
      self.x = 0 
     if not(up or down): 
      self.y = 0 

     self.move(self.x, 0, platforms) 
     self.move(0, self.y, platforms) 

    def move(self, x, y, platforms): 
     self.rect.left += x 
     self.rect.top += y 

     for p in platforms: 
      if pygame.sprite.collide_rect(self, p): 
       if isinstance(p, ExitBlock): 
        pygame.event.post(pygame.event.Event(QUIT)) 

       if self.x > 0: # Moving right 
        self.rect.right = p.rect.left 
       if self.x < 0: # Moving left 
        self.rect.left = p.rect.right 

       if self.y > 0: # Moving down 
        self.rect.bottom = p.rect.top 
       if self.y < 0: # Moving up 
        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")) 


def main(): 
    pygame.init 

    screen = pygame.display.set_mode((WIN_W, WIN_H), 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 

    entities.add(player) 

    while 1: 
     timer.tick(60) 

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

     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_w: 
       up = True 
       down = False 
      if e.type == KEYDOWN and e.key == K_s: 
       down = True 
       up = False 
      if e.type == KEYDOWN and e.key == K_a: 
       left = True 
       right = False 
      if e.type == KEYDOWN and e.key == K_d: 
       right = True 
       left = False 

      if e.type == KEYUP and e.key == K_w: 
       up = False 
      if e.type == KEYUP and e.key == K_s: 
       down = False 
      if e.type == KEYUP and e.key == K_d: 
       right = False 
      if e.type == KEYUP and e.key == K_a: 
       left = False 

     # update player, draw everything else 
     player.update(up, down, left, right, running, platforms) 

     for e in entities: 
      screen.blit(e.image, e.rect) 

     pygame.display.update() 


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

這是很多的代碼來通讀和原因; [你應該修剪一些脂肪](http://stackoverflow.com/help/mcve)讓我們更容易幫助你(例如,我很確定這段代碼中的所有涉及圖像和顏色的東西都是與這個問題無關)。 – JesseTG

+0

我剛剛運行了這段代碼,我可以上下左右移動。它沿對角線移動。有時候碰壁會讓你跳躍。 – cmd

+0

這就是我想要解決的問題。我希望能夠在左邊的牆上跑,然後同時向上推並讓角色跑向牆上。看一個移動方法,你會看到,當我開始按下時按住左邊,同時碰撞牆壁,分支設置矩形的y值。 – daniel

回答

0

找到問題@http://pygame.org/project-Rect+Collision+Response-1061-.html的算法:

def move(self, dx, dy): 

    # Move each axis separately. Note that this checks for collisions both times. 
    if dx != 0: 
     self.move_single_axis(dx, 0) 
    if dy != 0: 
     self.move_single_axis(0, dy) 

def move_single_axis(self, dx, dy): 

    # Move the rect 
    self.rect.x += dx 
    self.rect.y += dy 

    # If you collide with a wall, move out based on velocity 
    for wall in walls: 
     if self.rect.colliderect(wall.rect): 
      if dx > 0: # Moving right; Hit the left side of the wall 
       self.rect.right = wall.rect.left 
      if dx < 0: # Moving left; Hit the right side of the wall 
       self.rect.left = wall.rect.right 
      if dy > 0: # Moving down; Hit the top side of the wall 
       self.rect.bottom = wall.rect.top 
      if dy < 0: # Moving up; Hit the bottom side of the wall 
       self.rect.top = wall.rect.bottom