2015-10-23 41 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