Pygame框架实现飞机大战


Posted in Python onAugust 07, 2020

本文实例为大家分享了Pygame框架实现飞机大战的具体代码,供大家参考,具体内容如下

飞机大战主游戏类

"""
项目名称:简单飞机大战游戏
基于框架:Pygame
开发日期:2020.07
开发人员:Y
版本:****
"""


import sys # 导入内置模块sys 调用sys.exit()
import pygame # 导入第三方模块pygame
from plane_sprites import * # 导入自定义模块内所有工具


class PlayGame(object): # 定义开始游戏主类 继承object基类
 def __init__(self): # 定义初始化方法
 self.srceen = pygame.display.set_mode(SRCEEN_SIZE.size) # 设置游戏主窗口
 self.clock = pygame.time.Clock() # 设置游戏时钟 用于刷新屏幕帧率
 self.__creat_sprites() # 调用私有方法实现添加精灵类内容
 pygame.display.set_caption('飞机大战') # 设置窗口标题
 pygame.time.set_timer(CREAT_ENEMY_EVENT, 1000) # 设置事件定时器 用于每隔一段时间执行一次事件
 pygame.time.set_timer(FIRE_BULLTE, 300) # 设置事件定时器 用于每隔一段时间执行一次事件

 def start_game(self): # 定义开始游戏方法
 while True: # 游戏循环
  self.clock.tick(CLOCK_TICK) # 利用时钟设置刷新帧率
  self.__event_hander() # 调用私有方法实现监听事件
  self.__check_collide() # 调用私有方法检测碰撞
  self.__update_sprites() # 调用私有方法更新和绘制精灵组
  pygame.display.flip() # 更新窗口显示
  # pygame.display.update() # 更新窗口显示

 def __creat_sprites(self): # 定义添加精灵组方法
 bj1 = Background() # 利用背景类创建背景对象1 默认参数Flase 表示第一张图像,需要与屏幕重合
 bj2 = Background(True) # 利用背景类创建背景对象2 参数True 表示另一张图像, 在屏幕的正上方
 self.bj_group = pygame.sprite.Group(bj1, bj2) # 设置背景精灵组
 self.emeny_group = pygame.sprite.Group() # 提前设置敌机精灵组 但并不设置敌机对象
 # 敌机类对象是定时被创建的,因此在初始化方法中,不需要创建敌机对象
 self.hero = Hero() # 利用英雄类创建英雄对象 注意:后续对英雄做碰撞检测及发射操作,所有需要单独设置为属性
 self.hero_group = pygame.sprite.Group(self.hero) # 设置英雄精灵组

 def __event_hander(self): # 定义监听事件方法
 for event in pygame.event.get(): # 循环监听所有事件
  if event.type == pygame.QUIT: # 如果是单击退出按钮事件
  PlayGame.__game_over() # 调用私有方法实现结束游戏
  elif event.type == CREAT_ENEMY_EVENT: # 如果是执行自定义事件创建敌机
  emeny1 = Enemy("./images/enemy1.png") # 利用敌机类创建敌机1
  emeny2 = Enemy("./images/enemy2.png") # 利用敌机类创建敌机2
  emeny3 = Enemy("./images/enemy3_n1.png")
  self.emeny_group.add(emeny1, emeny2, emeny3) # 对之前设置好的敌机精灵组进行添加精灵对象
  elif event.type == FIRE_BULLTE: # 如果是执行自定义事件发射子弹
  self.hero.fire() # 调用英雄对象的发射子弹方法
 key_tuple = pygame.key.get_pressed() # 捕获键盘按键返回值为元组
 if key_tuple[pygame.K_RIGHT]: # 判断捕获键盘按键为右键
  self.hero.speed = 4 # 设置英雄类对象的速度为4 向右移动
 elif key_tuple[pygame.K_LEFT]: # 判断捕获键盘按键为左键
  self.hero.speed = -4 # 设置英雄类对象的速度为-4 向左移动
 else:   # 否则
  self.hero.speed = 0 # 捕获其余任何按键英雄类对象速度不变 不移动

 def __check_collide(self): # 定义检测碰撞方法
 pygame.sprite.groupcollide(self.hero.bullet_group, self.emeny_group, True, True)
 # 两个精灵组中所有的精灵的碰撞检测 属性True, 则发生碰撞的精灵将被自动移除
 enemies = pygame.sprite.spritecollide(self.hero, self.emeny_group, True)
 # 判断某个精灵和指定精灵组中的精灵的碰撞 属性True,则指定精灵组中发生碰撞的精灵将被自动移除
 # 返回精灵组中跟精灵发生碰撞的精灵列表
 if len(enemies) > 0: # 判断敌机精灵组内精灵是否存在 若存在
  self.hero.kill() # 碰撞导致英雄销毁
  PlayGame.game_over() # 调用类中结束游戏方法 退出游戏

 def __update_sprites(self): # 定义精灵组更新和绘制方法
 self.bj_group.update() # 更新背景类精灵
 self.bj_group.draw(self.srceen) # 绘制背景类精灵
 self.emeny_group.update() # 更新敌机类精灵
 self.emeny_group.draw(self.srceen) # 绘制敌机类精灵
 self.hero_group.update() # 更新英雄类精灵
 self.hero_group.draw(self.srceen) # 绘制英雄类精灵
 self.hero.bullet_group.update() # 更新英雄子弹类精灵
 self.hero.bullet_group.draw(self.srceen) # 绘制英雄子弹类精灵

 @staticmethod # 声明定义静态方法
 def __game_over(): # 定义静态方法
 print("游戏结束") # 控制台打印游戏结束
 pygame.quit() # 卸载所有pygame模块工具
 sys.exit() # 退出程序


if __name__ == '__main__': # 判断当前执行
 playgame = PlayGame() # 创建开始游戏对象
 playgame.start_game() # 调用开始游戏对象的开始方法

游戏工具类

"""
项目名称:简单飞机大战游戏
基于框架:Pygame
开发日期:2020.07
开发人员:Y
版本:****
"""

import random # 导入内置模块 random 调用randint方法
import pygame # 导入第三方模块pygame

SRCEEN_SIZE = pygame.Rect(0, 0, 480, 700) # 利用Rect方法定义窗口大小常量
CLOCK_TICK = 60 # 定义时钟帧率常量
CREAT_ENEMY_EVENT = pygame.USEREVENT # 自定义创建敌机事件
FIRE_BULLTE = pygame.USEREVENT + 1 # 自定义发射子弹事件


class GameSprites(pygame.sprite.Sprite): # 定义游戏精灵类 继承pygame.sprite.Sprite
 def __init__(self, image_name, speed=1): # 定义初始化方法
 super().__init__() # 因未继承object基类 定义初始化方法需要先super()下父类的 __init_方法
 self.image = pygame.image.load(image_name) # 定义实例属性image为加载图片至内存中
 self.rect = self.image.get_rect() # 定义实例属性rect为获取图片的矩形区域(0, 0, image.width, image.height)
 self.speed = speed # 定义实例属性speed为运动速度 实质为移动的幅度,幅度大则速度快

 def update(self): # 定义更新数据方法实现移动image
 self.rect.y += self.speed # 移动image的Y轴距离为向下speed距离


class Background(GameSprites): # 定义背景精灵类 继承游戏精灵类
 def __init__(self, is_alt=False): # 在父类(游戏精灵类)基础上定义初始化方法 is_alt缺省参数用于判断是否为第二张image
 super().__init__("./images/background.png")
 # 因未继承object基类 定义初始化方法需要先super()下父类的 __init_方法 并以背景图为image为参数
 if is_alt: # 判断是否为第二张image 如果是
  self.rect.y = -self.rect.height
  # 将第二张image的Y轴坐标设置为本身image.height的负值 用来实现将第二张image置于第一张image上方

 def update(self): # 在父类(游戏精灵类)基础上修改 更新数据方法实现移动background_image
 super().update() # 继承父类(游戏精灵类)的移动方式 按照speed向下移动
 if self.rect.y >= SRCEEN_SIZE.height:
  # 判断background_image在Y轴距离是否大于等于窗口高度 如果是
  # 表示第一张image全部下滑出窗口
  self.rect.y = -self.rect.height # 需要重新将该image置于第二张image上方


class Enemy(GameSprites): # 定义敌机精灵类 继承游戏精灵类
 def __init__(self, image): # 在父类(游戏精灵类)基础上修改定义初始化方法 自定义参数image用于实现多种形式敌机
 super().__init__(image)
 # 因未继承object基类 定义初始化方法需要先super()下父类的 __init_方法 并以自定义背景图为image为参数
 self.speed = random.randint(1, 5) # 修改敌机类image移动幅度(速度)为1--5随机值
 self.rect.bottom = 0 # 定义敌机类image的底部为0 表示每次从窗口最顶部驶入 美化效果
 MAX_WIDTH = SRCEEN_SIZE.width - self.rect.width
 # 定义常量为敌机对象出现时的image.x最大值 防止跑出窗口界面或只有敌机部分驶入窗口
 # 最大宽度 = 窗口宽度 - 敌机image的宽度
 self.rect.x = random.randint(0, MAX_WIDTH)
 # 设置敌机image的出现范围为限制在窗口内

 def update(self): # 在父类(游戏精灵类)基础上修改 更新数据方法实现移动emeny_image
 super().update() # 继承父类(游戏精灵类)的移动方式 按照speed向下移动
 if self.rect.y >= SRCEEN_SIZE.height: # 判断敌机对象的Y轴距离是否超过窗口高度 如果是 表示敌机对象驶出窗口
  # print("敌机销毁")
  self.kill() # 敌机对象驶出窗口后进行销毁 从内存中释放敌机image 减轻计算机内存压力

 def __del__(self): # 定义敌机对象销毁前的动作,如爆炸动画,碰撞音频等等
 pass # pass语句占位 待开发。。

class Hero(GameSprites): # 定义英雄精灵类 继承游戏精灵类
 def __init__(self): # 在父类(游戏精灵类)基础上修改定义初始化方法 实现英雄类image初始位置以及移动限制
 super().__init__("./images/me1.png", 0)
 # 因未继承object基类 定义初始化方法需要先super()下父类的 __init_方法 并以自定义英雄类image
 self.rect.centerx = SRCEEN_SIZE.centerx # 限制英雄类对象只可以在X轴(水平方向)移动
 self.rect.bottom = SRCEEN_SIZE.bottom - 120 # 设置英雄类对象出现时底部位置为窗口底部上120px
 self.bullet_group = pygame.sprite.Group() # 注意:内置子弹类精灵组为英雄类实例属性 提前设置子弹精灵组

 def update(self, *args): # 注意:此方法不是在父类(游戏精灵类)基础上修改 更新数据方法实现移动hero_image
 # 因为英雄类对象不需要从上向下移动,无需继承父类(游戏精灵类)的update方法
 self.rect.x += self.speed # 设置移动实例属性 在X轴水平方向以speed速度(幅度)移动
 if self.rect.x < 0: # 判断英雄类实例在X轴坐标是否小于0 即是否移出窗口左侧 如果是
  self.rect.x = 0 # 重置(限制)英雄实例在X轴方向坐标为0 即窗口最左侧
 elif self.rect.right > SRCEEN_SIZE.right: # 判断英雄类实例在X轴坐标是否大于窗口最右侧 即是否移除窗口右侧 如果是
  self.rect.right = SRCEEN_SIZE.right # 重置(限制)英雄实例在X轴方向坐标为窗口最右侧 即窗口最右侧

 def fire(self): # 英雄类精灵实例定义发射子弹方法
 print("发射子弹。。。") # 控制台打印发射子弹。。。字样
 for i in (0, 1, 2): # for计次循环用于实现子弹连发
  bullte = Bullet() # 利用子弹精灵类创建子弹实例
  bullte.rect.bottom = self.rect.y - i * 20 # 设置子弹初始位置的最底部为英雄类对象Y轴方向的上方 i*20 px的距离
  bullte.rect.centerx = self.rect.centerx # 限制子弹类对象位置始终为英雄类对象的X轴中间
  self.bullet_group.add(bullte) # 对之前设置好的子弹精灵组进行添加精灵对象


class Bullet(GameSprites): # 定义子弹精灵类 继承游戏精灵类
 def __init__(self): # 在父类(游戏精灵类)基础上修改定义初始化方法 实现子弹类image以及speed为-x 即向上移动speed
 super().__init__("./images/bullet1.png", -2)

 def update(self, *args): # 在父类(游戏精灵类)基础上 更新数据方法实现移动bullet_image
 super().update() # 继承父类(游戏精灵类)的移动方式 按照speed向上移动
 if self.rect.bottom < 0: # 判断子弹对象的Y轴距离是否超过窗口高度 如果是 表示子弹对象驶出窗口
  self.kill() # 子弹对象驶出窗口后进行销毁 从内存中释放子弹image 减轻计算机内存压力

游戏截图

Pygame框架实现飞机大战

更多有趣的经典小游戏实现专题,分享给大家:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python去除列表中重复元素的方法
Mar 20 Python
浅析Python中的getattr(),setattr(),delattr(),hasattr()
Jun 14 Python
基于Python os模块常用命令介绍
Nov 03 Python
基于Python实现的微信好友数据分析
Feb 26 Python
python奇偶行分开存储实现代码
Mar 19 Python
利用python如何处理nc数据详解
May 23 Python
在tensorflow中设置保存checkpoint的最大数量实例
Jan 21 Python
关于python中导入文件到list的问题
Oct 31 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
Nov 02 Python
python正则表达式re.match()匹配多个字符方法的实现
Jan 27 Python
Python3+PyCharm+Django+Django REST framework配置与简单开发教程
Feb 16 Python
Django展示可视化图表的多种方式
Apr 08 Python
python爬取网易云音乐热歌榜实例代码
Aug 07 #Python
Python变量格式化输出实现原理解析
Aug 06 #Python
Python实现Canny及Hough算法代码实例解析
Aug 06 #Python
vscode调试django项目的方法
Aug 06 #Python
Python如何使用input函数获取输入
Aug 06 #Python
Python map及filter函数使用方法解析
Aug 06 #Python
python学习笔记之多进程
Aug 06 #Python
You might like
图形数字验证代码
2006/10/09 PHP
PHP set_time_limit(0)长连接的实现分析
2010/03/02 PHP
php 字符串函数收集
2010/03/29 PHP
php比较多维数组中值的大小排序实现代码
2012/09/08 PHP
PHP实现过滤各种HTML标签
2015/05/17 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
全面解析PHP操作Memcache基本函数
2016/07/14 PHP
PHP异常类及异常处理操作实例详解
2018/12/19 PHP
jquery中attr和prop的区别分析
2015/03/16 Javascript
javascript实时获取鼠标坐标值并显示的方法
2015/04/30 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
2015/06/29 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
jQuery+ajax实现文章点赞功能的方法
2015/12/31 Javascript
微信小程序-小说阅读小程序实例(demo)
2017/01/12 Javascript
关于不同页面之间实现参数传递的几种方式讨论
2017/02/13 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
微信小程序实现传参数的几种方法示例
2018/01/10 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
vue中动态绑定表单元素的属性方法
2018/02/23 Javascript
JavaScript 中的 this 工作原理
2018/06/20 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
JavaScript中CreateTextFile函数
2020/08/30 Javascript
[07:55]2014DOTA2 TI正赛第三日 VG上演推进荣耀DKEG告别
2014/07/21 DOTA
一张图带我们入门Python基础教程
2017/02/05 Python
Python中的并发处理之asyncio包使用的详解
2018/04/03 Python
python实现维吉尼亚算法
2019/03/20 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
python 基于selenium实现鼠标拖拽功能
2020/12/24 Python
Farfetch台湾官网:奢侈品牌时尚购物平台
2019/06/17 全球购物
2013年保送生自荐信格式
2013/11/20 职场文书
理工科学生的自我评价
2013/12/15 职场文书
电脑专业个人求职信范文
2014/02/04 职场文书
校庆接待方案
2014/03/18 职场文书
创先争优承诺书
2015/01/20 职场文书
2015年乡镇纪检工作总结
2015/04/22 职场文书
在Python 中将类对象序列化为JSON
2022/04/06 Python