PyGame:与B的碰撞检测

2024-04-19 05:57:28 发布

您现在位置:Python中文网/ 问答频道 /正文

在一个平台上,我有生成的地形,但没有碰撞。以下是我尝试用来检查碰撞的代码:

def player_move(self):

    self.player.rect.x += self.player.velX
    self.check_collision(self.player, self.player.velX, 0)
    self.player.rect.y += self.player.velY
    self.check_collision(self.player, 0, self.player.velY)

def check_collision(self, sprite, x_vel, y_vel):
    # for every tile in Background.levelStructure, check for collision
    for block in self.moon.get_surrounding_blocks(sprite):
        if block is not None:
            if pygame.sprite.collide_rect(sprite, block):
                # we've collided! now we must move the collided sprite a step back
                if x_vel < 0:
                    sprite.rect.x = block.rect.x + block.rect.w

                if x_vel > 0:
                    sprite.rect.x = block.rect.x - sprite.rect.w

                if y_vel < 0:
                    sprite.rect.y = block.rect.y + block.rect.h

如果这有帮助的话,我也有生成级别的代码:

^{pr2}$

任何帮助都将不胜感激谢谢。在


Tags: 代码rectselfformoveifdefcheck
1条回答
网友
1楼 · 发布于 2024-04-19 05:57:28

有几个问题。在

首先,你不能告诉速度改变。。。你可能想让它停下来,或者在你撞到一个街区时倒车。在

第二,迭代所有的块两次,一次检查X轴,一次检查Y轴。对于大型或复杂的地图,这将使速度加倍。在

我还建议在这种情况下不要使用collide_rect函数来测试碰撞,除非您非常确定速度不能高于块(或精灵)的总大小。如果你移动71像素一帧,但块大小是20像素宽,而你的播放器只有50像素宽,你可以跳过一个街区,而不会撞到它!在

有一件事要非常小心,那就是你要移动物体,然后检查碰撞。这很可能会导致问题,因为您必须将其移回原来的位置。在

我建议把你的结构改成:

def player_move(self):

    # create some local vars for ease of reading...
    x = self.player.rect.x
    x_next = x + self.player.velX

    y = self.player.rect.y
    y_next = y + self.player.vely

    w = self.player.rect.w
    h = self.player.rect.h

    # has a collision happened?
    hitX = False
    hitY = False

    for block in self.moon.get_surrounding_blocks(self.player):

        # empty blocks are 'None' in this map system...
        if not block:
            continue

        if self.player.velX > 0:  # moving right
            if x + w < block.x and x_next + w >= block.x:
                # collision!
                x_next =  block.x - w
                hitX = True
        elif self.player.velX < 0: # moving left
            if x > block.x + block.w and x_next > block.x + block.w:
                # collision!
                x_next = block.x + block.w
                hitX = True

         if self.player.velY...... # do the same for Y axis...

    # now update rect to have the new collision fixed positions:

    self.player.rect.x = x_next
    self.player.rect.y = y_next

    # and if there was a collision, fix the velocity.

    if hitX:
        self.velX = 0  # or 0 - velX to bounce instead of stop
    if hitY:
        self.velY = 0  # or 0 - velY to bounce instead of stop

希望这有助于事情朝着正确的方向发展。。。在

另一个想法是,几年前我在写一个平台引擎时,我记得我在一个阶段遇到了一些问题,播放器对象撞到了积木,停止了,但是又重新开始了。最后,它在代码中的某个地方被一个错误关闭了。这可能值得添加一堆调试打印(最好使用“日志”包…),然后大大降低帧速率,这样你就可以看到到底发生了什么。在

祝你好运!写游戏很有趣,但有时也会很令人沮丧。在

相关问题 更多 >