Pygame 垂直碰撞
Pygame vertical collisions
我有一个代码可以让玩家在没有重力的情况下在二维空间中移动(比如 Isaac 或 World Hardest Game)。问题是与地图中的图块 (celle) 发生碰撞:
def collisions(self):
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0:
player.rect.left = cell.rect.right
elif player.direction.x > 0:
player.rect.right = cell.rect.left
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
player.rect.bottom = cell.rect.top
如果玩家仅在 x 方向或仅在 y 方向发生碰撞,它就可以正常工作,但当它垂直移动时,它会传送到另一侧。发生这种情况是因为当它在 y 侧发生碰撞时,如果它也在 x 方向移动,则会触发 x 碰撞算法。所以我尝试使用 bool 来检查 x 或 y 碰撞:
def collisions(self):
global collx, colly
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0 and colly == False:
player.rect.left = cell.rect.right
collx=True
elif player.direction.x > 0 and colly == False:
player.rect.right = cell.rect.left
collx=True
else:
collx=False
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
colly=True
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
colly=True
player.rect.bottom = cell.rect.top
else:
colly=False
效果更好,但是 False 条件没有正确出现,我认为这是因为代码在 for 循环中,但我真的不知道该怎么做。代码太长并且包含图像,所以我没有 post 它。
播放器中的移动功能class:
def movement(self):
key_input=pygame.key.get_pressed()
if key_input[pygame.K_a] or key_input[pygame.K_d]:
if key_input[pygame.K_a]:
self.direction.x = -1
if key_input[pygame.K_w] or key_input[pygame.K_s]:
self.rect.x += -self.velx_diag
else:
self.rect.x += -self.velx
if key_input[pygame.K_d]:
self.direction.x = 1
if key_input[pygame.K_w] or key_input[pygame.K_s]:
self.rect.x += self.velx_diag
else:
self.rect.x += self.velx
else:
self.direction.x = 0
if key_input[pygame.K_w] or key_input[pygame.K_s]:
if key_input[pygame.K_w]:
self.direction.y = -1
if key_input[pygame.K_a] or key_input[pygame.K_d]:
self.rect.y += -self.vely_diag
else:
self.rect.y += -self.vely
if key_input[pygame.K_s]:
self.direction.y = 1
if key_input[pygame.K_a] or key_input[pygame.K_d]:
self.rect.y += self.vely_diag
else:
self.rect.y += self.vely
else:
self.direction.y = 0
我知道处理 2d 碰撞的最好方法是在一个轴上移动玩家,检查碰撞,然后在另一个轴上移动玩家:
def collision_x(self):
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0:
player.rect.left = cell.rect.right
elif player.direction.x > 0:
player.rect.right = cell.rect.left
# make two different methods for x and y collision.
def collision_y(self):
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
player.rect.bottom = cell.rect.top
然后在移动方法中你需要单独调用它们:
还有你的移动功能我觉得有点乱,所以我稍微清理了一下(如果你不喜欢它,你也可以使用你的功能,它工作得很好。)
def movement(self):
key_input=pygame.key.get_pressed()
up = key_input[pygame.K_w]
down = key_input[pygame.K_s]
left = key_input[pygame.K_a]
right = key_input[pygame.K_d]
y_move = up or down
x_move = left or right
if left:
self.direction.x = -1
if up or down:
self.rect.x += -self.velx_diag
else:
self.rect.x += -self.velx
elif right:
self.direction.x = 1
if up or down:
self.rect.x += self.velx_diag
else:
self.rect.x += self.velx
else:
self.direction.x = 0
# this is the important part
# check the x collision first
self.collision_x()
if up:
self.direction.y = -1
if left or right:
self.rect.y += -self.vely_diag
else:
self.rect.y += -self.vely
elif down:
self.direction.y = 1
if left or right:
self.rect.y += self.vely_diag
else:
self.rect.y += self.vely
else:
self.direction.y = 0
# now check for the y collision
self.collision_y()
我有一个代码可以让玩家在没有重力的情况下在二维空间中移动(比如 Isaac 或 World Hardest Game)。问题是与地图中的图块 (celle) 发生碰撞:
def collisions(self):
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0:
player.rect.left = cell.rect.right
elif player.direction.x > 0:
player.rect.right = cell.rect.left
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
player.rect.bottom = cell.rect.top
如果玩家仅在 x 方向或仅在 y 方向发生碰撞,它就可以正常工作,但当它垂直移动时,它会传送到另一侧。发生这种情况是因为当它在 y 侧发生碰撞时,如果它也在 x 方向移动,则会触发 x 碰撞算法。所以我尝试使用 bool 来检查 x 或 y 碰撞:
def collisions(self):
global collx, colly
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0 and colly == False:
player.rect.left = cell.rect.right
collx=True
elif player.direction.x > 0 and colly == False:
player.rect.right = cell.rect.left
collx=True
else:
collx=False
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
colly=True
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
colly=True
player.rect.bottom = cell.rect.top
else:
colly=False
效果更好,但是 False 条件没有正确出现,我认为这是因为代码在 for 循环中,但我真的不知道该怎么做。代码太长并且包含图像,所以我没有 post 它。
播放器中的移动功能class:
def movement(self):
key_input=pygame.key.get_pressed()
if key_input[pygame.K_a] or key_input[pygame.K_d]:
if key_input[pygame.K_a]:
self.direction.x = -1
if key_input[pygame.K_w] or key_input[pygame.K_s]:
self.rect.x += -self.velx_diag
else:
self.rect.x += -self.velx
if key_input[pygame.K_d]:
self.direction.x = 1
if key_input[pygame.K_w] or key_input[pygame.K_s]:
self.rect.x += self.velx_diag
else:
self.rect.x += self.velx
else:
self.direction.x = 0
if key_input[pygame.K_w] or key_input[pygame.K_s]:
if key_input[pygame.K_w]:
self.direction.y = -1
if key_input[pygame.K_a] or key_input[pygame.K_d]:
self.rect.y += -self.vely_diag
else:
self.rect.y += -self.vely
if key_input[pygame.K_s]:
self.direction.y = 1
if key_input[pygame.K_a] or key_input[pygame.K_d]:
self.rect.y += self.vely_diag
else:
self.rect.y += self.vely
else:
self.direction.y = 0
我知道处理 2d 碰撞的最好方法是在一个轴上移动玩家,检查碰撞,然后在另一个轴上移动玩家:
def collision_x(self):
player = self.player.sprite
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.x < 0:
player.rect.left = cell.rect.right
elif player.direction.x > 0:
player.rect.right = cell.rect.left
# make two different methods for x and y collision.
def collision_y(self):
for cell in self.celle.sprites():
if cell.rect.colliderect(player.rect):
if player.direction.y < 0:
player.rect.top = cell.rect.bottom
elif player.direction.y > 0:
player.rect.bottom = cell.rect.top
然后在移动方法中你需要单独调用它们:
还有你的移动功能我觉得有点乱,所以我稍微清理了一下(如果你不喜欢它,你也可以使用你的功能,它工作得很好。)
def movement(self):
key_input=pygame.key.get_pressed()
up = key_input[pygame.K_w]
down = key_input[pygame.K_s]
left = key_input[pygame.K_a]
right = key_input[pygame.K_d]
y_move = up or down
x_move = left or right
if left:
self.direction.x = -1
if up or down:
self.rect.x += -self.velx_diag
else:
self.rect.x += -self.velx
elif right:
self.direction.x = 1
if up or down:
self.rect.x += self.velx_diag
else:
self.rect.x += self.velx
else:
self.direction.x = 0
# this is the important part
# check the x collision first
self.collision_x()
if up:
self.direction.y = -1
if left or right:
self.rect.y += -self.vely_diag
else:
self.rect.y += -self.vely
elif down:
self.direction.y = 1
if left or right:
self.rect.y += self.vely_diag
else:
self.rect.y += self.vely
else:
self.direction.y = 0
# now check for the y collision
self.collision_y()