Pygame墙体碰撞检测似乎“出错”
这是我的代码
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 个回答
让我们一步一步来看这段代码:
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描述过了。
第二个办法是先移动矩形,如果矩形移动到了边界之外,就把它放回到墙之前的位置。
没错!为了让这个方块能够自由移动和反弹,而不会卡在边缘,你需要在实际移动方块之前,先把它的速度反向(并且减少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:
,它的速度会来回反转多次,同时速度也会降低,这样就无法让方块逃离这个边缘了!
呼!抱歉回答得有点长,希望对你有帮助!
祝好!
亚历克斯