Python学习之路日志—利用pygame开发《外星人入侵》游戏项目(7)
在今天的学习中,我将在昨天的基础上继续对游戏进行开发与完善:
9.1 添加一个Play按钮:
在本节中,我们将学习如何添加一个Play按钮,它在游戏开始前出现,并在游戏结束后再次出现,让玩家能够开始新游戏。为此,在game_stats.py中输入如下代码:
现在游戏一开始将处于非活动状态,等我们创建Play按钮后,玩家才能开始游戏。由于Pygame没有内置创建按钮的方法,我们创建一个
Button类,用于创建带标签的实心矩形。可以在游戏中使用这些代码来创建任何按钮。下面是
Button类的第一部分, 将这个类保存为文件button.py:
简要分析一下:
-
首先,我们导入了模块
pygame.font
,它让Pygame能够将文本渲染到屏幕上。方法__init__()
接受参数self
,对象ai_settings
和screen
,以及msg
,其中msg
是要在按钮中显示的文本(见第5行)。 -
我们设置按钮的尺寸(见第12行),然后通过设置
button_color
让按钮的rect
对象为亮绿色,并通过设置text_color
让文本为白色。 在第15行处,我们指定使用什么字体来渲染文本。实参None
让Pygame 使用默认字体,而 48 指定了文本的字号。 -
为让按钮在屏幕上居中,我们创建一个表示按钮的
rect
对象(见第18行),并将其center
属性设置为屏幕的center
属性。 -
在第21行处,我们调用
prep_msg()
来处理这样的渲染。 -
方法
prep_msg()
接受实参self
以及要渲染为图像的文本(msg
)。调用font.render()
将存储在msg
中的文本转换为图像,然后将该图像存储在msg_image
中(见第26-27行)。方法font.render()
还接受一个布尔实参,该实参指定开启还是关闭反锯齿功能,余下的两个实参分别是文本颜色和背景色。 -
在第28-29行处,我们让文本图像在按钮上居中,根据文本图像创建一个
rect
,并将其center
属性设置为按钮的center
属性。 -
在第34-5行,我们调用
screen.fill()
来绘制表示按钮的矩形,再调用screen.blit()
,并向它传递一幅图像以及与该图像相关联的rect
对象,从而在屏幕上绘制文本图像。
9.2 在屏幕上绘制Play按钮:
我们将使用
Button类来创建一个Play按钮。鉴于只需要一个 Play 按钮,我们直接在alien_invasion.py中创建它,如下图所示:
我们导入
Button类,并创建一个名为
play_button的实例(见第20行),然后我们将
play_button传递给
update_screen(),以便能够在屏幕更新时显示按钮(见第37行)。
接下来,要修改
update_screen(),以便在游戏处于非活动状态时显示Play按钮:
在第45-46行中,为让Play按钮位于其他所有屏幕元素上面,我们在绘制其他所有游戏元素后再绘制这个按钮,然后切换到新屏幕。
如下图所示,如果现在运行这个游戏,将在屏幕中央看到一个Play按钮:
9.3 单击Play按钮时开始游戏:
为在玩家单击 Play 按钮时开始新游戏,需在game_functions.py中添加如下代码,以监视与这个按钮相关的鼠标事件:
首先,修改
check_events()的定义,在其中添加了形参
stats和
play_button。我们将使用
stats来访问标志
game_active,并使用
play_button来检查玩家是否单击了 Play 按钮。 无论玩家单击屏幕的什么地方,Pygame都将检测到一个
MOUSEBUTTONDOWN事件(见第37行),但我们只想让这个游戏在玩家用鼠标单击 Play 按钮时作出响应。为此,我们使用了
pygame.mouse.get_pos(),它返回一个元组,其中包含玩家单击时鼠标的 x 和 y 坐标(见第38行)。我们将这些值传递给函数
check_play_button()(见第38行)。
而这个函数使用
collidepoint()检查鼠标单击位置是否在Play按钮的
rect内(见第42行)。如果是这样的,就将
game_active设置为True ,让游戏就此开始!
在alien_invasion.py 中调用
check_events(),需要传递另外两个实参——
stats和
play_button:
至此,如下图所示,能够通过按下按键开始这个游戏了:
同样,游戏结束时,
game_active应为 False ,并重新显示Play按钮:
9.4 按下Play按钮时重置游戏:
前面编写的代码只处理了玩家第一次单击Play按钮的情况,而没有处理游戏结束的情况,因为没有重置导致游戏结束的条件。
为在玩家每次单击Play按钮时都重置游戏,需要重置统计信息、删除现有的外星人和子弹、创建一群新的外星人,并让飞船居中,如下所示:
我们更新了
check_play_button()的定义,使其能够访问
ai_settings、
stats、
ship、
aliens和
bullets。为重置在游戏期间发生了变化的设置以及刷新游戏的视觉元素,它需要这些对象。 在第42行处,我们重置了游戏统计信息,给玩家提供了新飞船。接下来,我们将
game_active设置为 True (这样,这个函数的代码执行完毕后,游戏就会开始),清空编组
aliens和
bullets(见47-48行),创建一群新的外星人,并将飞船居中(见52-53行处)。
接着,
check_events()的定义需要修改,调用
check_play_button()的代码亦如此:
check_events()的定义需要形参
aliens,以便将它传递给
check_play_button()。接下来,我们修改了调用
check_play_button()的代码,以将合适的实参传递给它(见第39-40行)。要特别注意的是,笔者在这里将形参的其中两个的顺序弄错了,导致花了很多时间来debug 。
下面来修改alien_invasion.py中调用
check_events()的代码,以将实参
aliens传递给它:
如下图所示,现在,每当单击Play按钮时,这个游戏都将正确地重置:
9.5 将Play按钮切换到非活动状态:
当前,Play按钮存在一个问题,那就是即便Play按钮不可见,玩家单击其原来所在的区域时,游戏依然会作出响应。为修复这个问题:
标志
button_clicked的值为True 或False (见第44行),仅当玩家单击了 Play 按钮且游戏当前处于非活动状态时,游戏才重新开始(见第45行)。为测试这种行为,可开始新游戏,并不断地单击Play 按钮原来所在的区域。如果一切都像预期的那样工作,单击 Play 按钮原来所处的区域应该没有任何影响。
- Python 为什么没有 void 关键字?
- Python+OpenCV入门教程【十七】分水岭算法
- python爬虫 爬取小姐姐图片
- python-pandas模块2-基本数据类型2
- 第五节课numpy作业
- python-pandas模块1-基本数据类型1
- python高级-19.pandas - 重塑与轴向选择
- 数据分析第六节课numpy函数练习作业
- python高级-18.pandas - 合并数据集
- python标准库--logging模块
- python项目构建_通过构建4个项目来学习Python网络
- java/php/net/python作业批改系统的设计
- java/php/net/python作业管理系统设计
- java/php/net/python中国传统建筑设计
- Python+OpenCV入门教程【十六】图像的膨胀与腐蚀
- python3数据分析之Numpy
- java/php/net/python智慧景区票务系统设计
- java/php/net/python在线作业提交系统设计
- Python+OpenCV入门教程【十五】轮廓发现及对象测量
- java/php/net/python在线音乐播放系统设计