python | 您所在的位置:网站首页 › 1943游戏飞机属性 › python |
文章目录
一、pygame模块1、安装:2、使用pygame创建图形窗口(1)新建项目`飞机大战`(2)新建文件`pygame.py`(3)建立游戏窗口:①pygame的初始化和退出②pygame的坐标系③创建游戏主窗口pygame.display④导入游戏背景图片⑤把一些精致的图像绘制到游戏窗口中
3、游戏循环①动画效果——游戏时钟②动画的简单实现③在游戏循环中监听事件④精灵sprite.Sprite和精灵组sprite.Group⑤派生精灵子类⑥使用 游戏精灵 和 精灵组 创建敌机
4、游戏框架搭建(1)明确主程序职责(2)实现飞机大战主游戏类常量
(3)游戏背景①背景交替滚动的思路②在plane_main.py中显示背景精灵③简化背景精灵的创建
(4)敌机①使用定时器添加敌机②设计Enemy类③创建敌机④ 随机 敌机位置和速度导入模块时,建议按照以下顺序导入
⑤移出屏幕销毁敌机
(5)英雄飞机(6)子弹需求①绘制英雄②移动英雄位置③控制英雄的移动边界④发射子弹⑤定义子弹类⑥发射子弹⑦一次发射三枚子弹⑧碰撞检测
五、游戏设计完成,运行图片附录一:plane_main.py附录二:plane_sprites.py附录三:飞机大战设计图片
一、pygame模块
pygame模块,转为电子游戏设计 1、安装:$ sudo pip3 install pygame windows:pip install pygame 2、使用pygame创建图形窗口 (1)新建项目飞机大战 (2)新建文件pygame.py (3)建立游戏窗口: ①pygame的初始化和退出pygame.init():导入并初始化所有pygame模块,使用其他模块之前,必须先调用init方法。 pygame.quit():卸载所有pygame模块,在游戏结束之前调用。 代码框架: import pygame pygame.init() print("游戏的代码") pygame.quit() ②pygame的坐标系原点在左上角(0, 0) x轴水平方向向右,逐渐增加 y轴垂直方向向下,逐渐增加 在游戏中,所有可见的元素都是以 矩形区域来描述位置的。四要素(x, y)(width, height)。(x, y) 指定矩形的左上角位置,(width, height) 指定矩形区域的大小。 pygame专门提供了一个类pygame.Rect用于描述矩形区域,【其中,size表示(width, height)】: Rect(x, y, width, height) import pygame hero_rect = pygame.Rect(100, 500, 120, 125) print("hero的原点%d %d" % (hero_rect.x, hero_rect.y)) print("hero的尺寸%d %d" % (hero_rect.width, hero_rect.height)) print("hero的size%d %d" % hero_rect.size )输出: ③创建游戏主窗口pygame.displaypygame.diaplay.set_mode():初始化游戏显示窗口 set_mode方法: det_mode(resolution = (0, 0), flags = 0, depth = 0) 参数:(因为每个参数都有=,也就是都有默认值,因此调用时不需要指定值) resolution:指定屏幕的 宽、高,默认创建的窗口大小和屏幕大小一致 flags:参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递 depth:参数表示颜色的位数,默认自动匹配 返回值: 暂时可以理解为游戏的屏幕,游戏的元素都需要被绘制到游戏的屏幕上。 例如:指定screen接收返回值。 screen = pygame.display.set_mode((480, 700))。 pygame.display.update():刷新屏幕内容显示,稍后使用 ④导入游戏背景图片1、将图片加载到内存中。pygame.image.load()加载图像的数据 注:(./images/1.jpg)其中的.表示当前目录 bg = pygame.image.load("D:/My life/music/some photos/sunrise.jpg") 2、使用 游戏屏幕对象,调用bilt(图像,位置)方法将图像绘制到指定位置 screen.blit(bg, (0, 0)) # (0, 0)表示从屏幕左上角开始绘制 3、调用pygame.display.update()方法更新整个屏幕的显示。 注:如果想在屏幕上看到绘制的结果,一定要调用这个方法 pygame.display.update() 运行结果: ⑤把一些精致的图像绘制到游戏窗口中1、加载hero_plane图像 png格式是支持透明的。在绘制图像时,透明区域不会显示任何内容。如果下方有内容,会透过透明区域显示出来 hero = pygame.image.load("D:/My life/music/some photos/plane.png") 2、将其绘制在屏幕的(150, 500)位置 screen.blit(hero, (150, 500)) 3、调用屏幕更新显示飞机图像 pygame.diaplay.update() 输出: 注:screen.blit方法可以在屏幕上绘制很多图像,这些图像之间可能会彼此重叠。编程时可以在screen对象完成所有bilt之后,统一执行一次 display.update()。而不是每执行一步update一次,可以减少程序的繁琐。 3、游戏循环将while True:称为游戏循环(无限循环、死循环)。进入游戏循环,意味着游戏正式开始。 设置刷新频率 检测用户交互 更新所有图像位置 更新屏幕显示 ①动画效果——游戏时钟根据 用户的交互 或者其他情况,快速移动 这些图像,产生动画效果。一般在电脑上 每绘制60次,就能够达到非常 连续 高品质的效果。每次绘制的结果被称为 帧Frame。 pygame专门提供了一个类pygame.time.Clock可以非常方便地设置屏幕绘制速度。 1、在游戏初始化 创建一个时钟对象 2、在游戏循环中让时钟对象调用tick(频率)方法。 如:clock.tick(20)表示每秒20次 tick方法会根据上次被调用的时间,自动设置 游戏循环中的延时。 代码示例: i = 0 while True: clock.tick(60) print(i) ②动画的简单实现每次调用update()之前,需要把所有的游戏图像都重新绘制一遍,而且 最先 重新绘制 背景图像 clock = pygame.time.Clock() plane_rect = pygame.Rect(250, 500, 107, 113) # 107和113表示所插入的飞机图片的宽度和高度 #死循环,确保上方执行的游戏界面不会退出 while True: # 1、指定循环体内部代码执行的频率 clock.tick(60) # 2、修改飞机的位置 plane_rect.y -= 1 # 如果移出顶部,就从底部重新开始移动 if plane_rect.y = 屏幕的高度说明已经移动到屏幕下方。 4、当移动到屏幕下方的这张图像 设置到 屏幕的正上方rect.y = -rect.heightupdate()方法: 判断 是否移出屏幕,如果是,将图像设置到 屏幕的正上方,从而实现 交替滚动 背景精灵的代码实现: class Background(GameSprite): """游戏背景精灵""" def update(self): # 1、调用父类的方法实现 super().update() # 2、判断是否移出屏幕,如果移出屏幕,将图片移动到正上方 if self.rect.y >= SCREEN_RECT.height: self.rect.y = -self.rect.height ②在plane_main.py中显示背景精灵在__creat_sprites方法中创建 精灵 和 精灵组 def __create_sprites(self): # 创建背景精灵和精灵组 bg1 = Background("D:/My life/music/some photos/sunrise.jpg") bg2 = Background("D:/My life/music/some photos/sunrise.jpg") bg2.rect.y = -bg2.rect.height self.back_group = pygame.sprite.Group(bg1, bg2)在__update_sprites方法中,让 精灵组 调用 update()和draw()方法 def __update_sprites(self): self.back_group.update() self.back_group.draw(self.screen) ③简化背景精灵的创建精灵的 初始位置的设置,由 精灵自己 负责,不由主程序负责。 初始化方法: 直接指定背景图片 is_alt判断是否是另一张图像 Flase表示 第一张图像,需要与屏幕重合 True表示 另一张图像,在屏幕的正上方 继承: 如果父类提供的方法不能满足子类的需求: 派生一个子类 在子类中针对特有的需求,重写父类方法,并且进行扩展 def __init__(self, is_alt = False): # 默认alt为False #1、调用父类方法实现精灵的创建(image / rect / speed) super().__init__("D:/My life/music/some photos/sunrise.jpg") #2、判断是否是交替图像,如果是,需要设置初始位置 if is_alt: self.rect.y = -self.rect.height由此一来,主程序的代码就可以简化为: def __create_sprites(self): # 创建背景精灵和精灵组 bg1 = Background() bg2 = Background(True) self.back_group = pygame.sprite.Group(bg1, bg2) (4)敌机设计Enemy类 ①使用定时器添加敌机在pygame中,可以使用pygame.time.set_timer()来添加 定时器(每隔一段时间,去执行一些动作)。 set_timer(eventid, milliseconds)。 set_timer可以创建一个事件,可以在 游戏循环 的事件监听方法中捕获到该事件。 第一个参数 事件代号需要基于常量 pygame.USEREVENT来指定。 USERENEVT是一个整数,再增加的事件可以使用USEREVENT + 1指定,以此类推… 第2个参数是 事件触发 间隔的 毫秒值 通过pygame.event.get()获取当前时刻所有的 事件列表; 遍历列表 并且判断event.type是否等于eventid,如果相等,表示 定时器事件 发生。 pygame的定时器使用套路非常固定: 1、定义 定时器常量——eventid 2、在初始化方法中,调用set_timer方法设置定时器事件 3、在游戏循环中,监听定时器事件。 定义事件: 在plane_sprites.py的顶部定义 事件常量 #创建敌机的定时器常量 CREATE_ENEMY_EVENT = pygame.USEREVENT ②设计Enemy类游戏启动后,每隔1秒 会 出现一架敌机 每架敌机 向屏幕下方飞行,飞行的 速度各不相同 没架敌机出现的 水平位置 也不尽相同 当敌机 从屏幕下方飞出,不会再飞回屏幕中 初始化方法: 指定 敌机图片 随机 敌机的初始位置和初始速度 重写update()方法 判断是否飞出屏幕,如果是,从 精灵组 删除 ③创建敌机1、在__creat_sprites添加敌机精灵组。 敌机是 定时被创建的,因此在初始化方法中,不需要创建敌机 self.enemy_group = pygame.sprite.Group() 2、在__event_handler创建敌机,并且添加到精灵组 调用 精灵组的add方法,可以向精灵组添加精灵 #创建敌机 enemy = Enemy() #将敌机精灵添加到精灵组 self.enemy_group.add(enemy) 3、在__update_sprites让 敌机精灵组调用update和draw方法 self.enemy_group.update() self.enemy_group.draw(self.screen) 可以看到敌机一架架陆续出现 ④ 随机 敌机位置和速度 导入模块时,建议按照以下顺序导入官方标准模块导入 第三方模块导入 应用程序模块导入 修改plane_sprites.py增加random的导入 import random # 官方标准模块 随机化敌机初始速度 self.speed = random.randint(1, 3) # (随机数的最小值,随机数的最大值) 敌机从屏幕顶部缓缓进入 self.rect.bottom = 0 随机化敌机出现的水平位置 max_x = SCREEN_RECT.width - self.rect.width self.rect.x = random.randint(0, max_x) #水平位置最小值为0,最大位置为“屏幕宽度-飞机宽度” ⑤移出屏幕销毁敌机敌机移出屏幕后,如果没有撞到飞机,敌机的历史生命已经终结。需要从 敌机组 删除,否则会造成 内存浪费 检测敌机被销毁: __del__内置方法会在对象被销毁前调用。在开发中,可以用于 判断对象是否被销毁 def __del__(self): print("敌机销毁%s" %self.rect)判断敌机是否飞出屏幕,如果是,调用kill()方法将精灵精灵组中移出,敌机自动销毁 def update(self): super().update(args) #判断敌机是否移出屏幕 if self.rect.y >= SCREEN_RECT.height: #将精灵从精灵组中删除 self.kill() (5)英雄飞机游戏启动后,飞机出现在屏幕的 水平中间 位置,距离 屏幕底部120像素。 飞机每隔0.5秒发射一次子弹,每次 连发三枚子弹。 飞机默认不会移动,需要通过 左 / 右 方向键,控制 英雄 在水平方向移动。 (6)子弹需求子弹 从 英雄飞机的正上方发射 沿直线 向 上方 飞行 飞出屏幕后,需要从 精灵组 中删除 在plane_sprites新建Hero类 初始化方法 指定 英雄图片 初始速度=0——英雄默认静止不动 定义bullets子弹精灵组 保存子弹精灵 重写update()方法 英雄需要 水平移动 并且需要保证不能 移出屏幕 增加 bullets 属性,记录所有 子弹精灵 增加 file 方法,用于发射子弹 center centerx = x + 0.5 * width # x的中心点 centery = y + 0.5 * height # y的中心点 bottom = y + height ①绘制英雄在__creat_sprites添加 英雄精灵 和 英雄精灵组 英雄需要单独定义成属性,因为后续要针对 英雄 做 碰撞检测 以及发射子弹 #创建英雄的精灵和 英雄精灵组 self.hero = Hero() self.hero_group = pygame.sprite.Group(self.hero) 在__update_sprites,让 英雄精灵组 调用 update和 draw 方法。 self.hero_group.update() self.hero_group.draw(self.screen) ②移动英雄位置在pygame中针对 键盘按键的捕获,有两种方式: 第一种方式: 判断 event.type == pygame.KEYDOWN elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT: print("向右移动...")缺点:如果用户按住不放,默认只按了一次。 第二种方式: 首先使用pygame.key.get_pressed()返回 所有 按键元组 通过 键盘常量,判断元组中某一个键是否被按下——如果被按下,对应数值为1 keys_pressed = pygame.key.get_pressed() #判断是否按下了方向键 if keys_pressed[pygame.K_RIGHT]: print("持续向右移动...")优点:可以 按住键盘不放,实现 持续移动。 在Hero类中重写 update方法 用速度speed和英雄rect.x进行叠加 不需要调用父类方法——父类方法只是实现了单纯的垂直运动 def update(self): self.rect.x += self.speed在__event_handler方法中根据 左右方向键 设置英雄的 速度 向右 => speed = 2 self.hero.speed = 2向左 => speed = -2 elif keys_pressed[pygame.K_LEFT]: self.hero.speed = -2其他 => speed = 0 else: self.hero.speed = 0 ③控制英雄的移动边界right = x + width,利用right属性可以非常容易地针对右侧设置精灵位置。 #控制英雄的移动边界 if self.rect.x < 0: self.rect.x = 0 elif self.rect.right > SCREEN_RECT.right: self.rect.right = SCREEN_RECT.right ④发射子弹回顾 “四(4)①”的知识点 pygame的定时器使用套路非常固定: 1、定义 定时器常量——eventid 2、在初始化方法中,调用set_timer方法设置定时器事件 3、在游戏循环中,监听定时器事件。 第一步: 在Hero中定义fire方法 def fire(self): print("发射子弹")第二步: #英雄发射子弹事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1第三步: pygame.time.set_timer(HERO_FIRE_EVENT, 500) # 500ms第四步: elif event.type == HERO_FIRE_EVENT: self.hero.fire() ⑤定义子弹类Bullet 初始化方法: 指定子弹图片 初始速度 = -2——实现子弹向 上方 飞行 重写update()方法 判断是否飞出屏幕,如果是,从 精灵组 删除 定义子弹类 在plane_sprites新建Bullet继承自GameSprite 重写 初始化方法,直接指定 图片名称,并且设置初始速度 重写update()方法,判断子弹 飞出屏幕从精灵组删除 class Bullet(GameSprite): """子弹精灵""" def __init__(self): # 调用父类方法,指定 图片名称,并且设置初始速度 super().__init__("D:/My life/music/some photos/bullet.png", -2) def update(self): # 调用父类方法,让子弹沿垂直方向飞行 super().update() # 判断子弹是否飞出屏幕 if self.rect.bottom < 0: self.kill() def __del__(self): print("子弹被销毁...") ⑥发射子弹1、在Hero的 初始化方法 中创建 子弹精灵组 属性 #3、创建子弹精灵组 self.bullets = pygame.sprite.Group() 2、修改plane_main.py的__update_sprites方法,让 子弹精灵组 调用update和draw方法 self.hero.bullets.update() self.hero.bullets.draw(self.screen)3、实现fire()方法 # 1、创建子弹精灵 bullet = Bullet() # 2、设置初始位置——在英雄的正上方 bullet.rect.bottom = self.rect.y - 20 bullet.rect.centerx = self.rect.centerx # 3、将 **子弹** 添加到精灵组 self.bullet.add(bullet) ⑦一次发射三枚子弹修改fire,一次发射三枚子弹 for i in (0, 1, 2): # 1、创建子弹精灵 bullet = Bullet() # 2、设置初始位置——在英雄的正上方 bullet.rect.bottom = self.rect.y - i * 20 bullet.rect.centerx = self.rect.centerx # 3、将 子弹 添加到精灵组 self.bullets.add(bullet) ⑧碰撞检测了解碰撞检测的方法: 方法一:pygame.sprite.groupcollide() 两个精灵组 中 所有的精灵 的 碰撞检测 groupcollide(group1, group2, dokill1, dokill2, collided = None) 如果将dokill设置为True,则 发生碰撞的精灵将被自动移除。 collided参数是用于 计算碰撞的回调函数。如果没有指定,则每个精灵必须有一个rect属性。 方法二:pygame.sprite.spritecollie() 判断 某个精灵 和 指定精灵组 中的精灵的碰撞 spritecollide(sprite, froup, dokill, collided = None) 如果将dokill设置为True,则 指定精灵组 中 发生碰撞的精灵将被自动移除。 collided参数是用于 计算碰撞的回调函数。如果没有指定,则每个精灵必须有一个rect属性。 返回 精灵组 中 跟 精灵 发生碰撞的 精灵列表 def __check_collide(self): #1、子弹摧毁敌机 pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True) #2、敌机撞毁英雄 enemies = pygame.sprite.spritecollide(self.hero, self.enemyy_group, True) #判断列表是否有内容 if len(enemies) >0: #让英雄牺牲 self.hero.kill() #结束游戏 PlaneGame.__game_over() 五、游戏设计完成,运行图片飞机大战游戏共包含两个python文件:plane_main.py和plane_sprites.py 附录一:plane_main.py import pygame pygame.init() # 这行代码可以解决“pygame is not initialized”问题 from plane_sprites import * class PlaneGame(object): def __init__(self): print("游戏初始化") # 1、创建游戏的窗口 self.screen = pygame.display.set_mode(SCREEN_RECT.size) # 2、创建游戏的时钟 self.clock = pygame.time.Clock() # 3、调用私有方法,精灵和精灵组的创建 self.__create_sprites() # 4、设置定时器事件-创建敌机 1s pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000) # 1000ms pygame.time.set_timer(HERO_FIRE_EVENT, 500) # 500ms def __create_sprites(self): # 创建背景精灵和精灵组 bg1 = Background() bg2 = Background(True) self.back_group = pygame.sprite.Group(bg1, bg2) # 创建敌机的精灵组 self.enemy_group = pygame.sprite.Group() # 创建英雄的精灵和 英雄精灵组 self.hero = Hero() self.hero_group = pygame.sprite.Group(self.hero) def start_game(self): print("游戏开始") while True: # 1、设置刷新频率 self.clock.tick(FRAME_PER_SECOND) # 2、事件监听 self.__event_handler() # 3、碰撞检测 self.__check_collide() # 4、更新 / 绘制精灵组 self.__update_sprites() # 5、更新显示 pygame.display.update() # 事件监听 def __event_handler(self): for event in pygame.event.get(): # 判断是否退出游戏 if event.type == pygame.QUIT: PlaneGame.__game_over() elif event.type == CREATE_ENEMY_EVENT: # print("敌机出场...") # 创建敌机 enemy = Enemy() # 将敌机精灵添加到精灵组 self.enemy_group.add(enemy) elif event.type == HERO_FIRE_EVENT: self.hero.fire() # elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT: # print("向右移动...") # 首先使用`pygame.key.get_pressed()`返回所有按键元组 # 通过键盘常量,判断元组中某一个键是否被按下——如果被按下,对应数值为`1` keys_pressed = pygame.key.get_pressed() # 判断是否按下了方向键 if keys_pressed[pygame.K_RIGHT]: # print("持续向右移动...") self.hero.speed = 2 elif keys_pressed[pygame.K_LEFT]: self.hero.speed = -2 else: self.hero.speed = 0 # 碰撞 def __check_collide(self): # 1、子弹摧毁敌机 pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True) # 2、敌机撞毁英雄 enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True) # 判断列表是否有内容 if len(enemies) > 0: # 让英雄牺牲 print("英雄牺牲了") self.hero.kill() # 结束游戏 PlaneGame.__game_over() def __update_sprites(self): self.back_group.update() self.back_group.draw(self.screen) self.enemy_group.update() self.enemy_group.draw(self.screen) self.hero_group.update() self.hero_group.draw(self.screen) self.hero.bullets.update() self.hero.bullets.draw(self.screen) @staticmethod def __game_over(): print("游戏结束") pygame.quit() exit() if __name__ == '__main__': # 创建游戏对象 game = PlaneGame() # 启动游戏 game.start_game() 附录二:plane_sprites.py import random # 官方标准模块 import pygame SCREEN_RECT = pygame.Rect(0, 0, 480, 700) FRAME_PER_SECOND = 60 # 创建敌机的定时器常量 CREATE_ENEMY_EVENT = pygame.USEREVENT # 英雄发射子弹事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1 class GameSprite(pygame.sprite.Sprite): # 飞机大战游戏精灵 def __init__(self, image_name, speed=1): # 调用父类的初始化方法 super().__init__() # 定义对象的属性 self.image = pygame.image.load(image_name) self.rect = self.image.get_rect() self.speed = speed def update(self): # 在屏幕的绘制方向移动 self.rect.y += self.speed class Background(GameSprite): """游戏背景精灵""" def __init__(self, is_alt=False): # 默认alt为False # 1、调用父类方法实现精灵的创建(image / rect / speed) super().__init__("D:/My life/music/some photos/sunrise.jpg") # 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 Enemy(GameSprite): """敌机精灵""" def __init__(self): # 1、调用父类方法,创建敌机精灵,同时指定敌机图片 super().__init__("D:/My life/music/some photos/enemyplane.png") # 2、指定敌机的初始位置 self.speed = random.randint(1, 3) # (随机数的最小值,随机数的最大值) # 3、指定敌机的初始速度 self.rect.bottom = 0 max_x = SCREEN_RECT.width - self.rect.width self.rect.x = random.randint(0, max_x) def update(self): # 1、调用父类方法,保持垂直方向的飞行 super().update() # 2、判断是否飞出屏幕,如果是,从 **精灵组** 删除 if self.rect.y >= SCREEN_RECT.height: # print("飞出屏幕,需要从精灵组中删除...") # 调用kill()方法将精灵精灵组中移出,敌机自动销毁 self.kill() def __del__(self): # print("敌机销毁成功%s" % self.rect) pass class Hero(GameSprite): """英雌精灵""" def __init__(self): # 1、调用父类方法,设置image和速度 super().__init__("D:/My life/music/some photos/plane.png", 0) # 2、设置英雌的初始位置 self.rect.centerx = SCREEN_RECT.centerx self.rect.bottom = SCREEN_RECT.bottom - 120 # 3、创建子弹精灵组 self.bullets = pygame.sprite.Group() def update(self): self.rect.x += self.speed # 控制英雄的移动边界 if self.rect.x < 0: self.rect.x = 0 elif self.rect.right > SCREEN_RECT.right: self.rect.right = SCREEN_RECT.right def fire(self): print("发射子弹") for i in (0, 1, 2): # 1、创建子弹精灵 bullet = Bullet() # 2、设置初始位置——在英雄的正上方 bullet.rect.bottom = self.rect.y - i * 20 bullet.rect.centerx = self.rect.centerx # 3、将 子弹 添加到精灵组 self.bullets.add(bullet) class Bullet(GameSprite): """子弹精灵""" def __init__(self): # 调用父类方法,指定 图片名称,并且设置初始速度 super().__init__("D:/My life/music/some photos/bullet.png", -2) def update(self): # 调用父类方法,让子弹沿垂直方向飞行 super().update() # 判断子弹是否飞出屏幕 if self.rect.bottom < 0: self.kill() def __del__(self): # print("子弹被销毁...") pass 附录三:飞机大战设计图片“英雄”“敌机”“子弹”均为PNG格式——便于设置透明背景。 英雄: 敌机: 子弹: 背景图片: |
CopyRight 2018-2019 实验室设备网 版权所有 |