最终程序图

程序分析——精灵对象与功能分析

  • 基本精灵对象,继承 pygame.sprite.Sprite

    • 属性:加载图片、设置初始速度

    • 功能:纵向更新速度

程序对象代码

import random
import pygameSCREEN_PRO = pygame.Rect(0, 0, 512, 768)# 自定义派生精灵子类,继承pygame.sprite.Sprite
class GameSprites(pygame.sprite.Sprite):"""游戏精灵基类"""def __init__(self, img_name, speed=1):# 调用父类的初始化方法super().__init__()if img_name is None:return# 加载图像self.image = pygame.image.load(img_name)# 设置尺寸; get_rect()可以获取图像的原始大小self.rect = self.image.get_rect()# 设置速度self.speed = speeddef update(self):# 默认在屏幕上垂直方向移动self.rect.y += self.speed
  • 背景图对象(继承精灵基类)

    • 属性:背景图片、背景音乐

    • 位置:从屏幕0,0 开始绘制(屏幕大小与背景图一样大小)

    • 功能:更新图片纵向移动,当移出屏幕后重置到屏幕上方(需要两张背景图,不断交替纵向下移动,表现出飞机不停飞的现象)

程序对象代码

class BackGround(GameSprites):"""背景精灵"""# 初始化背景图片def __init__(self, is_alternate=False):super().__init__("./img/bg2.jpg")# 加载背景音乐pygame.mixer.music.load("./music/bg.mp3")# 设置音量pygame.mixer.music.set_volume(0.1)# 设置播放次数, -1 表示无限循环pygame.mixer.music.play(-1)# 如果是交替图,初始位置则在屏幕上方if is_alternate:self.rect.bottom = SCREEN_PRO.ydef update(self):# 调用父类更新super().update()# 当图片移出屏幕外时,将图片设置到屏幕上方if self.rect.top >= SCREEN_PRO.height:self.rect.bottom = SCREEN_PRO.y
  • 英雄战机对象

    • 英雄图片

    • x轴在屏幕中间,y轴距离屏幕底部200个像素

    • 横向移动,不能移出屏幕。发射子弹,发射子弹音乐

程序对象代码

class Hero(GameSprites):"""英雄战机精灵"""def __init__(self):super().__init__("./img/hero.png")# 初始化英雄的位置self.rect.centerx = SCREEN_PRO.centerxself.rect.y = SCREEN_PRO.height - 200def update(self, speed=1):self.rect.x += speed# 控制边界if self.rect.left <= 0:self.rect.left = 0elif self.rect.right >= SCREEN_PRO.right:self.rect.right = SCREEN_PRO.rightdef fire(self, bulletGroup):# 英雄发射子弹for i in range(1, 2):bullet = Bullet(-2)bullet.rect.centerx = self.rect.centerxbullet.rect.y = self.rect.top - 30 * ibulletGroup.add(bullet)# 播放子弹音乐bullet.bulletMusic.play()
  • 两种类型的敌机对象

    • 一群普通敌机

      • 属性:敌机图片

      • 位置:从屏幕上方纵向移动到屏幕中

      • 功能:从上往下,纵向移动。移动屏幕后,销毁敌机对象

    • 一群雷霆敌机

      • 功能同上,敌机图片不同

程序对象代码

class EnemyPlane(GameSprites):"""敌机精灵"""def __init__(self):# 初始化敌机图像super().__init__("./img/enemy1.png")# 初始化 敌机随机速度self.speed = random.randint(2, 4)# 初始化 敌机随机位置,x轴的 最小位置是0,最大位置是屏幕宽度-敌机宽度maxSpeed = SCREEN_PRO.width - self.rect.widthself.rect.bottom = SCREEN_PRO.yself.rect.x = random.randint(0, maxSpeed)# 初始化爆炸图片self.boomImg = pygame.image.load("./img/boom.png")# 初始化敌机销毁音乐self.boomMusic = pygame.mixer.Sound("./music/boom.mp3")self.boomMusic.set_volume(0.3)def update(self):# 调用父类更新敌机速度super().update()# 如果敌机飞出屏幕需要从精灵组中删除if self.rect.top >= SCREEN_PRO.height:# kill 方法可以让精灵从所有精灵组中移除,精灵会自动销毁(会默认调用 __del__ 方法)self.kill()def plan_die(self):# 播放音乐self.boomMusic.play()class EnemyPlane2(GameSprites):"""敌机精灵2-雷霆敌机"""def __init__(self):# 初始化敌机图像super().__init__("./img/enemy2.png")# 初始化 敌机随机速度self.speed = random.randint(2, 4)# 初始化 敌机随机位置,x轴的 最小位置是0,最大位置是屏幕宽度-敌机宽度maxSpeed = SCREEN_PRO.width - self.rect.widthself.rect.bottom = SCREEN_PRO.yself.rect.x = random.randint(0, maxSpeed)# 初始化爆炸图片self.boomImg = pygame.image.load("./img/boom.png")# 初始化敌机销毁音乐self.boomMusic = pygame.mixer.Sound("./music/boom.mp3")self.boomMusic.set_volume(0.3)def update(self):# 调用父类更新敌机速度super().update()# 如果敌机飞出屏幕需要从精灵组中删除if self.rect.top >= SCREEN_PRO.height:# kill 方法可以让精灵从所有精灵组中移除,精灵会自动销毁(会默认调用 __del__ 方法)self.kill()def plan_die(self):# 播放音乐self.boomMusic.play()
  • 子弹图对象

    • 属性:子弹图片

    • 位置:在英雄敌机的正上方

    • 功能:子弹纵向移动,从下往上。移出屏幕后,子弹对象销毁

程序对象代码

class Bullet(GameSprites):"""子弹精灵"""def __init__(self, speed):super().__init__("./img/bullet.png", speed)# 初始子弹发出音乐self.bulletMusic = pygame.mixer.Sound("./music/bullet2.wav")self.bulletMusic.set_volume(0.2)def update(self):super().update()# 子弹超出屏幕就销毁if self.rect.bottom <= 0:self.kill()
  • 计分器对象

    • 属性:计分器文字对象

    • 位置:初始位置在屏幕左上角,游戏结束时,在结束图片的中间

    • 功能:子弹销毁一个敌机,分值+1

程序对象代码

class FontSprites(GameSprites):"""字体精灵"""def __init__(self, size=18):super().__init__(None)self.font = pygame.font.Font("./font/msyh.ttf", size)# 初始分值self.fontValue = 0self.textShow = self.font.render("分值:%d" % self.fontValue, True, (0, 255, 0))def update(self, color=(0, 255, 0)):# 第一个参数是写的文字;第二个参数是个布尔值,以为这是否开启抗锯齿,就是说True的话字体会比较平滑,不过相应的速度有一点点影响;# 第三个参数是字体的颜色;第四个是背景色,如果你想没有背景色(也就是透明),那么可以不加这第四个参数。self.textShow = self.font.render("分值:%d" % self.fontValue, True, color)

程序所需材料与监听事件

材料

  • 背景音乐材料

  • 子弹发出音乐材料

  • 敌机爆炸音乐材料

  • 敌机爆炸图片材料

  • 游戏结束图片材料、

  • 游戏重新开始图片材料

监听事件

  • 点击关闭窗口程序退出事件

  • 敌机随机出现事件

  • 鼠标点击重新开始游戏事件

  • 子弹发出事件

程序分析——主方法分析

  • 初始化

    • 初始化pygame模块

    • 初始化英雄生命

    • 初始化开始菜单图片位置

    • 初始化游戏窗口

    • 初始化游戏时钟

    • 初始化爆炸敌机对象

    • 初始化各个精灵及精灵组对象

    • 初始化 创建敌机定时器(每700毫秒创建一架敌机)

    • 初始化 创建子弹定时器 (每500毫秒创建一颗子弹)

  • 游戏循环

    • 检测如果敌机爆炸了,让爆炸效果最多持续1秒

    • 设置刷新频率,每秒刷新60次

    • 监听事件

      • 监听鼠标点击关闭窗口退出游戏事件

      • 监听创建敌机事件

      • 监听发射子弹事件

      • 监听鼠标点击重新开始游戏事件

      • 监听键盘按住向左或向右移动英雄战机事件

    • 判断英雄战机,如果死亡则不再向下更新,直到点击重新开始,或者关闭游戏

    • 碰撞检测

      • 检测子弹精灵组与敌机精灵组碰撞,一旦有碰撞,则相应的敌机与子弹都销毁,并播放敌机爆炸声音,加载爆炸图片、分值加+1

      • 检测英雄战机与敌机精灵组碰撞,一旦有碰撞,英雄战机阵亡,游戏结束,弹出游戏结束界面。停止全部音乐,加载最终分值

    • 更新精灵组

      • 更新与绘制背景图

      • 更新与绘制敌机精灵组,如果有爆炸的敌机,需要绘制爆炸图

      • 绘制英雄战机

      • 更新与绘制子弹

      • 绘制分值

      • 如果英雄战机销毁,则调用结束方法

    • 更新屏幕显示

程序代码

from plane_sprites import *
# 设置游戏时钟(刷新频率)
TICK_TIMES = 60# 设置敌机事件、创建敌机所需时间
EVENT_ENEMY=pygame.USEREVENT
CREATE_ENEMY_TIME=700# 设置子弹事件、创建子弹所需时间
EVENT_BULLET=pygame.USEREVENT+1
CREATE_BULLET_TIME=500# 总分值
TOTAL_SCORE=0class PlaneGame:"""飞机大战主类"""def __init__(self):# 初始化pygame模块pygame.init()# 初始化英雄生命self.life=True# 初始化开始菜单图片位置self.startImgRect=pygame.Rect(0,0,0,0)# 初始化游戏窗口self.screen = pygame.display.set_mode(SCREEN_PRO.size)# 初始化游戏时钟self.clock = pygame.time.Clock()# 初始化爆炸敌机对象self.boomEnemy= {"boomEnemy":None,"times":0}# 初始化精灵及精灵组相关self.__create_sprites()# 初始化 创建敌机定时器pygame.time.set_timer(EVENT_ENEMY,CREATE_ENEMY_TIME)# 初始化 创建子弹定时器pygame.time.set_timer(EVENT_BULLET,CREATE_BULLET_TIME)def __create_sprites(self):# 创建背景精灵bg1 = BackGround()bg2 = BackGround(True)# 创建精灵组,并放入背景精灵self.bgGroup = pygame.sprite.Group(bg1, bg2)# 创建敌机精灵组self.enemyGroup=pygame.sprite.Group()# 创建英雄战机self.hero=Hero()self.heroGroup=pygame.sprite.Group(self.hero)# 创建子弹精灵组self.bulletGroup=pygame.sprite.Group()# 创建分值self.font=FontSprites()self.fontGroup=pygame.sprite.Group(self.font)def start_game(self):# 游戏循环开始while True:# 爆炸图片持续1秒self.__enemy_boom()# 设置刷新频率self.clock.tick(TICK_TIMES)# 监听事件self.__event_handler()if not self.life:continue# 碰撞检测self.__check_collide()# 更新精灵组self.__update_group()# 更新屏幕pygame.display.update()def __enemy_boom(self):# 爆炸图片持续1秒if self.boomEnemy["boomEnemy"] is not None:enemyTimes = self.boomEnemy["times"]self.boomEnemy["times"] = enemyTimes + 1if enemyTimes > TICK_TIMES:self.boomEnemy["boomEnemy"] = Noneself.boomEnemy["times"] = 0def __event_handler(self):global TOTAL_SCOREfor event in pygame.event.get():# 判断退出游戏if event.type==pygame.QUIT:PlaneGame.game_over()# 监听鼠标点击开始游戏if event.type == pygame.MOUSEBUTTONDOWN:x, y = event.posprint("鼠标点击了...x:%d ,y:%d,原始图片位置,x:%d,y:%d"%(x,y,self.startImgRect.x,self.startImgRect.y))if self.startImgRect.collidepoint(x, y):self.life = TrueTOTAL_SCORE=0pygame.quit()PlaneGame().start_game()# 监听英雄死亡if not self.life:continue# 监听到创建敌机if event.type==EVENT_ENEMY:enemy=EnemyPlane()enemy2 = EnemyPlane2()self.enemyGroup.add(enemy)self.enemyGroup.add(enemy2)# 监听子弹if event.type == EVENT_BULLET:self.hero.fire(self.bulletGroup)keyPressed=pygame.key.get_pressed()if keyPressed[pygame.K_RIGHT]:self.hero.update(3)if keyPressed[pygame.K_LEFT]:self.hero.update(-3)def __update_group(self):# 绘制背景self.bgGroup.update()self.bgGroup.draw(self.screen)# 绘制敌机self.enemyGroup.update()self.enemyGroup.draw(self.screen)boomEnemy=self.boomEnemy["boomEnemy"]if boomEnemy:# 绘制爆炸图片self.screen.blit(boomEnemy.boomImg,(boomEnemy.rect.x,boomEnemy.rect.y))# 绘制英雄self.heroGroup.draw(self.screen)# 绘制子弹self.bulletGroup.update()self.bulletGroup.draw(self.screen)# 绘制分值self.fontGroup.update()self.screen.blit(self.font.textShow,(0,0))# 更新游戏结束if not self.life:self.load_game_over()def __check_collide(self):global TOTAL_SCORE# 子弹碰撞敌机,都销毁dictG=pygame.sprite.groupcollide(self.bulletGroup,self.enemyGroup,True,True)if dictG:self.font.kill()# 分值加1TOTAL_SCORE += 1self.font=FontSprites()self.font.fontValue=TOTAL_SCOREself.fontGroup.add(self.font)# 爆炸敌机对象enemy=list(dictG.values())[0][0]# 将爆炸的敌机记录self.boomEnemy["boomEnemy"]=enemy# 播放音乐enemy.plan_die()# # 敌机碰撞英雄战机,都销毁spriteList=pygame.sprite.spritecollide(self.hero,self.enemyGroup,True)# 碰撞的敌机列表if len(spriteList)>0:# self.hero.kill()self.life=Falseself.load_game_over()def load_game_over(self):# 背景音乐停止pygame.mixer.music.stop()# 停止全部音效pygame.mixer.stop()# 加载游戏结束img = pygame.image.load("./img/gameover1.png")self.screen.blit(img, (0, 30))# 加载开始菜单startImg = pygame.image.load("./img/restart.png")self.startImgRect=self.screen.blit(startImg, (150,img.get_rect().height+30))# 加载文字gameOverFont=FontSprites(40)gameOverFont.fontValue=TOTAL_SCOREgameOverFont.update((255,0,0))self.screen.blit(gameOverFont.textShow,(200,250))@staticmethoddef game_over():print("游戏结束!!!!")# 游戏退出pygame.quit()exit()if __name__ == '__main__':planGame = PlaneGame()planGame.start_game()

程序猿与投资生活实录已改名为  程序猿知秋,WX同款,欢迎关注!

Python —— 给女儿写个雷霆战机相关推荐

  1. python 0基础如何做出雷霆战机?【源码送上】

    嗨害大家好鸭!我是小熊猫~ 大家都玩过雷霆战机吧? 这样的 我的qun友 才学三周就做出了雷霆战机这种游戏, 看起来确实不错啊~ 今天就实现一下雷霆战机的运作,开始整活! 一.准备工作 使用的软件版本 ...

  2. python写出雷霆战机_利用Python自制雷霆战机小游戏,娱乐编程,快乐学习!

    开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块. 环境搭建 安装Python并添加到环境变量,pip安装需要的相关模块即可. 先睹为快 在cmd ...

  3. python写出雷霆战机_仿《雷霆战机》飞行射击手游开发--游戏的入口

    游戏的入口AppDelegate 游戏启动后,首先实例化的是AppDelegate这个类,这这个类里,我们需要修改两个函数:applicationDidFinishLaunching和applicat ...

  4. 基于JavaSwing写的雷霆战机(飞机大战)

    自学Java已经有一段时间了吧,一直都没有一个关于界面的完整的项目,计算器这些又太简单,所以就一直构思写一个基于JavaSwing的游戏.虽然在日常开发中使用到JavaSwing开发界面的很少.但是这 ...

  5. 当我给表弟用python写了个雷霆战机后

    雷霆战机大家都玩过吧,就这种的 才读小学的表弟,一到周末就打扰我上分,别人都是三年高考五年模拟,那我不一样,我直接给他写了个游戏自己到一边玩去,总不能教他爬虫吧,小小年纪不合适~ 一.准备工作 使用的 ...

  6. python及pygame雷霆战机游戏项目实战03 碰撞检测

    在这个系列中,将制作一个雷霆战机游戏. 碰撞 碰撞是游戏开发的基本部分. 碰撞检测意味着您要检测游戏世界中的一个对象是否正在触碰另一个对象. 碰撞反应决定了碰撞发生时你想要做什么 - 马里奥拿起硬币, ...

  7. python及pygame雷霆战机游戏项目实战01 控制飞机

    入门 在这个系列中,将制作一个雷霆战机游戏. 首先,将游戏设置修改一下: WIDTH = 480 HEIGHT = 600 FPS = 60 玩家精灵 要添加的第一件事是代表玩家的精灵.最终,这将是一 ...

  8. python及pygame雷霆战机游戏项目实战05 改进的碰撞

    项目详细介绍 项目详细介绍 在这个系列中,将制作一个雷霆战机游戏. 碰撞发生了什么? Pygame中的默认碰撞类型是使用collide_rect()函数,该函数使用两个精灵的rect属性来计算它们是否 ...

  9. JavaSwing多线程小游戏雷霆战机

    在做完连连看以后,想到要做一个多线程游戏,本来是做的一个跳伞的小游戏的.但是做到一半的时候,觉得可玩性太低了.后面想来想去还是打算做一个以前玩过的雷霆战机小游戏,也就是飞机大战. 1.效果展示 2.绘 ...

最新文章

  1. 科普:Flume是啥?干嘛用的?
  2. MYSQL 开启root远程登录权限
  3. HADOOP学习笔记(一):HDFS
  4. Python中的彩蛋
  5. 不要在循环,条件或嵌套函数中调用 Hook
  6. Apache 分割日志
  7. Mediator(中介者)
  8. 微星刀锋 无法进入bios_所有键都无法进入bios,微星主板无法进入bios-
  9. 一个基于jquery的周日历,简单易懂
  10. 古今安全帽头盔大PK,古人安全意识不比今人差
  11. 迅雷跃居全球BT市场第一
  12. ubuntu20安装gcc_Ubuntu:软件常用安装方法(附WPS安装)
  13. 200套工作室设计行业响应式Html5模板HTML5+CSS3设计网站模板简洁设计师作品展示响应式模板整洁扁平宽屏CSS3网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机se
  14. 打开计算机界面怎么没桌面图标,电脑桌面图标都没了?详解如何轻松恢复桌面图标...
  15. 架构解读:如何快速搭建直播答题方案
  16. 经典象棋残局——太白醉写标准解法
  17. 闲看花开花落,云卷云舒
  18. 菜鸟小万的每天一道ccf题Day22(202104-01灰度直方图)
  19. 从键盘输入三条边,先判断能否构成三角形,如果能,计算三角形的面积,否则输出不能构成三角形
  20. 在linux ubuntu下下载运行虚幻5引擎

热门文章

  1. 实习招聘 | 后摩智能解决方案算法实习生
  2. 【面筋烧烤手册】JavaScript原型专题
  3. 安装linux系统键盘布局,fedora键盘键位布局layout
  4. 实现一个通用的函数柯里化的函数
  5. 连续信号(三) | 周期信号的频谱分析 | 傅里叶级数展开式 + 频谱特性
  6. 【笔记】行测——语句表达总结与归纳
  7. SAP中采购销售业务流程及记账会计分录
  8. 探索C#之微型MapReduce
  9. 多车间该如何实施mes系统?
  10. 微信公众号申请服务器,微信公众号服务器接口验证示例