利用python做个小游戏(3)
前面我们已经把星星、棒和飞镖都已经做出来了,今天来完善一下碰撞、生命、分数等等功能。
碰撞检测
在学习碰撞检测之前,先来说明一下精灵的概念:简单地说,精灵就是游戏中的可视图像,如前面的星星,棒,飞镖这些都是精灵。
检测碰撞有很多种方法,我简单列举几种:
在本游戏中,很显然应该使用第一种检测方法,我们来定义一个检测碰撞的方法
这里我简单说明一下pygame.sprite.collide_mask的作用,因为pygame.sprite.spritecollide检测的是两个图形的矩形区域,而有些图形存在大量的透明区域,当两个图形在透明处碰撞并且消失时,会显得很突兀,而pygame.sprite.collide_mask的作用粗略地说就是只检测图形的非透明区域,这就很好地解决了这个问题,可能我说得不明白,看图你就明白了
为了让大家更加明白,我现在让大家来看两个动图,比较一下,我特意把图片的长度设置得更长一些,以便看清楚
没有加pygame.sprite.collide_mask的效果
可以看到,小球还没有碰到棒,棒就消失了,这不是我们要的效果
加了pygame.sprite.collide_mask的效果
因为小球在和棒碰撞的时候,棒的右边还能没有移除屏幕,然而却要调用重置方法,所以我们要把重置方法的条件if self.rect.right<0这个条件去掉,从而绘制棒的代码就要做点小改动,改为:
最后调用碰撞检测的方法
大功告成,我们来看看结果
飞镖和小球的碰撞检测也是一样的道理,不过需要注意的是,由于pygame.sprite.collide_mask方法实际上接收的参数是图片,而飞镖类的图片是一个列表,所以我们要稍微改动一下,将self.image = rotatebar_image_list改为self.image = rotatebar_image_list[0],self.image[self.image_idex]改为rotatebar_image_list[self.image_idex]即可,其它的和棒的代码的改动差不多
绘制飞镖的代码改为
调用碰撞检测方法
再来看看效果
碰撞检测已经搞定,下面来看看生命值和分数
生命值
我们先要把''生命''显示出来
导入设置好的字体
显示文字在坐标为(625,0)上
文字已经设置完毕,下面是生命图片的显示。
首先我们需要导入图片
当发生一次碰撞时,生命就减一,所以很显然要改动碰撞检测方法
显示生命值
大功告成,来看看效果
为了防止作弊,小球碰到底部或者顶部也要生命减一
生命值已经完成,下面来完成分数
分数
文字'分数''和''生命''的代码写法一样,就不多说了
下面来看看分数值的显示
先设置初始分数为score = 0
然后显示分数
分数的增加,因为当小球越过棒和飞镖时,分数就增加,故分数的增加和小球、棒和飞镖的距离有关,所以要在显示它们时判断它们的距离
又解决一个问题,看效果
然后来进行游戏结束的制作
游戏结束
游戏结束的时候会显示游戏结束,本局得分,历史最高分和再来一遍字样,我们都要把它们显示出来,因为点击再来一遍是重新开始游戏,为了好确定它的区域,我采用了以图片显示的方式,而其它的都是以文字方式显示。
那是什么时候将它们显示出来呢?毫无疑问,当生命为0的时候就显示,所以我在while循环中加了个判断语句if和while语句,当条件满足时,进入死循环,把以上的文字显示出来就行了。
效果
下面来显示分数和最高分数
因为要保存最高分数,所以我们要新建一个文本文件score.txt,设置文本开始所存的分数为prescore=0,最高分为0.
ok,大功告成
然后就到点击再来一遍就重新开始这一步了,只要控制当鼠标在'再来一遍'上并按下鼠标左键,running=0即可。
这里again_rect = again.get_rect(),设置again_rect.left=400,again_rect.top=400,即图片左上角在坐标(400,400)上。
效果演示
最后的最后来设置暂停和开始键即可
暂停
我们当然不会简简单单地设置一个暂停键就完事,我们还要提高游戏的颜值,当把鼠标移到暂停或者开始键时,按键变亮,当鼠标移除来时,按键变暗,好了,下面开始
首先导入图片
设置图片的位置
因为当暂停时,除了小球、棒和飞镖不显示,其它的都显示,所以要设置一个暂停变量pause来控制,刚开始我们当然设置为False。
因为分数,生命,星空和暂停或开始键在游戏没结束的时候始终显示,所以把它们放在if not pause:else语句之外。而其他的根据逻辑关系放在指定位置即可
因为当鼠标停在或者按下暂停和开始键时,图片会变化,所以在获取事件循环中要多加几个判断
这里的逻辑关系比较复杂,一定要细心
先来看看效果
下面是继续游戏的制作,大家坚持一下,我发誓这是最后一步了。
同样是在获取事件源中添加逻辑代码
累死了,终于结束了
最后再来看看结果吧