Python-项目实战--飞机大战-英雄登场(7)
目标
设计英雄和子弹类
使用pygame.key.get_pressed()移动英雄
发射子弹
1.设计英雄和子弹类
1.1英雄需求
游戏启动后,英雄出现在屏幕的水平中间位置,距离屏幕底部120像素
英雄每隔0.5秒发射一次子弹,每次连发三枚子弹
英雄默认不会移动,需要通过左/右方向键,控制英雄在水平方向移动

1.2子弹需求
子弹从英雄的正上方发射沿直线向上方飞行,飞出屏幕后,需要从精灵组中删除

Hero -- 英雄
初始化方法
指定英雄图片
初始速度 = 0 -- 英雄默认静止不动
定义bullets子弹精灵组保存子弹精灵
重写update()方法
英雄需要水平移动
并且需要保证不能移出屏幕
增加bullets属性,记录所有子弹精灵
增加fire方法,用于发射子弹
Bullet -- 子弹
初始化方法
指定子弹图片
初始速度= -2 -- 子弹需要向上方飞行
重写update()方法
判断是否飞出屏幕,如果是,从精灵组删除
2.创建英雄
2.1准备英雄类
分析
在plane_sprites新建Hero类
重写初始化方法,直接指定图片名称,并且将初始速度设置为0
设置英雄的初始位置

centerx = x + 0.5 * width
centery = y + 0.5 * height
bottom = y + height

代码演示
在plane_sprites.py中新建Hero类
class Hero(GameSprite):"""英雄精灵"""def __init__(self):# 1.调用父类方法,设置image&speedsuper().__init__("./images/me1.png", 0)# 2.设置英雄的初始位置self.rect.centerx = SCREEN_RECT.centerxself.rect.bottom = SCREEN_RECT.bottom - 1202.2绘制英雄
分析
在__create_sprites,添加英雄精灵和英雄精灵组
后续要针对英雄做碰撞检测以及发射子弹,所以英雄需要单独定义成属性
在__update_sprites,让英雄精灵组调用update和draw方法
代码演示
在plane_main.py中修改__create_sprites方法
# 创建英雄的精灵和精灵组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)在plane_main.py中修改__update_sprites方法
self.hero_group.update()
self.hero_group.draw(self.screen)3.移动英雄位置
在pygame中针对键盘按键的捕获,有两种方式
第一种方式:判断event.type == pygame.KEYDOWN
第二种方式:
首先使用pygame.key.get_pressed()返回所有按键元组
通过键盘常量,判断元组中某一个键是否被按下 -- 如果被按下,对应数值为1
请问:这两种方式的区别?
第一种方式
向右移动的按键如果被一直按下,控制台只会输出一个 向右移动,需要松开按键重新按下,飞机才能持续向右移动
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:print("向右移动...")
第二种方式
向右移动的按键如果被一直按下(按下不放),控制台会输出多个 向右移动,按键不需要松开,飞机就可以持续向右移动
# 使用键盘提供的方法获取键盘按键。返回所有按键的元组,如果某个键被按下,对应的值会是1
keys_pressed = pygame.key.get_pressed()
# 判是否按下了方向键
if keys_pressed[pygame.K_RIGHT]:print("向右移动...")
结论
第一种方式event.type用户 必须要抬起按键才算一次 按键事件,操作灵活性会大打折扣
第二种方式用户可以按住方向键不放,就能够实现持续向某一个方向移动了,操作灵活性更好
3.1移动英雄位置
演练步骤
在Hero类中重写update方法
用速度speed和英雄rect.x进行叠加
不需要调用父类方法 -- 父类方法只是实现了单纯的垂直运动
在__event_handler方法中根据左右方向键设置英雄的速度
向右 => speed = 2
向左 => speed =-2
其他 => speed = 0
代码演练
在Hero类,重写update()方法,根据速度水平移动英雄的飞机
在plane_sprites.py的Hero类中重写update()方法
def update(self):# 英雄在水平方向移动self.rect.x += self.speed在plane_main.py的__event_handler方法中根据左右方向键设置英雄的速度
# 使用键盘提供的方法获取键盘按键。返回所有按键的元组,如果某个键被按下,对应的值会是1
keys_pressed = pygame.key.get_pressed()
# 判是否按下了方向键
if keys_pressed[pygame.K_RIGHT]:self.hero.speed = 2
elif keys_pressed[pygame.K_LEFT]:self.hero.speed = -2
else:self.hero.speed = 03.2控制英雄运动边界
在plane_sprites.py的Hero类的update()方法中判断英雄是否超出屏幕边界

right = x + width利用right属性可以非常容易的针对右侧设置精灵位置

代码演练
在plane_sprites.py的Hero类的update()方法中判断英雄是否超出屏幕边界
def update(self):# 英雄在水平方向移动self.rect.x += self.speed# 控制英雄不能离开屏幕if self.rect.x < 0:self.rect.x = 0elif self.rect.right > SCREEN_RECT.right:self.rect.right = SCREEN_RECT.right4.发射子弹
需求回顾 -- 英雄需求
游戏启动后,英雄出现在屏幕的水平中间位置,距离屏幕底部120像素
英雄每隔0.5秒发射一次子弹,每次连发三枚子弹
英雄默认不会移动,需要通过左/右方向键,控制英雄在水平方向移动
4.1添加发射子弹事件
分析
pygame的定时器使用方法非常固定
定义定时器常量 -- eventid
在初始化方法中,调用set_timer方法设置定时器事件
在游戏循环中,监听定时器事件
代码演练
在plane_sprites.py中的Hero类中定义fire方法
def fire(self):print("发射子弹...")在plane_sprites.py中的顶部定义英雄发射子弹事件
# 英雄发射子弹事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1在plane_main.py中的PlaneGame类的__init__方法中修改定时器事件
pygame.time.set_timer(HERO_FIRE_EVENT, 500)在plane_main.py中的PlaneGame类的__event_handler方法中让英雄发射子弹
elif event.type == HERO_FIRE_EVENT:self.hero.fire()4.2定义子弹类
需求回顾 -- 子弹需求
子弹从英雄的正上方发射沿直线向上方飞行,飞出屏幕后,需要从精灵组中删除
Bullet -- 子弹
初始化方法
指定子弹图片
初始速度= -2 -- 子弹需要向上方飞行
重写update()方法
判断是否飞出屏幕,如果是,从精灵组删除
定义子弹类
分析
在plane_sprites.py新建Bullet继承自GameSprite
重写初始化方法,调用父类方法,直接指定图片名称,并且设置初始速度
重写update()方法,调用父类方法,判断子弹飞出屏幕从精灵组删除
代码演练
class Bullet(GameSprite):"""子弹精灵"""def __init__(self):# 调用父类方法,设置子弹图片,设置初始速度super().__init__("./images/bullet1.png", -2)def update(self):# 调用父类方法,让子弹沿着垂直方向飞行super().update()# 判断子弹是否飞出屏幕if self.rect.bottom < 0:self.kill()4.3发射子弹
演练步骤
在Hero的初始化方法中创建子弹精灵组属性
修改plane_main.py的__update_sprites方法,让子弹精灵组调用update和draw方法
实现fire()方法
创建子弹精灵
设置初始位置 -- 在英雄的正上方
将子弹添加到精灵组
代码实现
初始化方法
plane_sprites.py中的Hero类中修改初始化方法
# 3.创建子弹精灵组self.bullets = pygame.sprite.Group()修改fire()方法
plane_sprites.py中的Hero类中修改fire()方法
def fire(self):print("发射子弹...")# 1.创建子弹精灵bullet = Bullet()# 2.设置精灵位置,比英雄的y值小20个像素bullet.rect.bottom = self.rect.y - 20bullet.rect.centerx = self.rect.centerx# 3.将精灵添加到精灵组self.bullets.add(bullet)一次发射三枚子弹

修改fire()方法
plane_sprites.py中的Hero类中修改fire()方法,利用for循环
def fire(self):print("发射子弹...")for i in (0, 1, 2):# 1.创建子弹精灵bullet = Bullet()# 2.设置精灵位置,比英雄的y值小20个像素bullet.rect.bottom = self.rect.y - i * 20bullet.rect.centerx = self.rect.centerx# 3.将精灵添加到精灵组self.bullets.add(bullet)内容总结于:https://space.bilibili.com/37974444
相关文章:
Python-项目实战--飞机大战-英雄登场(7)
目标设计英雄和子弹类使用pygame.key.get_pressed()移动英雄发射子弹1.设计英雄和子弹类1.1英雄需求游戏启动后,英雄出现在屏幕的水平中间位置,距离屏幕底部120像素英雄每隔0.5秒发射一次子弹,每次连发三枚子弹英雄默认不会移动,需…...
寒假安全作业nginx-host绕过实例复现
1.测试环境搭建 LNMP架构的话,肯定就是linux、nginx、mysql、php四大组件。在后面的复现中我们还会用到https的一部分知识,故这里的nginx就需要使用虚拟主机并且配置https证书,且具有php解析功能。 1.1 基础nginx配置 #1.创建web目录 mkdir …...
RocketMQ-消息消费模式 顺序消费
RocketMQ-消息消费模式 顺序消费RocketMQ-消息消费模式集群模式集群模式的演示(本身就默认)Rocketmq存储队列广播模式顺序消费如何改实现顺序消费RocketMQ-消息消费模式 集群模式 在消费模式为集群的情况下,如果机器是集群的,消息只会给集群中的其中一台机器消费到 集群模…...
一、Java并发编程之线程、synchronized
黑马课程 文章目录1. Java线程1.1 创建和运行线程方法一:Thread方法二:Runnable(推荐)lambda精简Thread和runnable原理方法三:FutureTask配合Thread1.2 查看进程和线程的方法1.3 线程运行原理栈与栈帧线程上下文切换1.…...
12.hadoop系列之MapReduce分区实践
本文我们学习MapReduce默认分区以及自定义分区实践 当我们要求将统计结果按照条件输出到不同文件(分区),比如按照统计结果将手机归属地不同省份输出到不同文件中(分区) 1.默认Partitioner分区 public class HashPartitioner<K, V> extends Partitioner<…...
有了独自开,一个人就是一个团队
文章目录 简单介绍优点 优秀案例平台福利总结 简单介绍 独自开是一个基于商品与服务交易全流程的PaaS开发平台。对于开发者,独自开可以协助开发者一个人独自开发一套系统。 优点 独自开有独创的分层标准化平台架构,可以满足系统的任何个性化需求。 …...
web期末复习 2023.02.11
文章目录Web 的概念Web 组成用户通过浏览器请求资源的过程:HTML 超文本标记语言CSS插入样式表的方法有三种:对象,类,实例一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:JavaScript 用法什么是 Java Server Pages?JSP 注释JSP 的 J…...
第44章 用户密码实体及其约束规则的定义实现
1 说明: 由当前程序需要兼容实现多种用户密码的加密操作,所以必须把“CustomerPassword”定义为实体类,该类用于用于把加密方式、密钥及其加密后的密码持久化到“CustomerPassword”表中,以便用为用户登录操作提供验证支撑。 如果…...
聊聊并发与锁
持续坚持原创输出,点击蓝字关注我吧1.并发与并行并发可以充分地利用 CPU 资源,一般都会使用多线程实现。多线程的作用是提高任务的平均执行速度,但是会导致程序可理解性变差,编程难度加大。关于对并发与并行的概念,大家…...
开源项目 —— 原生JS实现斗地主游戏 ——代码极少、功能都有、直接粘贴即用
目录 效果如下 目录结构 GameEntity.js GrawGame.js konva.min.js PlayGame.js veriable.js index.html 结语: 前期回顾 卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://…...
Linux第四讲
目录 四、shell脚本 4.1 shell和shell脚本 4.2 脚本语言分类 4.2.1 编译型语言 4.2.2 解释型语言 4.2.3 脚本语言 4.3 shell常见种类 4.3.1 shell分类介绍 4.3.2 查看bash版本 4.3.3 sh和bash的关系 4.4 脚本书写规范 4.4.1 选择解释器 4.4.2 开发规范 4.5 shell…...
Redis 持久化
持久化是指数据写到物理硬盘里,即便程序崩溃、或者电脑重启,依然能够恢复。Redis提供了两种持久化机制:RDB和AOF。 RDB(Redis Database): RDB文件相当于内存快照,保存了某个时间点数据库信息。使用RDB文件恢复很简单,将…...
Python语言零基础入门教程(十三)
Python 字典(Dictionary) 字典是另一种可变容器模型,且可存储任意类型对象。 字典的每个键值 key:value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示: d {key1 : value1, key2 : …...
江苏五年制专转本应该复习几轮?
五年制专转本应该复习几轮? 据调查统计:2022年专转本17%的考生复习三轮及以上,23%的考生复习了两轮。这两类的考生录取率高至85%。可见复习轮数多,专转本上岸的概率也大。综合多方因素,建议同学们专转本复习四轮&#…...
微信小程序的优化方案之主包与分包的研究
什么是分包? 某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。 在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的…...
从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。
在开始之前先自学两个工具 商业web自动化测试工具请自学QTP;QTP的学习可以跳过,我是跳过了的。 开源web自动化测试工具请自学Selenium;我当年是先学watir(耗时1周),再学selenium(也耗时1周&…...
【计组笔记03】计算机组成原理之系统五大部件介绍、主存模型和CPU结构介绍
这篇文章,主要介绍计算机组成原理之系统五大部件、主存模型和CPU结构。 目录 一、计算机五大部件 1.1、体系结构 (1)冯诺依曼体系结构...
微信小程序解析用户加密数据
微信公众号 IT果果日记前言在上一篇文章“微信小程序如何获取用户信息”中我们完成了用户明文数据的校验工作,本文将学习解密用户的非明文用户信息,也就是获取用户的openId和unionId。解密调用wx.getUserProfile后将返回encryptedData和iv两个数据。encr…...
毕业四年换了3份软件测试工作,我为何仍焦虑?
今天一看日历:2023.2.11 ,才突然意识到自己毕业已经四年了。四年时间里一直在测试行业摸爬滚打,现在是时候记录一下了。 下面我来分享下我这4年软件测试经验及成长历程,或许能帮助你解决很多工作中的迷惑。 01、我是如何开始做…...
嵌入式C基础知识(7)
是否可以传递任何参数并从 ISR 返回值不可以。不能传递任何参数并从 ISR 返回值。 ISR 不返回任何内容,并且不允许传递任何参数。 当硬件或软件事件发生时调用 ISR,而代码不会调用它。 这就是为什么不向 ISR 传递参数的原因。 由于代码不调用 ISR&#x…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
