在向左或向右移动时无法上下移动

时间:2015-10-23 21:48:16

标签: python pygame game-physics

我正在开始一个角色扮演游戏,当角色在任何一侧的墙上奔跑时,我无法让玩家顺利上下移动。此外,角色不能平稳地向左或向右移动,同时按住上下键并靠近墙壁向北或向南移动。

我尝试了不同的“移动”配置。功能没有成功。我知道算法为什么不起作用,我只是无法弄清楚如何构造分支,这样当向右运行时,它会设置自我。直接。立即=正确。左'没有设置' 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()

1 个答案:

答案 0 :(得分: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