大多数计算机游戏中,需要知道一个动画精灵什么时候碰到另一个精灵。例如,可能需要知道保龄球何时碰到球瓶,或者导弹什么时候击中飞船。Pygame中内置有这种碰撞检测。
简单地说,碰撞测试指的是两个动画精灵何时接触或重叠。两个移动的东西相互碰到一起,这就是一个碰撞。
Python还提供了一种方法对动画精灵分组。例如,在保龄球游戏中,所有球瓶可能在一组,球在另一组。组合碰撞检测密切相关。如果想检测球何时击倒某个瓶子,可以寻找求精灵与球瓶组中所有精灵之间的碰撞。还可以检测内部的碰撞,即球瓶相互碰倒。
这次先建立四个小狗,与上次建立小狗的列表不同,这次我们使用的是Pygame中的group类。并命名一个函数animate( ),在里边包括碰撞检测的代码即两个小狗碰撞,便会反向运动。
上代码:
import sys,pygame
from random import *
class MyDogClass(pygame.sprite.Sprite):
def __init__(self, image_file, location,speed):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
self.speed = speed
def move(self):
self.rect = self.rect.move(self.speed)
if self.rect.left < 0 or self.rect.right > width:
self.speed[0] = - self.speed[0]
if self.rect.top < 0 or self.rect.bottom > height:
self.speed[1] = -self.speed[1]
def animate(group):
screen.fill([255,255,255])
for dog in group:
group.remove(dog) #从组删除精灵
if pygame.sprite.spritecollide(dog,group,False):
dog.speed[0] = -dog.speed[0]
dog.speed[1] = -dog.speed[1]
#检查精灵之间的碰撞
group.add(dog) #再将小狗添加回原来的组
dog.move()
screen.blit(dog.image,dog.rect)
pygame.display.flip()
pygame.time.delay(20)
size = width,height = 640,480 #主程序从这里开始
screen = pygame.display.set_mode(size)
screen.fill([255,255,255])
img_file = "timg.png"
group = pygame.sprite.Group() #创建精灵组
for row in range(0,2):
for column in range(0,2):
location = [column * 180 + 10,row * 180 + 10]
speed = [choice([-2,2]), choice([-2,2])]
dog = MyDogClass(img_file,location,speed)
group.add(dog) #把小狗添加到组
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
animate(group)
pygame.quit()
注意到程序中Pygame sprite模块中有这个函数:spritecollide( ) 。它会查找与一个组中所有精灵之间的碰撞,分三步来完成:
① 首先,从这个组中删除这个精灵;
② 其次,检查这个精灵与组中其它精灵之间的的碰撞;
③ 最后,再把这个精灵添加到原来的组。
运行程序之后,会发现两点:小狗碰撞后,它们会颤抖或者发生两次碰撞还有就是有时会卡在窗口边界,颤抖一段时间,为什么会出现这种情况呢?这与编写的animate( )函数有关。我们是先移动一个球,检查它的碰撞,然后移动另一个球,再检查这个球的碰撞,以此类推。可以尝试先完成所有的移动,然后再完成全部的检测:
def animate(group):
screen.fill([255,255,255])
for dog in group:
dog.move()
for dog in qroup:
group.remove(dog) #从组删除精灵
if pygame.sprite.spritecollide(dog,group,False):
dog.speed[0] = -dog.speed[0]
dog.speed[1] = -dog.speed[1]
#检查精灵之间的碰撞
group.add(dog) #再将小狗添加回原来的组
screen.blit(dog.image,dog.rect)
pygame.display.flip()
pygame.time.delay(20)