Python笔记16-实战小游戏飞机大战(下)

文章目录

  • play按钮
  • 重置游戏
  • 提高等级
  • 游戏完成

我们会添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏,还会修改这个游戏,使其随玩家等级提高而加快节奏。

play按钮

添加一个Play按钮,它在游戏开始前出现,并在游戏结束后再次出现,让玩家能够开始新游戏
让游戏一开始处于非活动状态,并提示玩家单击Play按钮来开始游戏

game_stats.py

def __init__(self, ai_game):"""初始化统计信息。"""self.settings = ai_game.settingsself.reset_stats()# 让游戏一开始处于非活动状态。self.game_active = False

于Pygame没有内置创建按钮的方法,我们将编写一个Button类,用于创建带标签的实心矩形
创建方法draw_button() ,用于将这个按钮显示到屏幕

import pygame.font
class Button:def __init__(self, ai_game, msg):"""初始化按钮的属性。"""self.screen = ai_game.screenself.screen_rect = self.screen.get_rect()# 设置按钮的尺寸和其他属性。self.width, self.height = 200, 50self.button_color = (0, 255, 0)self.text_color = (255, 255, 255)self.font = pygame.font.SysFont(None, 48)# 创建按钮的rect对象,并使其居中。self.rect = pygame.Rect(0, 0, self.width, self.height)self.rect.center = self.screen_rect.center# 按钮的标签只需创建一次。self._prep_msg(msg)def _prep_msg(self, msg):"""将msg渲染为图像,并使其在按钮上居中。"""self.msg_image = self.font.render(msg, True, self.text_color,self.button_color)self.msg_image_rect = self.msg_image.get_rect()self.msg_image_rect.center = self.rect.centerdef draw_button(self):# 绘制一个用颜色填充的按钮,再绘制文本。self.screen.fill(self.button_color, self.rect)self.screen.blit(self.msg_image, self.msg_image_rect)

在AlienInvasion 中使用Button 类来创建一个Play按钮

def __init__(self):--snip--self._create_fleet()# 创建Play按钮。self.play_button = Button(self, "Play")

在_update_screen() 对其调用方法draw_button()

    def _update_screen(self):"""更新屏幕上的图像,并切换到新屏幕。"""self.screen.fill(self.settings.bg_color)self.ship.blitme()for bullet in self.bullets.sprites():bullet.draw_bullet()self.aliens.draw(self.screen)# 如果游戏处于非活动状态,就绘制Play按钮。if not self.stats.game_active:self.play_button.draw_button()pygame.display.flip()

玩家单击Play按钮时开始新游戏,在_check_events() 末尾添加如下elif 代码块,以监视与该按钮相关的鼠标事件

     def _check_events(self):"""响应按键和鼠标事件。"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type == pygame.KEYDOWN:self._check_keydown_events( event)elif event.type == pygame.KEYUP:self._check_keyup_events( event)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_pos = pygame.mouse.get_pos()self._check_play_button(mouse_pos)

方法_check_play_button() 的代码如下,将它放在_check_events() 后面

   def _check_play_button(self, mouse_pos):"""在玩家单击Play按钮时开始新游戏。"""if self.play_button.rect.collidepoint(mouse_pos):self.stats.game_active = True

这里使用了rect 的方法collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内

重置游戏

为在玩家每次单击Play按钮时都重置游戏,需要重置统计信息、删除现有的外星人和子弹、创建一群新的外星人并让飞船居中

  def _check_play_button(self, mouse_pos):"""在玩家单击Play按钮时开始新游戏。"""if self.play_button.rect.collidepoint(mouse_pos):# 重置游戏统计信息。self.stats.reset_stats()self.stats.game_active = True# 清空余下的外星人和子弹。self.aliens.empty()self.bullets.empty()# 创建一群新的外星人并让飞船居中。self._create_fleet()self.ship.center_ship()

当前存在一个问题:即便Play按钮不可见,玩家单击其所在的区域时,游戏依然会做出响应。游戏开始后,如果玩家不小心单击了Play按钮所处的区域,游戏将重新开始!

   def _check_play_button(self, mouse_pos):"""在玩家单击Play按钮时开始新游戏。"""button_clicked = self.play_button.rect.collidepoint(mouse_pos)if button_clicked and not self.stats.game_active:# 重置游戏统计信息。self.stats.reset_stats()self.stats.game_active = True# 清空余下的外星人和子弹。self.aliens.empty()self.bullets.empty()# 创建一群新的外星人并让飞船居中。self._create_fleet()self.ship.center_ship()

隐藏鼠标光标

   def _check_play_button(self, mouse_pos):"""在玩家单击Play按钮时开始新游戏。"""button_clicked = self.play_button.rect.collidepoint(mouse_pos)if button_clicked and not self.stats.game_active:...# 隐藏鼠标光标。pygame.mouse.set_visible(False)

游戏结束后,将重新显示光标,让玩家能够单击Play按钮来开始新游戏。相关的代码如下:

def _ship_hit(self):"""响应飞船被外星人撞到。"""if self.stats.ships_left > 0:--snip--else:self.stats.game_active = Falsepygame.mouse.set_visible(True)

提高等级

将整群外星人消灭干净后,玩家将提高一个等级,但游戏的难度没变。下面来增加一点趣味性:每当玩家将屏幕上的外星人消灭干净后,都加快游戏的节奏,让游戏玩起来更难。

class Settings:"""存储游戏《外星人入侵》中所有设置的类"""def __init__(self):"""初始化游戏的设置。"""# 屏幕设置self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)#飞船移动速度self.ship_speed =5self.ship_limit = 3#子弹设置self.bullet_speed = 3.0self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60, 60, 60)self.bullets_allowed = 50# 外星人设置self.alien_speed = 1.0self.fleet_drop_speed = 30# fleet_direction为1表示向右移,为-1表示向左移。self.fleet_direction = 1# 加快游戏节奏的速度。self.speedup_scale = 1.1self.initialize_dynamic_settings()def initialize_dynamic_settings(self):"""初始化随游戏进行而变化的设置。"""self.ship_speed = 1.5self.bullet_speed = 3.0self.alien_speed = 1.0# fleet_direction为1表示向右,为-1表示向左。self.fleet_direction = 1#在玩家的等级提高时提高飞船、子弹和外星人的速度def increase_speed(self):"""提高速度设置"""self.ship_speed *= self.speedup_scaleself.bullet_speed *= self.speedup_scaleself.alien_speed *= self.speedup_scale

在_check_bullet_alien_collisions() 中,在整群外星人都被消灭后调用increase_speed() 来加快游戏的节奏

def _update_bullets(self):"""更新子弹的位置并删除消失的子弹。"""# 更新子弹的位置。self.bullets.update()# 删除消失的子弹。for bullet in self.bullets.copy():if bullet.rect.bottom <= 0:self.bullets.remove(bullet)# 检查是否有子弹击中了外星人。# 如果是,就删除相应的子弹和外星人。self._check_bullet_alien_collisions()def _check_bullet_alien_collisions(self):"""响应子弹和外星人碰撞。"""# 删除发生碰撞的子弹和外星人。collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)if not self.aliens:# 删除现有的所有子弹,并创建一群新的外星人。self.bullets.empty()self._create_fleet()self.settings.increase_speed()

每当玩家开始新游戏时,都需要将发生了变化的设置重置为初始值

def _check_play_button(self, mouse_pos):"""在玩家单击Play按钮时开始新游戏。"""button_clicked = self.play_button.rect.collidepoint(mouse_pos)if button_clicked and not self.stats.game_active:# 重置游戏设置。self.settings.initialize_dynamic_settings()--snip--

游戏完成

到目前为止,这个小游戏 就可以不断的 玩了。可以根据需要调整各项参数。
源码下载地址:点击下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/655152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spark系列4】Task的执行

一、Task的执行流程 1.1、Task执行流程 DAGScheduler将Stage生成TaskSet之后&#xff0c;会将Task交给TaskScheduler进行处理&#xff0c;TaskScheduler负责将Task提交到集群中运行&#xff0c;并负责失败重试&#xff0c;为DAGScheduler返回事件信息等&#xff0c;整体如流程…

OpenGL ES 渲染 NV21、NV12 格式图像有哪些“姿势”?

使用2个纹理实现 NV21 格式图像渲染 前文提到渲染 NV21 格式图像需要使用 2 个纹理,分别用于保存 Y plane 和 UV plane 的数据,然后在片段着色器中分别对 2 个纹理进行采样,转换成 RGB 数据。 OpenGLES 渲染 NV21或 NV12 格式图像需要用到 GL_LUMINANCE 和 GL_LUMINANCE_A…

http和https的区别是什么?https有什么优缺点?

HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。这个简单模型是早期Web成功的有功之臣&#xff0c;因为它…

The following untracked working tree files would be overwritten by merge问题的解决

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 在更新git仓库时出现了一个The following untracked working tree files would be overwritten by merge的错误&#xff0c;具体如下图&#xff1a; 分析…

windows下安装Linux虚拟机

一、 一般情况使用VMware虚拟机&#xff08;个人习惯&#xff0c;也可以使用红帽&#xff09; 下载VMware Workstation 虚拟机&#xff0c; 网址&#xff1a;https://vmware-workstation.en.softonic.com/ 二、 下载CentOS镜像文件&#xff0c; 网址&#xff1a;https://ww…

ES 分词器

概述 分词器的主要作用将用户输入的一段文本&#xff0c;按照一定逻辑&#xff0c;分析成多个词语的一种工具 什么是分词器 顾名思义&#xff0c;文本分析就是把全文本转换成一系列单词&#xff08;term/token&#xff09;的过程&#xff0c;也叫分词。在 ES 中&#xff0c;Ana…

深入理解vue相关的底层原理

keep-alive 组件的作用及原理 keep-alive 是 Vue 提供的一个内置组件&#xff0c;在组件切换过程中将状态保留在内存中&#xff0c;防止重复渲染 DOM。 如果为一个组件包裹了 keep-alive&#xff0c;那么它会多出两个生命周期&#xff1a;deactivated、activated。同时&#…

代码随想录算法训练营Day38|动态规划理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

目录 动态规划理论基础 什么是动态规划 动态规划的解题步骤 动态规划的debug 509. 斐波那契数 前言 思路 算法实现 方法一&#xff1a;动态规划 方法二&#xff1a;递归法 70. 爬楼梯 前言 思路 算法实现 拓展 746. 使用最小花费爬楼梯 算法实现 总结 动态规划…

2024年新提出的算法:(凤头豪猪优化器)冠豪猪优化算法Crested Porcupine Optimizer(附Matlab代码)

本次介绍一种新的自然启发式元启发式算法——凤头豪猪优化器(Crested Porcupine Optimizer&#xff0c;CPO)。该成果于2024年1月发表在中科院1区SCI top期刊Knowledge-Based Systems&#xff08;IF 8.8&#xff09;上。 1、简介 受到凤头豪猪&#xff08;CP&#xff09;各种…

iOS 自动打包如何配置配置打包证书和profile provision文件【脚本方式配置】

iOS 最新Jenkins自动化打包总结 本文主要内容&#xff1a; 1.Xcode和Jenkins的相关设置&#xff0c;以及环境切换 2.通过shell脚本将证书和描述文件拷贝到自动化打包的机器&#xff0c;并archive导出ipa包 3.上传到蒲公英 4.解决Swift不支持use_frameworks!的问题 开搞&…

【开源】SpringBoot框架开发天然气工程业务管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…

[Grafana]ES数据源Alert告警发送

简单的记录一下使用es作为数据源&#xff0c;如何在发送告警是带上相关字段 目录 前言 一、邮件配置 二、配置 1.Query 2.Alerts 总结 前言 ES作为数据源&#xff0c;算是Grafana中比较常见的&#xff0c;Alerts告警是我近期刚接触&#xff0c;有一个需求是当表空间大于…

如何使用ssh key免密码登录服务器?

以下是使用密钥对免密码登录服务器的具体指令操作步骤&#xff1a; 步骤一&#xff1a;生成密钥对 在本地电脑上打开终端或命令提示符&#xff0c;运行以下命令生成密钥对&#xff1a; ssh-keygen -t rsa -C "your_emailexample.com" 该命令会提示您选择保存密钥…

flutter实现:使用三方组件syncfusion_flutter_datagrid

Syncfusion Flutter DataGrid 是一个用于 Flutter 的数据网格组件&#xff0c;它提供了丰富的功能来显示和编辑数据。这个组件提供了灵活的配置选项&#xff0c;使得开发者能够根据需要定制数据的显示和编辑方式。 项目中有两个需求&#xff0c;一是在列表中要使用可变高度&am…

OpenCV 5 - 图像混合处理addWeighted()

图像混合 1 理论-线性混合操作 其中α的取值范围为0~1之间,表示图像的所占的权重 2 混合处理函数addWeighted() 3 代码示例 Mat src1, src2, dst;src1 imread("./1.png");src2 imread("./2.png");if (!src1.data && src2.empty()) //判断图片是…

Flutter WebView之给H5网页图片添加点击事件以实现原生图片预览

Flutter WebView之给H5网页图片添加点击事件以实现原生图片预览 前言环境及插件代码实现参考前言 网上很多方案,都是获取html中的图片列表,再往里面添加点击事件。 思路是没错的,但是由于很多H5使用的VUE或者Ajax等技术异步加载渲染,因此此处需要借助jQuery库给一步渲染的…

微信小程序canvas画布实现椭圆元素自由缩放、移动功能

目录 实现效果 ​编辑 一、获取画布信息并绘制背景 二、绘制椭圆

《微信小程序开发从入门到实战》学习九十七

7.3 表单组件 7.3.1 picke-view与picker-view-column组件 一个picker-view-column代表 一个滚动选择器子项&#xff0c;一个picker-view组件可以包含多个picker-view-column组件&#xff0c;这样可以一次性选择多项内容如年、月、日等。 picker-view-column组件中需包含多个…

云安全中的常见云漏洞和威胁,有哪些防范措施

随着企业在数字化时代的脚步中愈发倚重云托管服务&#xff0c;云安全问题成为不容忽视的焦点。云服务的便捷性为企业提供了强大的存储和计算能力&#xff0c;然而&#xff0c;与之伴随而来的攻击风险也日益显著。最新的研究数据揭示&#xff0c;云安全漏洞可能导致的数据泄露&a…

ETCD监控方法以及核心指标

文章目录 1. 监控指标采集1.1 监控指标采集1.2 配置promethues采集和大盘 2. 核心告警指标3. 参考文章 探讨etcd的监控数据采集方式以及需要关注的核心指标&#xff0c;便于日常生产进行监控和巡检。 1. 监控指标采集 etcd默认通过/metrics指标暴露相关指标&#xff0c;因此不…