使用 Python 开发飞机大战小游戏的实践指南,40,000 字的超级详细讲解!-制作一架小型飞机
搞起来
目标:创建一个可以左右移动的小飞机,用户可以通过空格space
键来控制飞机发射子弹。
创建背景
创建一个空背景
首先编写一个空的pygame
窗口,文件名为plane_war.py
display.set_mode
返回的是一个Surface
数据类型
效果图
创建设置类
一个游戏通常有n多个设置,如果每次想改变其中的某一个值的话在主文件中寻找容易眼花缭乱,现在创建一个新的文件settings.py
,专门用来存储这些信息
添加小飞机
这里用到的小飞机
绘制小飞机
现在图像也有了,来创建一个plane.py
模块,其中有一个Plane
类,来存储飞机的各种行为
get_rect
会返回Surface的矩形的区域,.centerx
和.bottom
是其两个属性
改写plane_war.py
将小飞机绘制在屏幕上
效果图
创建一个存储运行函数的模块
为了不使plane_war.py
太长而影响阅读,来创建一个名为game_func.py
的模块,用其飞机大战运行的函数,使其逻辑更容易理解
check_events
函数用来完成窗口不会关闭的功能,update_screen
用来完成更新图像的功能,有3个形参,Surface对象、背景图像、小飞机函数
因为check_events
完成了退出游戏的操作,所以plane_war.py
就不需要sys模块了,更新后的plane_war.py
如下
控制小飞机
通过修改小飞机的坐标来完成移动,在用户按下方向键的时候小飞机的坐标进行有规律的变化
控制小飞机移动
当用户按键时,都会在pygame
中注册一个事件,任何一个事件都是通过pygame.event.get()
获取的,因此可以在函数体内,为每个按键都注册一个KEYDOWN
事件。
现在将check_events
函数改写,通过检测按下键位,来对小飞机进行移动
现在按一下小飞机移动一个像素,一般的游戏都是通过按下不送则一直移动,
Pygame
中的pygame.KEYUP
可以检测用户是否松开按键现在结合KEYDOWN
和KEYUP
来完成一个持续移动
控制小飞机持续移动
来定义一个标志位,来判断用户是否按下按键,默认为Flase
一旦检测到用户按下俺家则为True
,小飞机就可以持续移动
由于小飞机是通过plane.py
文件来控制的,对这个文件进行改写
update
方法是标志位为True时,小飞机就开始移动
改写game_func.py
中的check_events
函数
最后只要在plane_war.py
中调用update
方法就可以完成持续移动的操作
完成左右移动
用同样的方法完成向左移动
改写后的plane.py
文件
改写后的game_func.py
中的check_events
函数
调整速度
现在的小飞机一次是按1px来移动的,那速度是相当的缓慢,修改一下小飞机的移动速度
首先在setting.py
中添加一行
现在对plane.py
做修改
将plane_war.py
中的plane
增加一个属性
限制小飞机的活动范围
现在小飞机已经可以飞呀飞,但是没有东西限制他,很容易就飞出了屏幕。现在将其限制在屏幕中,避免飞出去。
只需要修改plane.py
中的update
方法
重构game_func.py
中的check_events
函数
随着小飞机的功能愈来愈多,现在将check_events
重构为3个函数,捕捉用户按键和用户松开键分别定义两个函数
重构后的check_events
效果图
完成射击功能
通过玩家按下空格来发射子弹(一小小小的矩形)
添加子弹的设置
在settings.py
中的__init__
方法中添加以下数据
创建Bullet类
创建存储子弹的Bullet
类的bullet.py
文件
Bullet
类继承于pygame.sprite
中的Sprite
类,此类可以将游戏中的元素进行编组,可以同时操作编组中的所有元素
将子弹存储到编组中
首先在plane_war.py
中创建一个编组,用于存储所有有效的子弹,以便能够管理发射出去的子弹;这个编组是pygame.sprite.Group
类的一个实例;pygame.sprite.Group
类类似于列表,但是提供了有助于开发游戏的额外功能。在主循环中,我们将使用这个编组在屏幕上绘制子弹,以及更新没颗子弹的位置。
开火
通过修改game_func.py
中的函数来完成发射子弹的操作
用户按下空格之后会创建一个子弹(一个名为new_bullet的Bullet实例),并使用
add
追加到编组中方法bullets.sprites
返回一个列表,包含了编组中的所有精灵,遍历编组中的精灵,并通过draw_bullet()绘制到屏幕上
效果图:
现在已经完成基本的射击功能了,虽然子弹到达屏幕顶端后消失了,这仅仅是因为pygame
无法绘制屏幕外面的东西,这些子弹实际还是存在的,他们的y
坐标为负数且越来越少,会继续消耗内存
删除已经消失的子弹
这里通过.copy
进行浅拷贝,然后检测子弹是否消失,然后再将其删除
对plane_war.py
中的while
语句中添加下面这一句
注意:在
fg.update_screen
之前进行添加
限制子弹的数量
为了不使这个小游戏跟开挂似得,肯定要限制一下发射子弹的数量,在settings.py
中添加一行
在check_keydown_events
函数体中增加一个判断即可
简化plane_war.py
中的while
语句
将发射子弹移步到game_func.py
文件中并创建一个update_bullets
此时的while
语句中就4行代码