玩家不断坚持平台碰撞Pygame

时间:2020-08-04 02:39:54

标签: python pygame

我正在尝试与矩形发生良好的碰撞,但是我觉得我的方法很糟糕,因为每当我工作并与其他平台碰撞时,我的播放器就会一直卡在上面, 我可以使它不会被卡住而发生碰撞的方式 我只是在寻找良好的碰撞方式,谢谢!

VIDEO <如您所见,当我与平台碰撞时,我的玩家一直卡在平台上,左右晃动都是一样的,这只会使我的玩家卡住而没有适当的碰撞

        # collisions
        for platform in platforms:
            if playerman.rect.colliderect(platform.rect):
                collide = True
                playerman.isJump = False
                if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom) or
                    platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom)):
                    playerman.y = platform.rect.top - playerman.height + 1
                    playerman.moveright = True
                    playerman.moveleft = True
                
                if (platform.rect.collidepoint(playerman.rect.right, playerman.rect.top) or
                    platform.rect.collidepoint(playerman.rect.right, playerman.rect.bottom - 10)):
                    playerman.moveright = False
                elif (platform.rect.collidepoint(playerman.rect.left, playerman.rect.top) or
                      platform.rect.collidepoint(playerman.rect.left, playerman.rect.bottom - 10)):
                    playerman.moveleft = False
            else:
                playerman.moveright = True
                playerman.moveleft = True
                


我的完整代码:script

我一直在到处寻找适当的碰撞,但是我找不到合适的工作

1 个答案:

答案 0 :(得分:1)

从视频中看,如果您从障碍物下方走来,则碰撞检测似乎无法正常工作。

通常(请参见下面的示例):我在游戏中遇到了相同的“难题”,据我所知,有两种可能的方法。

  1. 预检查

您检查播放器距最近的“块”有多远,并让播放器仅移动至此。这包括:

  • 检查哪些块最靠近玩家
  • 检查到每个闭合块的距离并计算玩家可以在z方向上移动的剩余x像素。
  • 将播放器沿z方向精确移动x个像素。
  1. 事后检查(我使用了它,因为这样可以更轻松地自己弄清楚)

您可以根据玩家当前的速度移动其,然后检查是否有碰撞。如果发生碰撞,则将播放器后退移至像素数量,即像素边界与块边界之间的交点。

  • 根据自己的速度最大程度地移动玩家
  • 检查所有闭合块(或地图上所有起始块的碰撞,您可以从那里提高性能)
  • 如果发生碰撞,请计算玩家与碰撞块相交的程度。如果玩家的匹配框是矩形,并且使用由矩形块组成的图块地图,则这很容易,您可以简单地减去player.x和block.x坐标
  • 将播放器移回(更新屏幕之前)该像素量。

如果您想进一步了解它,并有深入的代码示例(如果您不希望自己尝试并尝试错误,直到您弄清楚它),建议您在youtube上搜索pygame-2D碰撞检测程序,那里的老师很棒。

这是我的冲撞检测_x_axis()方法的摘录(自己引用了玩家!)

# move player etc ...
for tile in map_tiles: # for all tiles on the map
    if pygame.sprite.collide_rect(self.hitboxBody, tile):
        if self.SpeedX < 0 and tile.rect.right > self.hitboxBody.rect.left:  # moving left and collision
             # move char back to "in front of the wall"
             self.rect.x += tile.rect.right - self.hitboxBody.rect.left
             self.SpeedX = 0  # set speedX to zero, as we cannot move in that direction anymore

        elif self.SpeedX > 0 and self.hitboxBody.rect.right > tile.rect.left:  # moving right and collision
             # move char back to "in front of the wall"
             self.rect.x -= self.hitboxBody.rect.right - tile.rect.left
             self.SpeedX = 0  # set speedX to zero, as we cannot move in that direction anymore

collision_detection_y_axis:

for tile in map_tiles: # for all tiles on the map
    if pygame.sprite.collide_rect(self.hitboxBody, tile):
        if self.SpeedY < 0 and tile.rect.bottom > self.hitboxBody.rect.top:  # moving up
            self.rect.y += tile.rect.bottom - self.hitboxBody.rect.top # move char back to "below the wall"
            self.SpeedY = 0
        elif self.SpeedY > 0 and self.hitboxBody.rect.bottom > tile.rect.top:  # moving downwards
            self.rect.y -= self.hitboxBody.rect.bottom - tile.rect.top # move back to "on top of the wall"
            self.SpeedY = 0
            self.jumping = False  # on ground

编辑:这要求您在碰撞检查之间的移动小于块的宽度,否则,如果角色有足够的速度,您的角色可以在块之间“小故障”。

注意:在进行碰撞测试之前,应该考虑玩家移动的方向 ,这样可以更轻松地确定玩家的哪一侧将首先与障碍物碰撞。例如,如果您向右移动,则播放器的右侧将与块的左侧碰撞。然后针对这两个点写一个碰撞检测以及随后的动作(例如,重置到块的前面和speed_x = 0的位置)

PS:尝试使用函数pygame.Rect.colliderect,它测试两个矩形是否重叠(=碰撞),我有一种感觉,设置碰撞点功能的方式不会在所有可能的情况下返回碰撞。