Pygame墙体碰撞检测似乎“出错”

0 投票
2 回答
635 浏览
提问于 2025-04-18 00:37

这是我的代码

import pygame, sys

pygame.init() #load pygame modules
size = width, height = 800, 600 #size of window
speed = [25,25] #speed and direction
x= 100
y= 100
screen = pygame.display.set_mode(size) #make window
s=pygame.Surface((50,50)) #create surface 50px by 50px
s.fill((33,66,99)) #color the surface blue
r=s.get_rect() #get the rectangle bounds for the surface
r[0] = x #changes initial x position
r[1] = y #changes initial y position
clock=pygame.time.Clock() #make a clock

while 1: #infinite loop

        clock.tick(30) #limit framerate to 30 FPS
        for event in pygame.event.get(): #if something clicked
                if event.type == pygame.QUIT:#if EXIT clicked
                        pygame.quit()
                        sys.exit() #close cleanly

        r=r.move(speed) #move the box by the "speed" coordinates
        #if we hit a  wall, change direction
        if r.left <= 0 or r.right >= width:
                speed[0] = -(speed[0])*0.9 #reduce x axis "speed" by 10% after hitting

        if r.top <= 0 or r.bottom >= height:
                speed[1] = -speed[1]*0.9 #reduce y axis "speed" by 10% after hitting

        screen.fill((0,0,0)) #make redraw background black
        screen.blit(s,r) #render the surface into the rectangle
        pygame.display.flip() #update the screen

这个代码创建了一个简单的窗口,里面有一个方块在移动,碰到边缘后会反弹回来。不过在这个特定的例子中(我把两个方向的速度都设定为25),反弹后速度减少设定为0.9(也就是减少10%),我的方块似乎卡在了窗口的左边(我建议你复制粘贴这段代码,自己试试看)

如果我把速度调低,或者在反弹后不减少速度,整个程序就能正常运行。

有没有什么原因导致这种情况发生呢?

2 个回答

1

让我们一步一步来看这段代码:

speed = [25,25] #speed and direction
if r.left <= 0 or r.right >= width:
      speed[0] = -(speed[0])*0.9

先看看在x轴上发生了什么。

假设在这个检查之前,位置是1。在下一个帧中,位置的值变成了1-25 = -24。因为这个条件现在满足了,速度变成了25 * 0.9 = 22.5。

这个矩形移动到了-1.5的位置,但我们还是在墙的另一边。由于每一帧都改变速度的方向,矩形就会卡在那儿。

解决这个问题有两个办法,第一个办法已经被Alex描述过了。

第二个办法是先移动矩形,如果矩形移动到了边界之外,就把它放回到墙之前的位置。

0

没错!为了让这个方块能够自由移动和反弹,而不会卡在边缘,你需要在实际移动方块之前,先把它的速度反向(并且减少10%)。这是我简单的建议。

if r.left + speed[0] <= 0 or r.right + speed[0] >= width:
    speed[0] = - (speed[0])*0.9

if r.top + speed[1] <= 0 or r.bottom + speed[1] >= height:
    speed[1] = -(speed[1])*0.9

上面的修改可以确保方块在任何时候都不会超出边界!至于你之前遇到的问题,经过一些调试后,很明显方块会移动到屏幕外面!(比如说,x坐标和y坐标都是负数等)。虽然看起来没什么大不了,但这种情况在速度较低时,会导致方块快速反向,同时速度也会降低10%!

举个例子,如果方块在某个时刻的位置是 x = -1,而它的水平速度是 1。由于这个条件:if r.left + speed[0] <= 0 or r.right + speed[0] >= width:,它的速度会来回反转多次,同时速度也会降低,这样就无法让方块逃离这个边缘了!

呼!抱歉回答得有点长,希望对你有帮助!

祝好!

亚历克斯

撰写回答