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

星际争霸之小霸王之小蜜蜂(七)--消失的子弹

目录

前言

 一、删除子弹

 二、限制子弹数量

 三、继续重构代码

总结


前言

昨天我们已经让子弹飞了起来,但是会面临一个和之前小蜜蜂一样的问题,小蜜蜂的行动应该限制在窗口内,那么子弹也是有相同之处,也需要限制一个移动范围,当超出范围之后,就要将其消灭,释放内存,因为子弹飞出屏幕外不是真的消失,只是不显示而已,依然占用内存空间。

 一、删除子弹

 按照上面的说法,我们只需要判断子弹的位置,如果子弹已经超出窗口就可以删除。这个判断放在哪里合适呢,个人觉得放在刷新窗口前比较合适,在显示窗口内容前判断是否需要删除后,就不用浪费资源了。这样,我们来修改主函数:

import pygame
import settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Groupdef run_game():pygame.init()new_setting=settings.Settings()screen = pygame.display.set_mode((new_setting.screen_width,new_setting.screen_height))ship = Ship(screen,new_setting)pygame.display.set_caption("狂敲代码的橘子")bullets = Group()while True:gf.check_events(new_setting,screen,ship,bullets)ship.update()bullets.update()for bullet in bullets:if bullet.rect.bottom<=0:bullets.remove(bullet)print(len(bullets))gf.update_screen(new_setting,screen,ship,bullets)run_game()

 我们再确定了每个子弹的位置后,添加循环判断代码,之前我们说过,窗口的左上角坐标是(0.0),所以只要子弹的最下边小于0就可以判断该子弹已经出了窗口,因为在游戏的显示中通过肉眼是无法判断子弹飞出窗口后有没有删除,所以增加了 print(len(bullets))来测试,当子弹删除后,bullets的长度会减少,直至为0,经运行,确实达到了想要的目的。

这里还有一个问题,我们写的for循环是for bullet in bullets:,但是“大蟒蛇”上写的是for bullet in bullets.copy():,这两者有什么区别呢?当我们在遍历一个列表的同时对其进行修改(如添加、删除元素),可能会导致程序出错或产生意外的结果。这是因为在遍历过程中,Python会不断地更新列表的长度和元素的索引,从而可能导致索引错误或遗漏某些元素。

而使用bullets.copy()创建了一个副本,遍历的是这个副本,对原列表的修改不会影响到副本,从而避免了上述问题。虽然两种写法都能实现我们想要的目的,但是明显第二种更加严谨、稳妥,第一种也许不知道什么时候就会发生错误。

 二、限制子弹数量

 “大蟒蛇”中认为一般的游戏子弹都有限制,我不记得我玩的游戏子弹有限制,好像都是无限子弹,最多对子弹的发射速度有限制,我们还是按照书上来实践操作。这个功能应该不难实现,只要在创建子弹之前加一个判断,如果存在的子弹小于限制数,就创建一个子弹,并添加到bullets中,如果不是就不做任何操作,这个判断语句代码写在game_functions模块中,但在这之前,要先在settings模块设置一下最大子弹数量属性。

class Settings():def __init__(self):self.screen_width = 800self.screen_height = 600self.bg_color = (220,220,220)self.ship_speed_factor = 0.1self.bullet_speed_factor = 0.3self.bullet_width = 2self.bullet_hight = 5self.bullet_color = 60,60,60self.bullets_allowed = 3
import sys
import pygame
from bullet import Bulletdef check_keydown_events(event,new_setting,screen,ship,bullets):if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:if len(bullets)<new_setting.bullets_allowed:new_bullet = Bullet(new_setting,screen,ship)bullets.add(new_bullet)def check_keyup_events(event,ship):if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(new_setting,screen,ship,bullets):for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type==pygame.KEYDOWN:check_keydown_events(event,new_setting,screen,ship,bullets)elif event.type==pygame.KEYUP:check_keyup_events(event, ship)def update_screen(new_setting,screen,ship,bullets):screen.fill(new_setting.bg_color)for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()pygame.display.flip()

通过修改这两处代码,每次屏幕上最多只有3发子弹

 

 可以看出,我一直在敲击空格键,但是窗口内最多只有3发子弹。

 三、继续重构代码

 现在“大蟒蛇”又觉得主程序内容有点多了,决定将判断删除子弹代码转移到game_functions中,并创建函数update_bullets,这样主函数只要调用update_bullets就行了,update_bullets里代码就是照搬过来的,没什么好说的。因为我们在判断按键是否为空格里又加了判断子弹数量,因此我还需单独写一个函数fire_bullet()来存放判断子弹数量代码,需要时直接调用,使代码块看起来更简洁。

import sys
import pygame
from bullet import Bulletdef check_keydown_events(event,new_setting,screen,ship,bullets):if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(new_setting, screen, ship, bullets)def check_keyup_events(event,ship):if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(new_setting,screen,ship,bullets):for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()elif event.type==pygame.KEYDOWN:check_keydown_events(event,new_setting,screen,ship,bullets)elif event.type==pygame.KEYUP:check_keyup_events(event, ship)def fire_bullet(new_setting,screen,ship,bullets):if len(bullets) < new_setting.bullets_allowed:new_bullet = Bullet(new_setting, screen, ship)bullets.add(new_bullet)def update_bullets(bullets):bullets.update()for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)def update_screen(new_setting,screen,ship,bullets):screen.fill(new_setting.bg_color)for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()pygame.display.flip()

总结

 截至目前,玩家操作部分基本完成,后面我将添加敌对的虫族,以及用子弹消灭他们。

相关文章:

星际争霸之小霸王之小蜜蜂(七)--消失的子弹

目录 前言 一、删除子弹 二、限制子弹数量 三、继续重构代码 总结 前言 昨天我们已经让子弹飞了起来&#xff0c;但是会面临一个和之前小蜜蜂一样的问题&#xff0c;小蜜蜂的行动应该限制在窗口内&#xff0c;那么子弹也是有相同之处&#xff0c;也需要限制一个移动范围&…...

Hadoop入门机安装hadoop

0目录 1.Hadoop入门 2.linux安装hadoop 1.Hadoop入门 定义 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下&#xff0c;开发分布式程序。充分利用集群的威力进行高速运算和存储。 优势 高可靠性&#xff1a;Hadoop底层维护多…...

cookie技术介绍

title: cookie技术 date: 2023-08-27 21:34:19 tags: [cookie, 网络, http] categories: 网络 我们经常说的cookie缓存数据&#xff0c;允许cookie是什么意思? Cookie也被称作Cookies&#xff0c;它是一种让网站的服务器端可以把少量数据存储在客户端的硬盘或内存中&#x…...

网络摄像头:SparkoCam Crack

SparkoCam 网络摄像头软件 SparkoCam 是一款网络摄像头和视频效果软件&#xff0c;用于广播实时网络摄像头效果并将其应用到视频聊天和录音中。 使用佳能/尼康数码单反相机作为常规网络摄像头通过向实时视频聊天和视频录制添加酷炫的网络摄像头效果和图形来增强 USB 网络摄像…...

【缓存设计】记一种不错的缓存设计思路

文章目录 前言场景设计思路小结 前言 之前与同事讨论接口性能问题时听他介绍了一种缓存设计思路&#xff0c;觉得不错&#xff0c;做个记录供以后参考。 场景 假设有个以下格式的接口&#xff1a; GET /api?keys{key1,key2,key3,...}&types{1,2,3,...}其中 keys 是业务…...

微信小程序大学校园二手教材与书籍拍卖系统设计与实现

摘 要 随着应用技术的发展以及电子商务平台的崛起&#xff0c;利用线上平台实现的二手交易为传统的二手交易市场注入了新的生机&#xff0c;大学校园内的新生和应届毕业生的相互交替产生了巨大的二手交易空间&#xff0c;同时考虑到环保和资源再利用&#xff0c;大学校园的书籍…...

涛然自得周刊(第06期):韩版苏东坡的突围

作者&#xff1a;何一涛 日期&#xff1a;2023 年 8 月 27 日 涛然自得周刊主要精选作者阅读过的书影音内容&#xff0c;不定期发布。历史周刊内容可以看这里。 电影 兹山鱼谱 讲述丁若铨因政治事件被贬黜到了遥远的黑山岛。来到岛上后&#xff0c;丁被大自然环境疗愈&#…...

DOCKER 部署 webman项目

# 设置基础镜像 FROM php:8.2-fpm# 安装必要的软件包和依赖项 RUN apt-get update && apt-get install -y \nginx \libzip-dev \libpng-dev \libjpeg-dev \libfreetype6-dev \&& rm -rf /var/lib/apt/lists/*# 安装 PHP 扩展 RUN docker-php-ext-configure gd …...

LLMs:LangChain-Chatchat(一款可实现本地知识库问答应用)的简介、安装、使用方法之详细攻略

LLMs&#xff1a;LangChain-Chatchat(一款可实现本地知识库问答应用)的简介、安装、使用方法之详细攻略 目录 LangChain-Chatchat的简介 1、原理图解 2、文档处理实现流程 1、模型支持 (1)、LLM 模型支持 (2)、Embedding 模型支持 LangChain-Chatchat的安装 1、镜像部署…...

Qt 解析XML文件 QXmlStreamReader

如何使用QXmlStreamReader来解析格式良好的XML&#xff0c;Qt的文档中指出&#xff0c;它是一种更快、更方便的Qt自己的SAX解析器&#xff08;QXmlSimpleReader&#xff09;的替代&#xff0c;它也较快&#xff0c;在某种情况下&#xff0c;比DOM&#xff08;QDomDocument&…...

图像线段检测几种方法

1、方法一 当我将OpenCV提升到4.1.0时&#xff0c;LineSegmentDetector&#xff08;LSD&#xff09;消失了。 OpenCV-contrib有一个名为FastLineDetector的东西&#xff0c;如果它被用作LSD的替代品似乎很好。如果你有点感动&#xff0c;你会得到与LSD几乎相同的结果。 2、方…...

【Vue2.0源码学习】生命周期篇-初始化阶段(initEvents)

文章目录 1. 前言2. 解析事件3. initEvents函数分析4. 总结 1. 前言 本篇文章介绍生命周期初始化阶段所调用的第二个初始化函数——initEvents。从函数名字上来看&#xff0c;这个初始化函数是初始化实例的事件系统。我们知道&#xff0c;在Vue中&#xff0c;当我们在父组件中…...

SQL高级知识点

MySQL基础 1、安装 1)设置编码 2)设置密码 2、配置文件&#xff1a;my.ini、my.cnf 1)设置端口号 port3306 2)设置编码 default-character-setutf8character-set-serverutf8 3)存储引擎 default-storage-engineINNODB 4)最大连接数 max_connections100 注意&…...

【安全】原型链污染 - Code-Breaking 2018 Thejs

目录 准备工作 环境搭建 加载项目 复现 代码审计 payload 总结 准备工作 环境搭建 Nodejs BurpSuite 加载项目 项目链接 ① 下载好了cmd切进去 ② 安装这个项目 可以检查一下 ③运行并监听 可以看到已经在3000端口启动了 复现 代码审计 const fs require(fs) cons…...

【架构】探索计算机处理器的世界:ARM和x86架构解析及指令集

目录 导语ARM架构x86架构AMD公司对比与应用不同架构处理器的指令集结语 导语 计算机处理器是数字化时代的核心引擎&#xff0c;而在众多处理器架构中&#xff0c;ARM和x86是备受关注的三个。本文将带您深入探索这三个架构&#xff0c;介绍它们的特点、公司背景以及应用领域。让…...

SpringBoot权限认证

SpringBoot的安全 常用框架&#xff1a;Shrio,SpringSecurity 两个功能&#xff1a; Authentication 认证Authorization 授权 权限&#xff1a; 功能权限访问权限菜单权限 原来用拦截器、过滤器来做&#xff0c;代码较多。现在用框架。 SpringSecurity 只要引入就可以使…...

OpenGL-入门-BMP像素图glReadPixels

glReadPixels函数用于从帧缓冲区中读取像素数据。它可以用来获取屏幕上特定位置的像素颜色值或者获取一块区域内的像素数据。下面是该函数的基本语法&#xff1a; void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *da…...

同源策略以及SpringBoot的常见跨域配置

先说明一个坑。在跨域的情况下&#xff0c;浏览器针对复杂请求&#xff0c;会发起预检OPTIONS请求。如果服务端对OPTIONS进行拦截&#xff0c;并返回非200的http状态码。浏览器一律提示为cors error。 一、了解跨域 1.1 同源策略 浏览器的同源策略&#xff08;Same-Origin Po…...

基于jeecg-boot的flowable流程跳转功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 今天我…...

react图片预加载

道阻且长&#xff0c;行而不辍&#xff0c;未来可期 图片预加载的原理&#xff1a;new一个image对象&#xff0c;用这个对象加载图片&#xff0c;等这个对象将这个图片请求完后&#xff0c;再将这个图片放入原本应该放置的位置 代码如下&#xff1a; import React, { useEffe…...

OpenClaw对话式编程:Qwen3.5-9B解释代码与生成可执行脚本

OpenClaw对话式编程&#xff1a;Qwen3.5-9B解释代码与生成可执行脚本 1. 为什么需要对话式编程助手&#xff1f; 作为一个经常需要写脚本处理数据的开发者&#xff0c;我发现自己80%的时间都花在重复性工作上&#xff1a;查文档、调试语法错误、验证代码逻辑。直到尝试用Open…...

如何通过自动化工具高效获取阴阳师游戏资源?完整实践指南

如何通过自动化工具高效获取阴阳师游戏资源&#xff1f;完整实践指南 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 阴阳师自动化工具是一款功能强大的智能辅助应用&#xff0c…...

Windows 11下用VSCode+CMake+MinGW编译OpenCV 4.8.0,保姆级避坑指南

Windows 11下用VSCodeCMakeMinGW编译OpenCV 4.8.0全流程实战 最近在Windows 11上配置OpenCV开发环境时&#xff0c;发现很多教程都存在版本过时或Win11特有兼容性问题。本文将分享一套经过验证的最新工具链组合&#xff1a;VSCode 1.85CMake 3.28MinGW-w64 12.2OpenCV 4.8.0。不…...

17:L关注AI伦理:蓝队的道德防御

作者&#xff1a; HOS(安全风信子) 日期&#xff1a; 2026-03-17 主要来源平台&#xff1a; GitHub 摘要&#xff1a; 当基拉开始利用AI的伦理漏洞时&#xff0c;传统的安全防御已无法应对。L将AI伦理原则融入安全防御&#xff0c;构建符合道德规范的安全体系。本文拆解L如何在…...

FigmaCN:5分钟快速实现Figma中文界面的终极解决方案

FigmaCN&#xff1a;5分钟快速实现Figma中文界面的终极解决方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma英文界面而烦恼吗&#xff1f;figmaCN是一款专为中文用户打造…...

终极桌面歌词解决方案:LyricsX 让你的音乐体验全面升级

终极桌面歌词解决方案&#xff1a;LyricsX 让你的音乐体验全面升级 【免费下载链接】Lyrics Swift-based iTunes plug-in to display lyrics on the desktop. 项目地址: https://gitcode.com/gh_mirrors/lyr/Lyrics 在macOS平台上享受音乐时&#xff0c;你是否曾渴望拥有…...

用极空间 NAS 搭专属博客:Typecho 部署全攻略,把创作握在自己手里

前言 作为常年折腾各类私有部署工具的科技爱好者&#xff0c;我一直觉得「真正的创作自由」&#xff0c;藏在自己能掌控的服务器里。试过不少博客程序&#xff0c;要么配置繁琐&#xff0c;要么资源占用高&#xff0c;直到把 Typecho 和极空间 NAS 结合&#xff0c;才找到最舒…...

HunyuanVideo-Foley部署案例:混合精度(FP16/AMP)推理性能实测报告

HunyuanVideo-Foley部署案例&#xff1a;混合精度&#xff08;FP16/AMP&#xff09;推理性能实测报告 1. 测试环境与配置 1.1 硬件配置 显卡&#xff1a;RTX 4090D 24GB显存&#xff08;驱动550.90.07&#xff09;CPU&#xff1a;10核心处理器内存&#xff1a;120GB DDR4存储…...

STM32标准库项目如何用VSCode一键编译下载?详解tasks.json与Makefile的联动配置

STM32标准库项目在VSCode中实现一键编译下载的终极指南 1. 为什么选择VSCode进行STM32开发&#xff1f; 传统嵌入式开发往往依赖于Keil、IAR等商业IDE&#xff0c;但这些工具存在几个明显痛点&#xff1a; 高昂的授权费用&#xff1a;商业IDE的许可证价格让个人开发者和小团队望…...

类和对象(中)——运算符重载

引入语言在语法上可以直接用指令实现运算符对 内置类型 的操作C中加入了类类型&#xff0c;那如何使用以前的运算符&#xff08;如 - * / 等&#xff09;&#xff0c;对类类型进行操作呢&#xff1f;由此引入运算符重载&#xff1a;C为了增强代码的可读性引入了运算…...