繁体   English   中英

2D平台游戏的碰撞检测

[英]Collision detection for 2D platformer

我正在开发平台游戏,我想与平台进行基本的碰撞,遗憾的是仍然无法正确完成。 玩家移动计算如下:

velocity += acceleration
position += velocity + 0.5 * acceleration

所有变量都是具有xy值的向量。 这按预期工作,问题在于碰撞。 我的规则是:

  • 降落在平台上时停止坠落。
  • 从平台运行时开始下降。
  • 在跳跃过程中碰到平台时停止向上移动。
  • 撞墙时停止向一侧移动,但可以向相反方向移动。

检查底部是否与平台碰撞很简单,但棘手的部分是检测哪一侧与平台碰撞并能够为玩家设置适当的位置。

我试图从每一侧检测角落和中间,但由于我的速度不是每帧 1px,有时玩家跌落到快速并被检测为侧面。

检测哪一侧发生碰撞的好方法是什么?

我在 javascript 中有几个类似平台的游戏,这就是我实现碰撞的方式:

1.落地停止坠落:可以给你的精灵一个矩形作为边界区域,然后使用Pygames内置的Rect类来检测相交。 当您的精灵命中框(矩形)和平台矩形(另一个矩形)之间发生这种交集时,您可以将玩家的 Y 速度设置为 0。

2. 离台运行时开始坠落。 我通常有一个专门用于重力的变量,并且简单地不断将其应用于精灵以将其向下推。 这样,当您不再与平台相交后,它会向下坠落。

3.跳跃时撞到平台停止向上移动:与之前的交叉点相同,在矩形碰撞后将Y速度设置为0,并让玩家因为恒定的重力而坠落。

4. 撞墙时停止向一侧移动,但可以向相反方向移动:同样的,但这次将X速度设置为0。 (如果你被困在墙上,你总是可以将 X 设置为大于 0 来推动你回到游戏中)

还要注意的是,如果您只想在精灵碰到平台的某个边缘时执行某些操作,您可以创建一个与精灵的边对齐的矩形。 例如,如果我想查看某个东西是否与我的精灵左侧相交,我可以使用 - height: same height - width: 1 - x: x + width - y: same y

矩形文档: https : //www.pygame.org/docs/ref/rect.html

好吧,这里有代码可以帮助检测何时可以从平台跳转:

self.rect.y += 2
platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
self.rect.y -= 2

# If it is ok to jump, set our speed upwards
if len(platform_hit_list) > 0:
    velocity += acceleration
    position += velocity + 0.5 * acceleration

然后用于检测何时跌倒平台的代码:

if self.rect.y >= constants.SCREEN_HEIGHT and self.change_y >= 0:
    self.change_y = 0
    self.rect.y = constants.SCREEN_HEIGHT

最后碰撞代码:

block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
    # If we are moving right,
    # set our right side to the left side of the item we hit
    if self.change_x > 0:
        self.rect.right = block.rect.left
    elif self.change_x < 0:
        # Otherwise if we are moving left, do the opposite.
        self.rect.left = block.rect.right

# Move up/down
velocity += acceleration
position += velocity + 0.5 * acceleration

# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:

    # Reset our position based on the top/bottom of the object.
    if self.change_y > 0:
        self.rect.bottom = block.rect.top
    elif self.change_y < 0:
        self.rect.top = block.rect.bottom

    # Stop our vertical movement
    self.change_y = 0

希望这一切都会以某种方式帮助您提供所需的答案。 请注意,这些块是指平台,将检查给定列表中的每个平台,我使用 rects,因为它是检查冲突的最佳方法之一。 至于change_x 和change_y,它只是存储玩家将移动多少的变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM