通过游戏来学Python–微信飞机大战1
通过游戏来学Python–微信飞机大战2
通过游戏来学Python–微信飞机大战3
子弹飞得够久了,就让它击毁敌机吧!究竟要怎么实现呢?
这是所有游戏都要解决的一个重要问题:碰撞检测
1.碰撞检测
碰撞检测是游戏中非常重要的部分。简单地说,碰撞检测,就是判断两个物体是否发生了碰撞。我方英雄一个大招,是否打中敌人了呢?大招有范围,如果敌人在范围内,就是打中。
为了简化计算,通常把物体简化为矩形或圆形,这样在数学上比较好算。如果物体是不规则的,也可以把它分成几个矩形(或圆形)构成的子物体。
在更精细一些的游戏中,有时会把主角分为头部、胸部、腹部、四肢等部位,因为每个部位受伤对人物的影响不同。
pygame.sprite库中,有一些函数可以用于碰撞检测。参看文档http://www.pygame.org/docs/ref/sprite.html(从最后往前看)
例如:
pygame.sprite.collide_rect():检测两个精灵是否碰撞,两个精灵视为矩形。
pygame.sprite.collide_circle():检测两个精灵是否碰撞,两个精灵视为圆形。
pygame.sprite.groupcollide():检测两个精灵组是否碰撞,依次判断精灵组A中的每一个精灵是否与精灵组 B中的每一个精灵发生碰撞。
groupcollide()这个函数正是我们要的,因为我方子弹有很多,是精灵组,敌方飞机也有很多,也是精灵 组。
让我们来认真研究一下这个函数。
函数原型:
groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict
参数:
group1:精灵组1。
group2:精灵组2。
dokill1:发生碰撞时,是否销毁精灵组1中的发生碰撞的精灵。
dokill2:发生碰撞时,是否销毁精灵组2中的发生碰撞的精灵。
collided:自定义的回调函数,你可以自己编写碰撞检测函数。碰撞检测函数的参数是两个精灵,返回值是 True/False。
返回值:
返回一个字典,键是精灵组1中发生碰撞的精灵,值是精灵组2中与该精灵发生碰撞的精灵的列表。
2.添加代码
在变量定义部分,添加如下代码:
在游戏主循环中,添加如下代码:
这样,你就会看到我方子弹击中敌方飞机,然后两者同时消失的场面了。其实如果只是这样,根本不需要定义enemy_hit_group这个精灵组,直接调用pygame.sprite.groupcollide()函数即可,因为这个函数检测到碰撞时,会销毁发生碰撞的双方物体(因为我们把第3个参数和第4个参数都设成True了呀~~~)。之所以要定义这个精灵组,主要是想演绎出更震撼的爆炸效果,所以先记住要发生爆炸的敌方飞机,然后在敌方飞机的位置上依次播放爆炸图片,产生爆炸的效果。
3.爆炸效果
1.首先我们要截取资源图片爆炸效果的图片代码如下:
2.在敌方飞机类中添加一个属性:
- 在游戏主循环的绘图部分添加如下代码:
产生爆炸效果的原理是这样的:
将几张图片保存在一个列表中;
通过一个变量从列表中取图片;
需要切换图片时,让此变量递增;
当变量超过范围时,将敌方飞机从爆炸列表中移走。
来看看效果吧:
下就简单说一下积分的编写:
3、pygame字体原理
pygame.font库中有字体相关的类。
pygame编程时可以调用系统中已经安装的字体,也可以使用自己的ttf字体文件,这样做的好处是可以将字体文件与游戏一起打包分发,避免玩家电脑没有这个字体的问题。
- 使用系统字体
font1 = pygame.font.SysFont(‘宋体’, 16, True)
这句代码使用系统字体创建一个Font对象,3个参数分别是字体名、字体大小、是否粗体,还可以有第4个参数,是否斜体。一般只要前两个参数即可。
font_list = pygame.font.get_fonts()
get_fonts()函数可以得到系统中已安装的字体的列表。
- 使用ttf字体文件
my_font = pygame.font.Font(‘my_font.ttf’, 16)
这句代码使用自己的ttf字体文件创建一个Font对象。
- 在屏幕上打印文字
通过字体对象,可以生成一个surface,然后再调用blit()将surface显示出来。
这里主要用到字体对象的render()方法,方法原型如下:
render(text, antialias, color, background=None) -> Surface
参数说明:
参数1:要打印的文字。
参数2:抗锯齿(True/False)。
参数3:文字的颜色。颜色使用一个列表,提供rgb三个值。
参数4:背景颜色。如果使用透明背景,这个参数可以不写。
示例:
surface1 = font1.render(u’当前得分’, True, [255, 0, 0])
注意,要打印汉字,需要加一个u,表示unicode编码。
最后,将这个surface显示在屏幕上即可:
screen.blit(surface1, [20, 20])
将刚才的文字显示在x、y坐标分别为20、20的位置上。
4、计算得分
上面我们分析过,可以使用pygame.sprite库中的groupcollide()函数来进行碰撞检测,代码如下:
pygame.sprite.groupcollide(enemy_group, hero.bullets, True, True)
这个函数返回一个字典,字典的键是第1个精灵组中发生碰撞的精灵。
既然这样,只要知道这个字典中的元素个数,就可以知道击落了几架飞机。而len()函数可以获知字典的元素个数。
- 添加变量
在程序的变量定义部分,增加一个变量定义:
被击中的敌方飞机字典
enemy_hit_dict = dict()
再增加一个变量定义,用于保存得分:
score = 0 # 得分
增加一个常量,表示每击落一架飞机的得分:
击落敌方飞机得分
ENEMY_SCORE = 100
还要增加一个字体的变量:
game_font = pygame.font.SysFont(‘宋体’, 16, True) # 字体
- 碰撞检测部分
将原有的碰撞检测部分的代码修改为:
检测我方子弹是否击中敌方飞机
enemy_hit_dict = pygame.sprite.groupcollide(enemy_group, hero.bullets, True, True)
score += len(enemy_hit_dict) * ENEMY_SCORE; # 计算得分
enemy_hit_group.add(enemy_hit_dict)
- 界面显示部分
在更新屏幕之前,显示得分:
绘制游戏得分
screen.blit(game_font.render(u’当前得分:%d’ % score, True, [255, 0, 0]), [20, 20])
更新屏幕
pygame.display.update()
但怎么感觉我们的飞机这么厉害,怎么都打不死。( ﹁ ﹁ ) ~→
Original: https://blog.csdn.net/weixin_30697437/article/details/112351962
Author: 吕宸昊
Title: pygame只能编写游戏_通过游戏来学Python–微信飞机大战4
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/782860/
转载文章受原作者版权保护。转载请注明原作者出处!