使用pygame处理Python矩形碰撞

4

我已经花费了几天的时间对此主题进行广泛的研究,但似乎找不到解决我的确切问题的答案。

所以,我设置了一个简单的游戏,在这个游戏中,玩家位于0,0点,宽度为10x10。

    player= pygame.Rect(0, 0, 10, 10)

除此以外,玩家的速度为x: 0, y: 10,这将使他下落(因为屏幕的原点在左上角,所以y是正数)。

而我有一个瓦片在0, 100的位置,如下图所示:

    dirt= pygame.Rect(0, 100, 10, 10)

那么,我该如何处理碰撞呢?我已经知道我可以使用Rect.colliderect(Rect)来检测它。

我已经尝试了一些方法,但遇到了一些问题:

当玩家撞到物体时,我不能将他的速度减为0并将他移回到刚好触摸到物体的位置,因为这仍然会导致走路时的问题。当他行走时,我在x轴上施加+10的速度,但不幸的是,游戏仍然会处理他正在下落、碰撞和侧向移动,所以它只会将他移回到起始位置。

我是个初学者,所以希望得到一个简单的答案,并且如果可能的话,我希望不必使用任何第三方模块,除了pygame。

更新:

以下是我尝试过的粗略测试代码:

    def sim(obj, time, world):
        time= time / 1000
        obj.physProp['vel']= (obj.physProp['vel'][0] + (accel[0] * time), obj.physProp['vel'][1] + (accel[1] * time))
        if obj.physProp['vel'][1] > terminalY:
            obj.physProp['vel']= (obj.physProp['vel'][0], terminalY)
        obj.pos= (obj.pos[0] + (obj.physProp['vel'][0] * time) + ((accel[0] / 2) * (time ** 2)), obj.pos[1] + (obj.physProp['vel'][1] * time) + ((accel[1] / 2) * (time ** 2)))

        for ID in world:
            if obj.getRect().colliderect(world[ID].getRect()) == True:
                pass

        return (obj.pos, obj.physProp['vel'])

@vdbuilder 好的,我已经将其作为更新发布了,请告诉我是否需要更多信息,谢谢。 - Parker Hoyes
2个回答

4

将x/y移动分开。

先移动x,检查是否发生碰撞,如果有,则后退并将xspeed设置为0。

再移动y,检查是否发生碰撞,如果有,则后退并将yspeed设置为0。

这意味着每步需要进行两次碰撞检查,但非常平滑。:)


1
Pygame API邀请您以面向对象的方式编写所有游戏主题,这样您的下落角色将具有所有“方法”和“属性”,以正确响应场景中的事物,例如撞击某些东西。
因此,如果您的角色被定义为简单的某些内容:
class Char(object):
    # these start as class attributes, 
    # but whenever they are assigned to with a "self.var = bla" in
    # a method, an instance attribute starts existing
    x, y = 0,0
    vx, vy = 0,0

    def update(self):
        self.x += self.vx
        self.y += self.vy

当您的外部代码检测到碰撞时,可以执行以下操作:

def mainloop():
   while True:
       ...
       obj.update()
       if obj.getRect().colliderect(world[ID].getRect()): # don't do "== True" in `if's - it is just silly
             # take character back to the precious position
             obj.x -= obj.vx
             obj.y -= obj.vy
             # zero out velocities to make it stop:
             obj.vx = obj.vy = 0

等等,你很快就会意识到,在编程中使用“对象”来思考你的游戏“事物”,这使得代码流程非常自然 - 一旦你理解了这个工作原理,看看Pygame的sprite模块 - 它允许你自动化很多检查和更新,而不必明确地编写每个检查的for循环。


谢谢,但我认为这在我的情况下不太适用,因为重力加速度会不断地添加到物体上,如果发生碰撞,则将其设置为0,因此如果该角色行走,则其速度向量将向下和向左,仍然位于其他物体内部,因此它将被送回,这使得行走变得不可能。 - Parker Hoyes
简单修复!不是在玩家移动时应用速度,而是直接向前移动并检查碰撞,虽然不是很好,但它能够工作,感谢您的帮助!我会记住这些信息。 - Parker Hoyes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接