嘿伙计我在pygame上遇到碰撞问题需要帮助。 我有一个边界图,通过使用蒙版重叠来设置像素完美碰撞。检测到碰撞时没有任何问题,但是当要阻止玩家穿过墙壁时,总会有某种方式通过它发送。我做了几次尝试(其中很多都是真的),包括当你一次按下三个按钮以避免它出现时,甚至冻结了播放器,但无济于事。
现在,我检查用户按下哪个按钮来设置方向:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
key = pygame.key.get_pressed()
if key[pygame.K_w]:
COLLISION_DIRECTION = "UP"
if key[pygame.K_s]:
COLLISION_DIRECTION = "DOWN"
if key[pygame.K_d]:
COLLISION_DIRECTION = "RIGHT"
if key[pygame.K_a]:
COLLISION_DIRECTION = "LEFT"
然后根据方向检查碰撞。在我最后的绝望尝试中,我使用了保存阵列上的最后一个非碰撞位置,将世界(我移动世界,而不是玩家)转换到该位置并减去或增加移动速度:
if boundariesMap_mask.overlap(player.mask, (offset_x, offset_y)) is None:
lastPos = [world.x, world.y]
else:
while COLLISION_DIRECTION == "UP":
world.y = (lastPos[1]-DIST_WORLD)
break
while COLLISION_DIRECTION == "DOWN":
world.y = (lastPos[1]+DIST_WORLD)
break
while COLLISION_DIRECTION == "LEFT":
world.x = (lastPos[0]-DIST_WORLD)
break
while COLLISION_DIRECTION == "RIGHT":
world.x = (lastPos[0]+DIST_WORLD)
break
我最好的猜测是,我应该在移回安全位置时阻止所有额外输入,以避免更改COLLISION_DIRECTION。 你能帮我个忙吗?
world.x和world.y是世界的变量坐标
编辑:我忘了添加世界构造函数类
class World(pygame.sprite.Sprite):
def __init__(self):
self.sprite = pygame.image.load('bin\\assets\\test.png')
self.x = 220
self.y = 45
def draw(self, surface):
surface.blit(self.sprite, (self.x, self.y))
def handle_keys(self):
key = pygame.key.get_pressed()
if pygame.joystick.get_count():
joystick_x = round(my_joystick.get_axis(0))
joystick_y = round(my_joystick.get_axis(1))
if joystick_x < 0:
self.x += DIST_WORLD
if joystick_x > 0:
self.x -= DIST_WORLD
if joystick_y < 0:
self.y += DIST_WORLD
if joystick_y > 0:
self.y -= DIST_WORLD
if key[pygame.K_w]:
self.y += DIST_WORLD
if key[pygame.K_s]:
self.y -= DIST_WORLD
if key[pygame.K_a]:
self.x += DIST_WORLD
if key[pygame.K_d]:
self.x -= DIST_WORLD
答案 0 :(得分:1)
根据问题和评论中的回答判断,只要注册了三个或更多按键,就会触发故障,从而导致COLLISION_DIRECTION
和World.y
以及World.x
不恰当地更新。
考虑这样一个事实:如果玩家沿X轴或Y轴的某个方向移动,它们不能同时向相反的方向移动。还要考虑这样一个事实:如果玩家同时按下多个键,主游戏循环中的代码允许覆盖COLLISION_DIRECTION
的值;例如,如果同时按住W,A和S,则最终COLLISION_DIRECTION
将为"LEFT"
。
我假设你允许对角线运动,所以我们想要做的是使COLLISION_DETECTION
同时对x轴和y轴有意义。然后,我们必须将按键检查的数量限制为两个(一次用于x轴,一次用于y轴),这样三按钮问题就不会发生。
在你的主游戏循环中:
## Instead of one COLLISION_DIRECTION, we now have two separate variables:
## COLLISION_DIRECTION_X and COLLISION_DIRECTION_Y
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
key = pygame.key.get_pressed()
## Using elif so we don't mess up COLLISION_DIRECTION_Y
if key[pygame.K_w]:
COLLISION_DIRECTION_Y = "UP"
elif key[pygame.K_s]:
COLLISION_DIRECTION_Y = "DOWN"
## Using elif so we don't mess up COLLISION_DIRECTION_X
if key[pygame.K_d]:
COLLISION_DIRECTION_X = "RIGHT"
elif key[pygame.K_a]:
COLLISION_DIRECTION_X = "LEFT"
相应地更新碰撞检测:
if boundariesMap_mask.overlap(player.mask, (offset_x, offset_y)) is None:
lastPos = [world.x, world.y]
else:
## Redundant while-break replaced with simple if-statements;
## Using while is not exactly necessary because we carry out
## these statements each frame
if COLLISION_DIRECTION_Y == "UP":
world.y = (lastPos[1]-DIST_WORLD)
elif COLLISION_DIRECTION_Y == "DOWN":
world.y = (lastPos[1]+DIST_WORLD)
if COLLISION_DIRECTION_X == "LEFT":
world.x = (lastPos[0]-DIST_WORLD)
elif COLLISION_DIRECTION_X == "RIGHT":
world.x = (lastPos[0]+DIST_WORLD)
然后,在handle_keys
函数中:
def handle_keys(self):
key = pygame.key.get_pressed()
if pygame.joystick.get_count():
joystick_x = round(my_joystick.get_axis(0))
joystick_y = round(my_joystick.get_axis(1))
## Restrict joystick x-input checking, because we logically
## cannot be both greater and less than zero
if joystick_x < 0:
self.x += DIST_WORLD
elif joystick_x > 0:
self.x -= DIST_WORLD
## Restrict joystick y-input checking, because we logically
## cannot be both greater and less than zero
if joystick_y < 0:
self.y += DIST_WORLD
elif joystick_y > 0:
self.y -= DIST_WORLD
## Restrict keypress vertical axis checking for the same reason
if key[pygame.K_w]:
self.y += DIST_WORLD
elif key[pygame.K_s]:
self.y -= DIST_WORLD
## Restrict keypress horizontal axis checking for same reason
if key[pygame.K_a]:
self.x += DIST_WORLD
elif key[pygame.K_d]:
self.x -= DIST_WORLD
我希望这有帮助!如果代码没有这样做,我道歉,但至少,我希望我在代码之前的评论提供一些见解。