当前位置: 首页 > news >正文

Python学习笔记50:游戏篇之外星人入侵(十一)

前言

本篇文章接着之前的内容,继续对游戏功能进行优化,主要是优化游戏状态以及对应的处理。

状态

一个游戏包含多种状态,这个状态是一个可以很复杂也可以很简单的内容。条件所限,我们这个游戏的状态就比较简单:

  • 未开始
  • 游戏中
  • 暂停
  • 结束

我们通过一个字段进行控制,并且将这个字段放置到setting模块中。

class Setting:"""系统设置类"""def __init__(self):-- snip --# 游戏状态:0未开始,1游戏中,2暂停,3结束self.game_status = 0

处理状态

根据不同的状态值,我们先对main模块进行简单的处理。

import pygame
from pygame.sprite import Groupimport alien_invasion.game_functions as gf
from alien_invasion.setting import Setting
from alien_invasion.ship import Shipdef run_game():"""启动游戏"""# 初始化pygamepygame.init()# 定义一个系统设置对象setting = Setting()# 新建窗口screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))# 窗口命名pygame.display.set_caption(setting.caption)# 定义一个飞船对象ship = Ship(setting, screen)# 创建子弹编组bullets = Group()# 创建外星人编组aliens = Group()# 创建编组内的外星人gf.create_fleet(setting, screen, aliens)while True:if setting.game_status == 0:passelif setting.game_status == 1:# 处理监听事件gf.check_event(ship, setting, screen, bullets)# 移动飞船ship.move()# 更新子弹位置gf.update_bullets(bullets, aliens, setting, screen)# 更新外星人gf.update_aliens(aliens, setting, ship)# 刷新屏幕gf.update_screen(setting, screen, ship, bullets, aliens)elif setting.game_status == 2:passelif setting.game_status == 3:passif __name__ == '__main__':run_game()

状态对应的业务

现在,我们要对状态思考响应的游戏业务。

这里直接描述一下我个人简单预定的功能:

  1. 启动游戏,弹出窗口,显示欢迎来到游戏,按回车键开始游戏。其他所有按键不生效。
  2. 在游戏中,按下回车暂停游戏;暂停游戏时按下回车继续游戏
  3. 开始游戏后,任意时刻按下Esc键退出游戏,回到黑色窗口,显示游戏介绍,暂停一秒关闭游戏。

代码实现

我们在第二步已经简单的对状态值进行了处理,接下来就根据上面的业务在对应的状态处理部分一一填充。

首先我们处理开始游戏的状态。

开始游戏

首先我们需要在setting.game_status == 0的条件下新建一个not_start()函数,传入参数settingscreen。这两个参数一个是要回写状态值到配置模块中,一个是渲染游戏窗口需要的一些属性。

修改main模块中循环处理的部分如下:

-- snip --while True:# 没啥用,方便编写代码的时候看看代码执行情况print(setting.game_status)if setting.game_status == 0:# 处理没启动的业务逻辑gf.not_start(setting, screen)-- snip --

main模块处理好以后,我们在gf模块进行实际的业务代码编写。

在函数中,我们需要完成两个功能,一个是渲染文字,一个是监听按键事件,是否有开始游戏,那么代码编写如下:

def not_start(setting, screen):# 先渲染文字handle_text(screen)print("not_start")# 处理监听事件for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:if setting.game_status == 0:setting.game_status = 1print("开始游戏")

这里监听事件的部分没有单独拉函数出来,主要是不影响阅读,不过因为渲染文字的函数有点行数并且也算一个比较独立的功能,所以又单独创建了一个函数,后面的结束也是如此。

另外虽然我们这个时候只监听是否按下回车键的这个事件,但是点击退出窗口的监听事件,在任何地方都不能忘了,不然到时候可能你的窗口关不了,只能去通过停止程序关闭。

监听事件的代码比较简单的,就是在确认是按下了回车,状态是0的时候,回写状态值即可。

我们看看文字渲染的代码。

文字渲染我们在项目开始之前介绍pygame就提前讲过,相比大家都不陌生,看代码注释即可,代码如下:

def handle_text(screen):# 字体颜色pink = pygame.Color('#FFFFFF')# 使用Arial字体创建一个字体对象,32号,加粗,倾斜font = arial_bold = pygame.font.SysFont('Arial', 32, bold=True, italic=True)# 渲染文本text_surface1 = font.render("Welcome to the Game Of Alien Invasion", True, pink)# 获取文件的矩形区域text_rect1 = text_surface1.get_rect()# 设置文本Y坐标320,居中位置text_rect1.midtop = (screen.get_width() // 2, 320)# 渲染文本text_surface2 = font.render("Press The Enter Key To Start The Game", True, pink)# 获取文件的矩形区域text_rect2 = text_surface2.get_rect()# 设置文本Y坐标420,居中位置text_rect2.midtop = (screen.get_width() // 2, 420)# 绘制文本screen.blit(text_surface1, text_rect1)screen.blit(text_surface2, text_rect2)# 更新显示pygame.display.flip()

运行main模块,按下回车。

在这里插入图片描述
可以看到文字正常渲染,并且输出栏一直在出输出当前状态。

如果你觉得画面单调,可以自己加点东西渲染,pygame渲染图片这些相比也不陌生了。

按下回车,游戏正常开始!

在这里插入图片描述
可以看到,已经进入到游戏页面,并且输出栏的状态值也变成了1。

游戏中

游戏中的处理比较简单,因为我们之前已经完成了游戏中的代码编写,所以我们只需要在游戏中的监听事件中加上回车键的监听事件暂停游戏。

ps: 这里其实也可以结束游戏,代码我先写上,但是不操作。业务代码也不复杂,就是多加一个Esc键的监听事件。

gf模块中的check_keydown_events()函数代码修改如下:

def check_keydown_events(event, ship, setting, screen, bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_UP:ship.moving_top = Trueelif event.key == pygame.K_DOWN:ship.moving_bottom = Trueelif event.key == pygame.K_SPACE:fire(bullets, screen, setting, ship)elif event.key == pygame.K_q:sys.exit()elif event.key == pygame.K_RETURN:if setting.game_status == 1:setting.game_status = 2print("暂停游戏")elif event.key == pygame.K_ESCAPE:setting.game_status = 3print("游戏结束")

启动main模块,开始游戏后再按回车,效果如下:

在这里插入图片描述

可以看到,我们的飞船,子弹,外星人全部暂停住了,输出栏一直打印状态也变成了2(暂停)。

屏幕中显示了一些文字,这些其实是暂停的业务。

我们马上进行暂停的业务代码编写。

暂停游戏

参考开始游戏的实现,我们在暂停的分支下调用一个函数stop()

main模块循环部分代码如下:

	-- snip --while True:# 没啥用,方便编写代码的时候看看代码执行情况print(setting.game_status)if setting.game_status == 0:# 处理没启动的业务逻辑gf.not_start(setting, screen)elif setting.game_status == 1:# 处理监听事件gf.check_event(ship, setting, screen, bullets)# 移动飞船ship.move()# 更新子弹位置gf.update_bullets(bullets, aliens, setting, screen)# 更新外星人gf.update_aliens(aliens, setting, ship)# 刷新屏幕gf.update_screen(setting, screen, ship, bullets, aliens)elif setting.game_status == 2:gf.stop(setting, screen)-- snip --

同样,我们去到gf模块创建stop()函数并实现相应的功能,代码如下:

-- snip --
def stop(setting, screen):handle_stop_text(screen)for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:if setting.game_status == 2:setting.game_status = 1print("继续游戏")elif event.key == pygame.K_ESCAPE:setting.game_status == 3:print("结束游戏")
-- snip --

代码依旧分两部分实现,渲染文字和监听事件。在暂停的监听事件中我们和开始一样,监听关闭窗口,回车和结束,并在回车事件中回写状态值,让游戏继续运行,在Esc时间中结束游戏。

文字渲染部分代码如下:

def handle_stop_text(screen):# 字体颜色pink = pygame.Color('#000000')# 使用Arial字体创建一个字体对象,32号,加粗,倾斜font = arial_bold = pygame.font.SysFont('Arial', 32, bold=True, italic=True)# 渲染文本text_surface1 = font.render("Game Stop", True, pink)# 获取文件的矩形区域text_rect1 = text_surface1.get_rect()# 设置文本Y坐标50,居中位置text_rect1.midtop = (screen.get_width() // 2, 320)# 渲染文本text_surface2 = font.render("Press The Enter Key To restore The Game", True, pink)# 获取文件的矩形区域text_rect2 = text_surface2.get_rect()# 设置文本Y坐标50,居中位置text_rect2.midtop = (screen.get_width() // 2, 420)# 绘制文本screen.blit(text_surface1, text_rect1)screen.blit(text_surface2, text_rect2)# 更新显示pygame.display.flip()

基本上就是复制开始的文字渲染,改了下文字内容。

效果的话这里就不展示了,就是暂停开始,开始暂停这一套。

结束游戏

在游戏中和暂停的时候,我们都可以通过按键Esc实现游戏结束。

main模块的改动依旧是调用一个结束函数,但是结束函数不需要回写状态值,所以我们只需要一个screen参数。

代码如下:

while True:# 没啥用,方便编写代码的时候看看代码执行情况print(setting.game_status)if setting.game_status == 0:# 处理没启动的业务逻辑gf.not_start(setting, screen)elif setting.game_status == 1:# 处理监听事件gf.check_event(ship, setting, screen, bullets)# 移动飞船ship.move()# 更新子弹位置gf.update_bullets(bullets, aliens, setting, screen)# 更新外星人gf.update_aliens(aliens, setting, ship)# 刷新屏幕gf.update_screen(setting, screen, ship, bullets, aliens)elif setting.game_status == 2:gf.stop(setting, screen)elif setting.game_status == 3:gf.end(screen)

gf模块改动如下:

def end(screen):# 重新填充屏幕screen.fill((0, 0, 0))# 渲染文字handle_end_text(screen)# 休眠一秒sleep(1)# 退出pygame.quit()sys.exit()

和之前比对有一点不同,多了几部,其实没有特别含义,就是看起来流畅好看一点。

文字渲染代码如下:

def handle_end_text(screen):# 字体颜色pink = pygame.Color('#FFFFFF')# 使用Arial字体创建一个字体对象,32号,加粗,倾斜font = arial_bold = pygame.font.SysFont('Arial', 48, bold=True, italic=True)# 渲染文本text_surface1 = font.render("Game Over", True, pink)# 获取文件的矩形区域text_rect1 = text_surface1.get_rect()# 设置文本Y坐标50,居中位置text_rect1.midtop = (screen.get_width() // 2, screen.get_height() // 2)# 绘制文本screen.blit(text_surface1, text_rect1)# 更新显示pygame.display.flip()

运行效果如下:

在这里插入图片描述

结尾

今天的内容就是这些,设定状态值,并且在对应的状态中处理不同的逻辑,渲染不同的画面。

当然我们是学习,所以内容都比较简单,有兴趣的话可以深入一下加点自己的元素进去。

后面我们继续优化游戏功能,加油!!!

相关文章:

Python学习笔记50:游戏篇之外星人入侵(十一)

前言 本篇文章接着之前的内容,继续对游戏功能进行优化,主要是优化游戏状态以及对应的处理。 状态 一个游戏包含多种状态,这个状态是一个可以很复杂也可以很简单的内容。条件所限,我们这个游戏的状态就比较简单: 未…...

vue3踩坑问题记录

//vue3element-plus //1、placeholder换行显示 const startTxt ref() const contentText ref<any>() startTxt.value "请描述问题内容、例如&#xff1a;" historyData.prompt.forEach((el:any)>{contentText.value \n${el.question}}) <ElInputv-mo…...

Python 爬虫实战:Scrapy 框架详解与应用

&#x1f6e0;️ Scrapy 框架基本使用 Scrapy 是一个强大的 Python 爬虫框架&#xff0c;提供了用于提取和处理网页数据的功能。以下是 Scrapy 的基本使用步骤&#xff1a; 安装 Scrapy pip install scrapy创建 Scrapy 项目 scrapy startproject myproject这将生成一个基础…...

60 函数参数——关键参数

关键参数主要指调用函数时的参数传递方式&#xff0c;与函数定义无关。 通过关键参数可以按参数名字传递值&#xff0c;明确指定哪个值传递给哪个参数&#xff0c;实参顺序可以和形参顺序不一致&#xff0c;但不影响参数值的传递结果&#xff0c;避免了用户需要牢记参数位置和…...

wps 最新 2019 专业版 下载安装教程,解锁全部功能,免费领取

文章目录 前言软件介绍软件下载安装步骤激活步骤小福利&#xff08;安卓APP&#xff09;软件介绍软件下载安装步骤 前言 本篇文章主要针对WPS2019专业版的安装下载进行详细讲解&#xff0c;软件已激活&#xff0c;可放心使用&#xff1b;并且可以进行账号登录&#xff0c;进行…...

前端(三):Ajax

一、Ajax Asynchronous JavaScript And XML&#xff0c;简称Ajax&#xff0c;是异步的JavaScript和XML。 作用&#xff1a;数据交换&#xff0c;通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互&#xff1a;可以在不重新加载整个页面的情况下&…...

启动 /使用/关闭 Redis 服务器

1. Linux 启动 Linux 系统启动 Redis 有两种方法&#xff0c;分别是前台启动&#xff0c;后台启动&#xff0c;两者各有差异&#xff1b; &#xff08;1&#xff09;前台启动 首先&#xff0c;需要进入 bin 路径(安装路径不同输入的命令也不同); 个人的命令&#xff08;一般…...

Linux系统中的高级SELinux安全策略定制技术

随着信息技术的发展&#xff0c;计算机系统的安全性变得越来越重要。在开源世界中&#xff0c;Linux作为一种广泛应用的操作系统&#xff0c;其安全性一直备受关注。其中&#xff0c;SELinux&#xff08;Security-Enhanced Linux&#xff09;作为Linux系统中的一个安全模块&…...

使用 Ansible Blocks 进行错误处理

注&#xff1a;机翻&#xff0c;未校。 How to Use Ansible Blocks Make your Playbooks more readable and maintainable using Blocks feature in Ansible. 使用 Ansible 中的块功能使 Playbook 更具可读性和可维护性。 Jul 15, 2024 — LHB Community How to Use Ansible…...

java中的静态变量和实例变量的区别

java中的静态变量和实例变量的区别 在Java中&#xff0c;静态变量&#xff08;也称为类变量&#xff09;和实例变量是两种不同类型的变量&#xff0c;它们在多个方面存在显著的区别。以下是它们之间的一些主要区别&#xff1a; 存储位置 静态变量&#xff1a;存储在方法区&am…...

【Effecutive C++】条款02 尽量以const, enum, inline替换 #define

Prefer consts, enums, and inline to #define. 这个条款或许改为“宁可以编译器替换预处理器”比较好&#xff0c;因为或许#define不被视为语言的一部分。那正是它的问题所在。当你做出这样的事情&#xff1a; #define ASPECT_RATIO 1.653记号名称ASPECT_RATIO也许从未被编译…...

leetcode-226. 翻转二叉树

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,3,1]…...

用的到linux-tomcat端口占用排查-Day5

前言&#xff1a; 最近使用tomcat搭建了一套测试环境的应用&#xff0c;整个搭建过程也很简单&#xff0c;就是将部署包上传至服务器☞解压☞启动tomcat服务器&#xff0c;当然服务器也是成功启动了&#xff0c;但是发现前端应用报404&#xff0c;具体如下图所示。 一、现象及思…...

mqtt协议详解(0)初步认识mqtt

文章目录 1. 介绍2. 主要特性3. 架构1. 介绍 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种构建在TCP/IP协议之上的轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境,例如IOT。 MQTT 协议于 1…...

Java语言程序设计基础篇_编程练习题*16.7 (设置时钟的时间)

*16.7 (设置时钟的时间) 编写一个程序&#xff0c;显示一个时钟&#xff0c;并通过在三个文本域中输入小时、分钟和秒 钟来设置时钟的时间&#xff0c;如图16-38b 所示。使用程序清单14-21的ClockPane改变时钟大小使其居于面板中央 习题思路 实例化一个ClockPane(在程序清单1…...

YOLOv8新版本支持实时检测Transformer(RT-DETR)、SAM分割一切

原文:YOLOv8新版本支持实时检测Transformer(RT-DETR)、SAM分割一切 - 知乎 (zhihu.com) 一、SAM 分割任何模型 (Segment Anything Model - SAM) 是一种突破性的图像分割模型,可实现具有实时性能的快速分割。 项目地址 https://github.com/facebookresearch/segment-…...

【传输层协议】UDP和TCP协议

文章目录 UDP协议UDP特点UDP的缓冲区基于UDP的应用层协议 TCP协议6位标志位&#xff1a;确认应答机制超时重传机制连接管理机制&#xff08;握手和挥手&#xff09;服务端状态转换过程客户端状态转换过程TIME_WAIT状态CLOSE_WAIT状态 为什么是三次握手和四次挥手滑动窗口如果发…...

Java Excel复杂表头,表头合并单元格

Java Excel复杂表头&#xff0c;表头合并单元格 效果预览 一、maven依赖 <!--操作excel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version><scope>test</…...

Java整合腾讯云发送短信实战Demo

简介 在现代应用开发中&#xff0c;短信服务是非常重要的功能之一。它可以用于用户验证、通知等各种场景。本文将介绍如何使用Java整合腾讯云短信服务&#xff0c;并提供一个完整的实战示例代码。 环境准备 在开始之前&#xff0c;确保你已经完成以下准备工作&#xff1a; 注…...

电路中电阻,电容和电感作用总结

电阻作用 1&#xff0c;上拉电阻 电阻的连接一般是一端接上拉的电源&#xff08;一般与芯片信号的电压值相匹配&#xff09;&#xff0c;另一端连接芯片引脚所对应的信号大概如下图 功能&#xff1a;一、预置某些引脚的功能&#xff0c;例如复位信号拉高&#xff08;失能&…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...