我试图在Pygame中创建一个有效的跳跃系统,但我在碰撞检测方面遇到了一些问题。我有一个存储在这样的列表中的级别:
level = [
"WWWWWWWWWWWWWWWWWWWW",
"W W",
"W W",
"W W",
"W W",
"W W",
"W W",
"W W",
"W W",
"W W",
"WWWWWWWWWWWWWWWWWWWW",
]
x = y = 0
for row in level:
for col in row:
if col == "W":
Wall((x, y))
x += 32
y += 32
x = 0
每个墙都附加到列表中,并根据其在网格中的位置给出位置。
这是墙类:
class Wall (pygame.sprite.Sprite):
def __init__(self,pos):
pygame.sprite.Sprite.__init__(self)
walls.append(self)
self.rect = pygame.Rect(pos[0],pos[1],32,32)
当按下向上键并且检测到播放器与其中一个图块之间发生碰撞时,我尝试将播放器向上移动30个像素:
if event.type == KEYDOWN and event.key == K_UP:
if player.hitCheck():
player.move(0,-30)
hitCheck()是Player类的一个函数,如下所示:
def hitCheck(self):
for wall in walls:
if self.rect.colliderect(wall.rect):
return True
但是,无论是否有任何实际碰撞,该函数都不会返回True。通过将碰撞玩家端的值设置为相关墙侧的值,我可以移动玩家矩形而不会穿过墙壁,但这不会产生任何结果。
为什么函数在碰撞时返回True?
wall最初被声明为空列表。它在移动函数中使用,它是播放器类的一部分:
def move_single_axis(self, dx, dy):
# Move the rect
self.rect.x += dx
self.rect.y += dy
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
这没有问题,这就是为什么我无法理解为什么hitCheck()无法检测到碰撞。
答案 0 :(得分:1)
你在哪里宣布墙?它是一个全局变量吗?由于墙也是精灵的一部分,您可以使用spritecollide
代替colliderect
:
def hitCheck(self):
if pygame.sprite.spritecollide(self, self.walls):
return True
答案 1 :(得分:1)
找出问题所在。移动功能可自动防止碰撞,这就是从未检测到的原因。当self.rect.bottom设置为wall.rect.top时,通过将var转为True来绕过这个。