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程序设计入门(5)类的使用简介
Jun 16 Python
python django集成cas验证系统
Jul 14 Python
Python RuntimeError: thread.__init__() not called解决方法
Apr 28 Python
Python功能键的读取方法
May 28 Python
利用Python自动监控网站并发送邮件告警的方法
Aug 24 Python
Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
Mar 19 Python
浅谈Python中重载isinstance继承关系的问题
May 04 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
Feb 16 Python
python tkinter控件布局项目实例
Nov 04 Python
jupyter notebook运行命令显示[*](解决办法)
May 18 Python
聊聊Python String型列表求最值的问题
Jan 18 Python
Python字符串常规操作小结
Apr 03 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
PHP中单引号与双引号的区别分析
2014/08/19 PHP
PHP目录与文件操作技巧总结(创建,删除,遍历,读写,修改等)
2016/09/11 PHP
redirect_uri参数错误的解决方法(必看)
2017/02/16 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
Code:findPosX 和 findPosY
2006/12/20 Javascript
extjs 为某个事件设置拦截器
2010/01/15 Javascript
JavaScript与Image加载事件(onload)、加载状态(complete)
2011/02/14 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
2014/01/09 Javascript
jQuery使用before()和after()在元素前后添加内容的方法
2015/03/26 Javascript
JavaScript 性能优化小结
2015/10/12 Javascript
JS中创建函数的三种方式及区别
2016/03/13 Javascript
JS在onclientclick里如何控制onclick的执行
2016/05/30 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
将RGB值转换为灰度值的简单算法
2019/10/09 Javascript
JavaScript常用工具函数大全
2020/05/06 Javascript
微信小程序实现点击页面出现文字
2020/09/21 Javascript
[50:02]完美世界DOTA2联赛循环赛 Magma vs IO BO2第一场 11.01
2020/11/02 DOTA
Python实现的递归神经网络简单示例
2017/08/11 Python
python 二分查找和快速排序实例详解
2017/10/13 Python
Python中一行和多行import模块问题
2018/04/01 Python
python 地图经纬度转换、纠偏的实例代码
2018/08/06 Python
python打包exe开机自动启动的实例(windows)
2019/06/28 Python
详解python pandas 分组统计的方法
2019/07/30 Python
Django ORM 查询管理器源码解析
2019/08/05 Python
django组合搜索实现过程详解(附代码)
2019/08/06 Python
html5音频_动力节点Java学院整理
2018/08/22 HTML / CSS
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
网络、C以及其他硬件方面的面试题
2016/08/23 面试题
司机的工作范围及职责
2013/11/13 职场文书
致铅球运动员广播稿精选
2014/01/12 职场文书
设计师个人求职信范文
2014/02/02 职场文书
《猴子种树》教学反思
2014/02/14 职场文书
小学校长竞聘演讲稿
2014/05/16 职场文书
店铺转让协议书(2014版)
2014/09/23 职场文书
义诊活动通知
2015/04/24 职场文书
SpringCloud Function SpEL注入漏洞分析及环境搭建
2022/04/08 Java/Android