GitHub |
您所在的位置:网站首页 › 飞机爆炸的新闻怎么写好 › GitHub |
PlaneGame
飞机大战游戏Airplane war game
https://blog.csdn.net/i6223671/article/details/99344046
python项目_飞机大战(爆炸效果,血条,音效,buff加成,boss,菜单,完整详细注释的源码)
python3.7环境下
pip -r requirements.txt安装依赖
运行main
@[TOC] 一. 总体概览话不多说,先看效果图,动作是有声音的,但是放不出来
(简单重复性工作可让细节更加到位,代码看明白后可以自行添加,这是个无底洞,提供个思路) 增加历史最高分,建立变量每局更新 增加个人中心,记录分数变化 增加敌机,boss,改变子弹发射方式 添加更多buff,增添更多特效 增加关卡 让敌机,buff出现的时机,数量,等级,随游戏的推进而动态变化,更加人性化 ... 二,技术框架主要就是python类和pygame模块的运用,有项目文件后直接安装pygame库就可以运行了 核心技术概述 1.游戏的初始化和退出 要使用 pygame 提供的所有功能之前,需要调用 init 方法 在游戏结束前需要调用一下 quit 方法 方法 说明 pygame.init() 导入并初始化所有 pygame 模块,使用其他模块之前,必须先调用 init 方法 pygame.quit() 卸载所有 pygame 模块,在游戏结束之前调用!pygame.init()==这个模块初始化一定不能省略== 游戏代码... pygame.quit() 2 理解游戏中的坐标系坐标系 原点 在 左上角 (0, 0) x 轴 水平方向向 右,逐渐增加 y 轴 垂直方向向 下,逐渐增加在游戏中,所有可见的元素 都是以 矩形区域 来描述位置的 要描述一个矩形区域有四个要素:(x, y) (width, height) pygame 专门提供了一个类 pygame.Rect 用于描述 矩形区域 Rect(x, y, width, height) -> Rectset_mode 方法 set_mode(resolution=(0,0), flags=0, depth=0) -> Surface 4. 理解 图像 并实现图像绘制 在游戏中,能够看到的 游戏元素 大多都是 图像 图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存 要在屏幕上 看到某一个图像的内容,需要按照三个步骤: 使用 pygame.image.load() 加载图像的数据 使用 游戏屏幕 对象,调用 blit 方法 将图像绘制到指定位置 调用 pygame.display.update() 方法更新整个屏幕的显示跟 电影 的原理类似,游戏中的动画效果,本质上是 快速 的在屏幕上绘制 图像 电影是将多张 静止的电影胶片 连续、快速的播放,产生连贯的视觉效果!一般在电脑上 每秒绘制 60 次,就能够达到非常 连续 高品质 的动画效果 每次绘制的结果被称为 帧 Frame游戏循环的开始 就意味着 游戏的正式开始 游戏循环的作用 保证游戏 不会直接退出 变化图像位置 —— 动画效果 每隔 1 / 60 秒 移动一下所有图像的位置 调用 pygame.display.update() 更新屏幕显示 检测用户交互 —— 按键、鼠标等...只有 捕获 到用户具体的操作,才能有针对性的做出响应 代码实现 pygame 中通过 pygame.event.get() 可以获得 用户当前所做动作 的 事件列表 用户可以同一时间做很多事情 提示:这段代码非常的固定,几乎所有的 pygame 游戏都 大同小异! # 游戏循环 while True: # 设置屏幕刷新帧率 clock.tick(60) # 事件监听 for event in pygame.event.get(): # 判断用户是否点击了关闭按钮 if event.type == pygame.QUIT: print("退出游戏...") pygame.quit() # 直接退出系统 exit() 7. 理解 精灵 和 精灵组 精灵 和 精灵 为了简化开发步骤,pygame 提供了两个类 pygame.sprite.Sprite —— 存储 图像数据 image 和 位置 rect 的 对象 pygame.sprite.Group在游戏开发中,通常把 显示图像的对象 叫做精灵 Sprite 精灵 需要 有 两个重要的属性 image 要显示的图像 rect 图像要显示在屏幕的位置默认的 update() 方法什么事情也没做 子类可以重写此方法,在每次刷新屏幕时,更新精灵位置注意:pygame.sprite.Sprite 并没有提供 image 和 rect 两个属性 需要程序员从 pygame.sprite.Sprite 派生子类 并在 子类 的 初始化方法 中,设置 image 和 rect 属性 精灵组 一个 精灵组 可以包含多个 精灵 对象 调用 精灵组 对象的 update() 方法 可以 自动 调用 组内每一个精灵 的 update() 方法 调用 精灵组 对象的 draw(屏幕对象) 方法 可以将 组内每一个精灵 的 image 绘制在 rect 位置 整体框架
因为子弹组是敌军对象的成员,子弹不是 就是在主函数需要敌军的子弹再加到一个组,而且所有敌军的子弹加到一起更更新更加方便,这样不用担心敌机毁掉了,他们的子弹对象也访问不了了. 2.子弹和敌机多次撞击由于播放爆炸动画采用的方法是被撞毁时,先不移除精灵组,然后更改该对象图片,知道图片轮完了才kill(),这就导致进行下一次循环,对象还没kill(),kill()了就不能进行轮播. 思考一: 撞毁的时候新建循环把爆炸图片画在屏幕上, 行不通,第循环一次只能更新一帧图片,如果你要更新多帧那么其他精灵就会静止. 思考二: 撞毁时候,先移除精灵组,然后用变量储存,进行最初更新的方法.实验证明可行. 3.进行了update却不显示混淆draw和display.update 首先一个精灵的update方法让图像有改变 精灵组的draw方法调用screen的blit方法画到屏幕上 这时候屏幕画面残留在上一帧 只有display更新了才能看到 4. 想方设法把一个Sprite或者rect或者image进行清除操作其实pygam你们只有贴上去,没有"撕下来" 想要看不见他,两种方法如果是精灵,skill()从所有精灵组里面删除,如果只是单纯的image和rect,直接从他们的list里面remove,这样就不会被blit,实际上屏幕在更新,如果你想要看到,就要画在在更新的每一帧上面,之后如果不再用到它,python自己会进行回收. 同样的道理,如果希望一个坏人消失,最好的办法不是你去杀死他,而是从你所在的集体里面孤立排除他,这样你就再也见不到他了 5. 为什么英雄死掉了,还是会发生碰撞检测这是因为,虽然我们把英雄加入英雄队伍,但是队伍中英雄很少,为了方便我们碰撞的时候不是从队伍中取直接就用该英雄对象进行检测,这时候,英雄skill()了,但是rect并没有丢失, 记住skill(),只是把他从需要显示或者操作群体中把他删除了,但是这个对象并没有被立即回收,它的rect还是在,还能用于碰撞检测 6, 如何按键不放,移动不止方向键监听有两种方式 按一下 elif event.type ==pygame.KEYDOWN and event.key = = pygame.K_RIGHT:按下 返回所有按键的元组,如果某个键被按下,对应的值会是1 keys_pressed = pygame.key.get_pressed() #判断是否按下了方向键 if keys_pressed[pygame.K_RIGHT]: 7,不知道全局变量如何使用python里面的全局常量和其他语言一样是没有歧义的,但是全局变量就不一样了,因为python定义变量不用定义类型,只有在赋值的时候才知道,所以在函数里面使用全局变量,无法保证两个变量是一样的,所以在函数里面需要用global声明一下这个变量是我开始设的这个全局变量,不是又重新定义了一个局部变量, 同样的道理,全局变量也不能跨模块调用,即使import了也只能用他的初始值,所以可以建立一个全局变量操作类,用来获取和修改全局变量. 8.明明画在屏幕上也更新了可就是看不到注意更新的顺序影响图像的上下层关系 三,源代码 注释超级详细 方法比较简单,很容易看懂 易修改,易扩展,可定制化参数 import random import pygame pygame.init() # ************************************************************** # FileName: plane_sprites.py*************************************** # Author: Junieson ********************************************* # Version: 2019.8.12 ****************************************** # **************************************************************** # 分数 SCORE = 0 # 屏幕大小的常量 SCREEN_RECT = pygame.Rect(0, 0, 480, 700) # color color_blue = (30, 144, 255) color_green = (0, 255, 0) color_red = (255, 0, 0) color_purple = (148, 0, 211) color_gray = (251, 255, 242) # 刷新的帧率 FRAME_PER_SEC = 60 # 刷新率是60hz,即每秒update60次 # 创建敌机的定时器常量,自定义用户事件,其实就是int数,不同数表示不同事件 CREATE_ENEMY_EVENT = pygame.USEREVENT # 英雄发射子弹事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1 # buff1 出现的事件 BUFF1_SHOW_UP = pygame.USEREVENT + 2 # buff2 BUFF2_SHOW_UP = pygame.USEREVENT + 3 # 敌军发射子弹 ENEMY_FIRE_EVENT = pygame.USEREVENT + 4 # 发射炸弹 BOMB_THROW = pygame.USEREVENT + 5 class GameScore(object): global SCORE def __init__(self): self.score = 0 pass def getvalue(self): self.score = SCORE return self.score class GameSprite(pygame.sprite.Sprite): """飞机大战游戏精灵""" def __init__(self, image_name, speedy=1, speedx=0): # 调用父类的初始化方法 super().__init__() # 定义对象的属性 self.image = pygame.image.load(image_name) self.rect = self.image.get_rect() self.speedy = speedy self.speedx = speedx self.injury = 1 self.index = 0 # 记帧数变量 self.bar = bloodline(color_blue, self.rect.x, self.rect.y - 10, self.rect.width) def update(self): # 在屏幕的垂直方向上移动 self.rect.y += self.speedy self.rect.x += self.speedx self.bar.x = self.rect.x self.bar.y = self.rect.y - 10 class Background(GameSprite): """游戏背景精灵""" def __init__(self, is_alt=False): # 1. 调用父类方法实现精灵的创建(image/rect/speed) super().__init__("./images/background.png") # 2. 判断是否是交替图像,如果是,需要设置初始位置 if is_alt: self.rect.y = -self.rect.height def update(self): # 1. 调用父类的方法实现 super().update() # 2. 判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方 if self.rect.y >= SCREEN_RECT.height: self.rect.y = -self.rect.height class Boss(GameSprite): def __init__(self): super().__init__("./images/enemy3_n1.png", 0, 1) self.music_boom = pygame.mixer.Sound("./music/enemy3_down.wav") self.music_fly = pygame.mixer.Sound("./music/enemy3_flying.wav") self.music_fly.play(-1) self.rect.centerx = 240 self.y = 200 self.isboom = False self.number = 3 self.index1 = 1 # 控制动画速度 self.index2 = 0 self.index3 = 0 self.index4 = 0 self.injury = 1 self.bar = bloodline(color_purple, 0, 0, 480, 8, 200) self.bullets = pygame.sprite.Group() def fire(self): for j in range(2, 7): # 每层5个 bullet = Bullet(0, 1) bullet.injury = 1 # 2. 设置精灵的位置 bullet.rect.centerx = self.rect.centerx bullet.rect.y = self.rect.bottom if j == 2: bullet.speedx = 0 else: bullet.speedx = (-1) ** j * ((j - 1) // 2) * 1 self.bullets.add(bullet) def update(self): # 左右移 global SCORE if self.index4 % 2 == 0: # 降低帧速率,注意这两个指针不能一样 # 内部为左右移动大概50像素 if self.index3 % 50 == 0 and (self.index3 // 50) % 2 == 1: self.speedx = -self.speedx self.rect.x += self.speedx self.index3 += 1 self.index4 += 1 # 发电动画 self.image = pygame.image.load("./images/enemy3_n" + str((self.index1 // 6) % 2 + 1) + ".png") self.index1 += 1 # 爆炸动画 if self.isboom: self.bar.length -= self.injury * self.bar.weight if self.bar.length |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |