python - Pygame 垂直碰撞
问题描述
我有一个代码可以让玩家在没有重力的情况下在二维中移动(比如艾萨克或世界最难游戏)。问题是与地图中的瓦片(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 中移动,它就可以工作,但是当它垂直移动时,它会传送到另一侧。发生这种情况是因为当它在 ay 侧发生碰撞时,如果它也在 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 循环内,但我真的不知道该怎么做。代码太长而且包含图像,所以我没有发布它。
Player 类中的移动函数:
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()
推荐阅读
- javascript - 如何从 AngularJS 中的 url 中删除 # 并使路径在重新加载/刷新时工作?
- python - 使用python修改Excel文件
- javascript - 外部 Js 文件中的一项功能未在 HTMLButtonElement.onclick 中定义
- sql - 我们如何在 HAVING 子句中编写带有搜索条件的摘要查询?
- java - 如何将流转换为增强循环
- google-apps-script - Google Apps - 如何从当前目录获取所有文件名?
- mysql - 我无法让我的查询从我的产品表中提取所有记录
- c++ - C++字节数组到int
- python - 如何将frozendict对象转换为熊猫数据框
- javascript - 如何查看 RecyclerView 项目逆序最新项目在顶部