内容正文:
少儿编程课
1
飞机大战5
本节我们优化碰撞检测,并添加计分机制,完善飞机大战游戏效果
3
碰撞检测的优化
4
如果仔细观察游戏效果,你会发现陨石还没有碰到飞机,就发生了碰撞检测,游戏结束
这是因为虽然陨石和飞机是不规则的形状,但是碰撞检测还是以图片的长方形来判断的。以下图为例:
明白了原因之后,接下来我们想办法优化一下碰撞检测
陨石图片
陨石本身
飞机图片
飞机本身
图片边缘已经碰撞
飞机和陨石本身并没有碰到
优化碰撞检测的方法:将飞机和陨石当做圆来处理
2
3
为spritecollide添加第四个参数pygame.sprite.collide_circle
之前说过,这个参数可以指定一个回调函数,能够定制一些特殊的检测方法,pygame.sprite.collide_circle就是pygame提供的用来检测两个圆是否碰撞的函数
将陨石当作圆来处理,指定半径
hits = pygame.sprite.spritecollide(player, all_meteorite, True, pygame.sprite.collide_circle)
# 把陨石当做圆处理,设定陨石的半径
self.radius = int(self.rect.width * 0.85 / 2)
# pygame.draw.circle(self.image, COLOR_GREEN, self.rect.center, self.radius)
# 把飞机当圆处理,设置飞机圆的半径
self.radius = 20
# pygame.draw.circle(self.image, COLOR_GREEN, self.rect.center, self.radius)
因为陨石外面有透明部分,可以先乘以0.85去掉透明部分然后再除以2作为半径。
两个设定半径后跟的一行代码表示绘制指定半径的一个圆,这样可以更直观的看到把飞机和陨石当成圆的样子。
1
将飞机当作圆来处理,指定半径
运行程序,效果如下:
素材丰富与记分机制
8
接下来,我们丰富掉落的陨石类型
1
首先把所有陨石的图片效果列出来存到列表中
3
最后在陨石的初始化方法中,随机选定一个图片即可
4
运行程序,效果如下:
2
然后循环获取所有图片
meteor_list = ['img_meteorite_01.png', 'img_meteorite_02.png',
'img_meteorite_03.png','img_meteorite_04.png',
'img_meteorite_05.png','img_meteorite_06.png',
'img_meteorite_07.png', 'img_meteorite_08.png']
# 循环获取所有图片
meteor_images = []
for img in meteor_list:
meteor_images.append(pygame.image.load('img/' + img))
# 随机获取列表中的某一项
self.image = random.choice(meteor_images)
飞机打陨石的过程已经做好了,下面我们给游戏添加计分机制
1
定义绘制计分的方法,首先设置字体和大小
# 定义绘制计分的方法
def draw_text(surf, text, size, x, y):
# 设置画笔的字体
font_name = pygame.font.match_font('arial')
# 设置画笔的字体和大小
font = pygame.font.Font(font_name, size)
3
# 将字体绘制到屏幕上
surf.blit(text_surface, text_rect)
2
创建字体的矩形区域并设置位置
# 绘制内容:text为内容,True为是否抗锯齿,字体颜色为白色
text_surface = font.render(text, True, (255, 255, 255))
# 设置字体的矩形
text_rect = text_surface.get_rect()
# 设置字体的位置
text_rect.midtop = (x, y)
使用blit方法将创建好的字体绘制到屏幕
4
定义变量score表示分数,初始值为0,每次子弹与陨石碰撞加五分。
score = 0
for hit in hits:
# 分数增加
score += 5
……
5
在死循环中调用绘制计分方法将分