项目详细介绍
在这个系列中,将制作一个雷霆战机游戏。
碰撞发生了什么?
Pygame中的默认碰撞类型是使用collide_rect()函数,该函数使用两个精灵的rect属性来计算它们是否重叠。这称为AABB碰撞,它非常快速和可靠。但是,如果精灵图像不是矩形,那么就会出现如图所示的情况。矩形重叠,那么collide_rect()就是True,但是玩家会感到沮丧,因为他们觉得自己应该已经成功地躲过流星(还差点才碰到一起)。
如果发现处于这种情况,可以尝试以下几种方法:
通过使用collide_rect_ratio()
函数,您可以使用较小的矩形(上图矩形的0.7倍),减少可以计为重叠的“空”空间量。根据精灵的形状,这可以很好地工作。这意味着在某些情况下,流星似乎会通过机翼而不会被视为撞击。这实际上是一个很好的情况!当游戏中的事物发生变化时,玩家不会直接注意到这一点,只会觉得他们“躲开”了一个非常接近的闪避。他们不会感到沮丧,而是会觉得自己做得很好。
另一种选择是使用圆形边界框。在流星的情况下,这是非常合适的。它不太适合飞船---在碰到飞船之外的机翼也不会算数。
设置精灵的半径
根据上面的选项,将为流星与玩家碰撞设置碰撞圈。Pygame让这很容易实现 - 只需要在每个sprite上设置一个新属性:self.radius
。
让从玩家开始。碰撞圈应该有多大?可以通过一些实验来获得正确的值。以下是如何在玩家精灵中执行此操作__init()__
:
self.rect = self.image.get_rect() self.radius = 25 pygame.draw.circle(self.image, RED, self.rect.center, self.radius)
在玩家图像上绘制一个红色圆圈,以便可以看到它的外观。让为流星做同样的事情:
self.rect = self.image.get_rect() self.radius = int(self.rect.width / 2) pygame.draw.circle(self.image, RED, self.rect.center, self.radius)
玩家精灵的半径可能太大了 - 它在y轴上实际上比船的大小更大。为了更接近,让设置self.radius = 20
。
对于流星,想要一些角落伸出来,所以让将圆圈缩放到85%的大小:
self.radius = int(self.rect.width * .85 / 2)
更改碰撞类型
为了让游戏开始后使用这些圆圈进行碰撞测试,只需要更改spritecollide
命令以使用圆形函数而不是AABB:
# check to see if a mob hit the player hits = pygame.sprite.spritecollide(player, mobs, False, pygame.sprite.collide_circle) if hits: running = False