全网首份pyQt6飞机大战

该飞机大战具备较为完善的框架

可自动调整飞机与屏幕的位置

具备单点开火,半自动开火,全自动开火三种开火状态

每个作品作者花了不少头发,希望路过的大神多多留言点赞,对于不足的地方可以提出更完善的解决方法,我也会吸取教训,也会继续保持开源精神,奈何作者家境贫寒,需要不断的加班上班来养活自己,没有太多的时间精力去研究更多其他游戏,也欢迎有经济条件的大神也可以请我喝一瓶可乐,感激不尽。下面是飞机大战的图片及源码,图片素材是网上搜集的,如有侵权的请联系删除。

要运行该游戏需要安装python环境 并且在控制台输入pip install pyqt6进行安装环境

使用openGL 驱动需显卡支持

完整包下载地址:点击这里

import random
import sys
import timefrom PyQt6 import QtOpenGLWidgets
from PyQt6.QtCore import QTimer, Qt
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QLabel, QApplication# 飞机大战主类
class PlaneBigWar(QtOpenGLWidgets.QOpenGLWidget):"""控制方式:子弹发射:1. 使用鼠标单点发射2. 使用X半自动发射3. 使用空格自动发射# 屏幕宽高,内部部件与飞机位置会随着屏幕大小改变自动改变screenWidth = 1300screenHeight = 700# 初始生命分数life = 3score = 0# 存储子弹与敌人的列表enemies = []bullets = []# 游戏状态控制,初始为开始状态STATES = {"START": 0, "RUNNING": 1, "PAUSE": 2, "GAME_OVER": 3}state = STATES["START"]# 时间间隔静态方法,可提供其他类使用def isActionTime(lastTime, interval)"""# 屏幕宽高,内部部件与飞机位置会随着屏幕大小改变自动改变screenWidth = 1300screenHeight = 700# 初始生命分数life = 3score = 0# 存储子弹与敌人的列表enemies = []bullets = []# 游戏状态控制,初始为开始状态STATES = {"START": 0, "RUNNING": 1, "PAUSE": 2, "GAME_OVER": 3}state = STATES["START"]# 时间间隔静态方法,可提供其他类使用@staticmethoddef isActionTime(lastTime, interval):if lastTime == 0:return TruecurrentTime = time.time()return currentTime - lastTime >= interval# 初始化主类构造器def __init__(self):super().__init__()# 初始化相关变量self.timer = QTimer(self)# 初始化UI窗口self.initUI()# 入场对象的时间间隔0.5self.lastTime = 0self.interval = 0.5# 与英雄机碰撞的时间间隔0.5self.hitLastTime = 0self.hitInterval = 0.5# 初始化爆炸特效self.booms = [QPixmap(f"./images/b{i}.png") for i in range(1, 12)]# 初始化logo图片logo = QPixmap("./images/LOGO.png")# 初始化分数牌图片indicator = QPixmap("./images/score.png")# 初始化游戏开始提示图片图片startGame = QPixmap("./images/startGame.png")# 初始化暂停提示图片gamePause = QPixmap("./images/game_pause_nor.png")# 初始化图片提示图片gameOver = QPixmap("./images/over.png")# 初始化再来一次提示图片again = QPixmap("./images/again.png")# 初始化背景图片self.bg = QPixmap("./images/bg235.jpg")# 初始化英雄图片self.h = QPixmap("./images/hero1.png")# 初始化子弹图片self.b = QPixmap("./images/bullet1.png")# 初始化敌人1图片self.e1 = QPixmap("./images/enemy1.png")# 初始化敌人2图片self.e2 = QPixmap("./images/enemy2.png")# 初始化敌人3图片self.e3 = QPixmap("./images/enemy3.png")# 初始化天空类self.sky = Sky(self, self.bg)# 初始化英雄类self.hero = Hero(self, self.h, self.booms)# 初始化Logo类(图片)self.logo = Remind(self, PlaneBigWar.screenWidth // 2 - logo.width() // 2,PlaneBigWar.screenHeight // 2 - logo.height() // 2, logo)# 初始化分数牌类(图片)self.indicator = Remind(self, PlaneBigWar.screenWidth - indicator.width(), 0, indicator)# 初始化游戏开始类(图片)self.startGame = Remind(self, PlaneBigWar.screenWidth // 2 - startGame.width() // 2,PlaneBigWar.screenHeight // 2 + logo.height() // 2 + startGame.height(),startGame)# 初始化暂停类(图片)self.gamePause = Remind(self, PlaneBigWar.screenWidth // 2 - gamePause.width() // 2,PlaneBigWar.screenHeight // 2 - gamePause.height() // 2, gamePause)# 初始化游戏结束类(图片)self.gameOver = Remind(self, PlaneBigWar.screenWidth // 2 - gameOver.width() // 2,PlaneBigWar.screenHeight // 2 - gameOver.height() // 2, gameOver)# 初始化再来一次类(图片)self.again = Remind(self, PlaneBigWar.screenWidth // 2 - again.width() // 2,PlaneBigWar.screenHeight // 2 + gameOver.height() // 2 + again.height(),again)# 初始化生命文字类self.lifeLabel = Text(self, PlaneBigWar.screenWidth - indicator.width() + 140, 51)# 初始化分数文字类self.scoreLabel = Text(self, PlaneBigWar.screenWidth - indicator.width() + 140, 13)def initUI(self):"""初始化UI界面"""self.initializeGL()# 设置窗口大小,并设置不可自动调整大小self.resize(PlaneBigWar.screenWidth, PlaneBigWar.screenHeight)self.setFixedSize(PlaneBigWar.screenWidth, PlaneBigWar.screenHeight)# 设置游戏标题self.setWindowTitle('飞机大战')# 设置鼠标可被自动侦测self.setMouseTracking(True)# 显示窗口self.show()# 初始化定时器自动运行run方法self.timer.start(10)self.timer.timeout.connect(self.run)def run(self):"""程序运行体,该方法每10毫秒被调用一次功能与游戏状态息息相关"""self.componentPaint()# 开始状态if PlaneBigWar.state == PlaneBigWar.STATES["START"]:self.logo.img.raise_()self.startGame.img.raise_()self.logo.paint()self.startGame.paint()# 运行状态elif PlaneBigWar.state == PlaneBigWar.STATES["RUNNING"]:self.componentEnter()self.componentStep()self.componentHit()self.componentDelete()# 暂停状态elif PlaneBigWar.state == PlaneBigWar.STATES["PAUSE"]:self.gamePause.paint()self.gamePause.img.raise_()# 游戏结束状态elif PlaneBigWar.state == PlaneBigWar.STATES["GAME_OVER"]:self.gameOver.paint()self.again.paint()self.again.img.raise_()self.gameOver.img.raise_()# 判断英雄总生命是否小于1,如果是将游戏状态设置为结束if PlaneBigWar.life < 1:PlaneBigWar.state = PlaneBigWar.STATES["GAME_OVER"]def enterEvent(self, event):"""该方法判断鼠标是否移入了程序窗口如果游戏状态为暂停状态将之恢复为运行状态"""if PlaneBigWar.state == PlaneBigWar.STATES["PAUSE"]:PlaneBigWar.state = PlaneBigWar.STATES["RUNNING"]self.gamePause.img.hide()def leaveEvent(self, event):"""该方法判断鼠标是否移出了程序窗口如果游戏状态为运行状态将之设置为暂停状态"""if PlaneBigWar.state == PlaneBigWar.STATES["RUNNING"]:PlaneBigWar.state = PlaneBigWar.STATES["PAUSE"]def mousePressEvent(self, event):"""鼠标点击事件状态为开始时,点击鼠标设置为运行状态状态为结束时,点击鼠标游戏将被初始化为开始状态游戏运行时,激活单发发射子弹模式"""if not self.hero.isDead:self.hero.shoot()if PlaneBigWar.state == PlaneBigWar.STATES["START"]:PlaneBigWar.state = PlaneBigWar.STATES["RUNNING"]self.logo.img.hide()self.startGame.img.hide()elif PlaneBigWar.state == PlaneBigWar.STATES["GAME_OVER"]:PlaneBigWar.life = 3PlaneBigWar.score = 0for enemy in PlaneBigWar.enemies:enemy.img.hide()for bullet in PlaneBigWar.bullets:bullet.img.hide()PlaneBigWar.enemies = []PlaneBigWar.bullets = []self.hero.img.hide()self.gameOver.img.hide()self.again.img.hide()self.hero = Hero(self, self.h, self.booms)PlaneBigWar.state = PlaneBigWar.STATES["START"]def keyPressEvent(self, QKeyEvent):"""键盘按键事件,按下x键启用半自动模式按下空格键时,启动自动发射模式"""if QKeyEvent.key() == Qt.Key.Key_X:if not self.hero.isDead:self.hero.shoot()if QKeyEvent.key() == Qt.Key.Key_Space:if self.hero.autoShoot:self.hero.autoShoot = Falseelse:self.hero.autoShoot = Truedef mouseMoveEvent(self, event):"""鼠标移动事件,活着的英雄机将跟随鼠标移动"""if PlaneBigWar.state == PlaneBigWar.STATES["RUNNING"] and not self.hero.isDead:mousePos = event.position()pos = (int(mousePos.x()), int(mousePos.y()))self.hero.step(pos)def componentPaint(self):"""游戏绘制组件,将绘制游戏中显示的图片与文字"""self.sky.paint()self.indicator.paint()self.indicator.img.raise_()self.lifeLabel.paint(f"{PlaneBigWar.life}")self.lifeLabel.label.raise_()self.scoreLabel.paint(f"{PlaneBigWar.score}")self.scoreLabel.label.raise_()self.hero.paint()for enemy in PlaneBigWar.enemies:enemy.paint()for bullet in PlaneBigWar.bullets:bullet.paint()def componentHit(self):"""游戏碰撞组件,用于检测某个物体与某个物体是否发生碰撞"""for enemy in PlaneBigWar.enemies:if enemy.hit(self.hero):self.hero.punish()enemy.punish()for bullet in PlaneBigWar.bullets:if bullet.hit(enemy) and (not bullet.isDead or not enemy.isDead):enemy.punish()bullet.punish()def componentEnter(self):"""游戏物体入场组件,用于添加对象至游戏"""if self.hero.autoShoot and not self.hero.isDead:self.hero.shoot()if not PlaneBigWar.isActionTime(self.lastTime, self.interval):returnself.lastTime = time.time()num = random.randint(0, 9)if num < 5:PlaneBigWar.enemies.append(Enemy(self, 1, 3, 1, self.e1, self.booms, random.randint(4, 5)))elif num <= 8:PlaneBigWar.enemies.append(Enemy(self, 2, 7, 5, self.e2, self.booms, random.randint(3, 4)))elif num == 9:if PlaneBigWar.enemies.__len__() == 0 or PlaneBigWar.enemies[0].type != 3:PlaneBigWar.enemies.insert(0, Enemy(self, 3, 10, 30, self.e3, self.booms, random.randint(2, 3)))def componentDelete(self):"""删除组件,将物体状态isDelete为True的对象进行移除"""for enemy in PlaneBigWar.enemies:enemy.isOutBounds()if enemy.isDelete:enemy.img.hide()PlaneBigWar.enemies.remove(enemy)for bullet in PlaneBigWar.bullets:bullet.isOutBounds()if bullet.isDelete:bullet.img.hide()PlaneBigWar.bullets.remove(bullet)if not PlaneBigWar.isActionTime(self.hitLastTime, self.hitInterval):returnself.hitLastTime = time.time()if self.hero.life <= 0:self.hero.img.hide()if PlaneBigWar.life > 0:self.hero = Hero(self, self.h, self.booms)PlaneBigWar.life -= 1def componentStep(self):"""游戏对象移动组件,用于移动游戏中的对象"""self.sky.step()for enemy in PlaneBigWar.enemies:enemy.step()for bullet in PlaneBigWar.bullets:bullet.step()class Sky(object):"""天空类,该类作为游戏的背景,自动创建两张相同的背景从上向下移动"""def __init__(self, canvas, img, speed=1):self.imgLab1 = QLabel(canvas)self.imgLab1.setPixmap(img)self.imgLab2 = QLabel(canvas)self.imgLab2.setPixmap(img)self.imgLab1.setMouseTracking(True)self.imgLab2.setMouseTracking(True)self.imgLab1.lower()self.imgLab2.lower()self.speed = speedself.x = 0self.y = 0self.width = img.width()self.height = img.height()def paint(self):self.imgLab1.show()self.imgLab2.show()self.imgLab1.move(self.x, self.y % self.height)self.imgLab2.move(self.x, (self.y - self.height) % self.height - self.height)def step(self):if self.y % self.height == 0:self.y = 0self.y += self.speedclass FlayingObject(object):"""游戏物体父类,所有能被添加到游戏中的物体都继承于此类"""def __init__(self, canvas, x, y, life, img, imgs, speed=2):self.canvas = canvasself.img = QLabel(canvas)self.img.setPixmap(img)self.img.setMouseTracking(True)self.imgs = imgsself.x = xself.y = yself.life = lifeself.speed = speedself.width = img.width()self.height = img.height()self.img.move(self.x, self.y)self.index = 0self.hitLastTime = 0self.hitInterval = 0.5self.isDead = Falseself.isDelete = Falsedef isOutBounds(self):"""越界方法,判断是否超出了屏幕的高度"""if self.y > PlaneBigWar.screenHeight:self.isDelete = Truedef hit(self, obj):"""碰撞算法,判断两个对象是否发生碰撞5为偏差值,使游戏更自然"""x1 = self.x - obj.width + 5x2 = self.x + self.width - 5y1 = self.y - obj.height + 5y2 = self.y + self.height - 5return x1 <= obj.x <= x2 and y1 <= obj.y <= y2def paint(self):"""绘制自己的方法,如果活着,正常绘制,死了激活动画效果,动画播放完毕激活删除"""if self.isDead:if self.index > self.imgs.__len__() - 1:self.isDelete = Trueif (isinstance(self, Enemy) or isinstance(self, Hero)) and self.index < self.imgs.__len__():self.img.setPixmap(self.imgs[self.index])self.img.move(self.x - 20, self.y - 20)self.img.resize(self.imgs[0].width(), self.imgs[0].height())self.index += 1else:self.img.move(self.x, self.y)if self.isDelete:self.img.hide()else:self.img.show()def step(self):"""移动方法,但多数子类都是从上向下所以默认从上向下.有特殊需求重写此方法"""self.y += self.speeddef punish(self):"""惩罚与奖励方法,调用此方法该对象会获得惩罚,如果敌人获得惩罚,英雄将获得奖励"""self.life -= 1if self.life < 1:self.isDead = Trueif isinstance(self, Enemy):if not PlaneBigWar.isActionTime(self.hitLastTime, self.hitInterval):returnself.hitLastTime = time.time()PlaneBigWar.score += self.scoreif isinstance(self, Bullet):self.isDelete = Trueclass Hero(FlayingObject):"""英雄类,具备发生子弹功能"""def __init__(self, canvas, img, imgs):FlayingObject.__init__(self, canvas, PlaneBigWar.screenWidth // 2 - img.width() // 2,int(PlaneBigWar.screenHeight * 0.7), 1, img, imgs)# 自动射击self.autoShoot = False# 射击延迟self.shootLastTime = 0self.shootInterval = 0.1# 子弹类型self.bulletType = 0def step(self, pos):"""重写父类移动方法,定位至pos的位置"""self.x = pos[0] - self.width // 2self.y = pos[1] - self.height // 2def shoot(self):"""子弹设计方法bulletType 0: 普通子弹bulletType 1: 双排子弹bulletType 2: 散弹"""if not PlaneBigWar.isActionTime(self.shootLastTime, self.shootInterval):returnself.shootLastTime = time.time()if self.bulletType == 0:PlaneBigWar.bullets.append(Bullet(self.canvas, self.x + self.width // 2 - self.canvas.b.width() // 2,self.y - self.canvas.b.height(), 1, self.canvas.b))class Enemy(FlayingObject):"""敌人类,游戏的敌人对象模板"""def __init__(self, canvas, type, life, score, img, speed, imgs: list):FlayingObject.__init__(self, canvas, random.randint(0, PlaneBigWar.screenWidth - img.width()), -img.height(),life, img, speed, imgs)# 敌人类型self.type = type# 敌人分数self.score = scoreclass Award(FlayingObject):"""奖励类,英雄机碰到此物获得奖励"""def __init__(self, canvas, type, life, code, img, speed, imgs: list):FlayingObject.__init__(self, canvas, random.randint(0, PlaneBigWar.screenWidth - img.width()), -img.height(),life, img, speed, imgs)# 奖励类型self.type = type# 奖品代码self.code = codeclass Bullet(FlayingObject):"""子弹类,英雄或敌人可发射用于攻击"""def __init__(self, canvas, x, y, life, img, speedX=0, speedY=-20):FlayingObject.__init__(self, canvas, x, y, life, img, [], speedY)self.speedX = speedXdef step(self):"""子弹移动方法"""self.y += self.speedself.x += self.speedXdef isOutBounds(self):"""子弹越界方法"""if self.x > PlaneBigWar.screenWidth or self.x < -self.width or self.y > PlaneBigWar.screenHeight or self.y < -self.height:self.isDelete = Trueclass Remind(FlayingObject):"""提示类,用于显示图片信息的类"""def __init__(self, canvas, x, y, img):FlayingObject.__init__(self, canvas, x, y, 1, img, [])class Text(FlayingObject):"""文本类,用于显示文字"""def __init__(self, canvas, x, y, size=30, fontStyle="simhei"):self.canvas = canvasself.label = QLabel(canvas)self.label.resize(75, 30)self.label.setMouseTracking(True)self.label.setStyleSheet("QLabel{color:rgba(245,245,245,1);""font-size:" + str(size) + "px;""font-weight:bold;""font-family:" + fontStyle + ";}")self.x = xself.y = yself.label.move(self.x, self.y)self.width = self.label.width()self.height = self.label.height()def paint(self, text):"""绘制文字方法"""self.label.setText(text)self.label.move(self.x, self.y)self.label.show()# 程序运行入口
if __name__ == "__main__":app = QApplication(sys.argv)pbw = PlaneBigWar()sys.exit(app.exec())

全网首份pyQt6飞机大战相关推荐

  1. 类似pyinstaller_全网首份Python打包工具Pyinstaller实战指南,如丝滑般体验

    写了个吊炸天的Python项目,把我和左手相处的时间都赔上了.但出于版权考虑,我不太想让使用方直接用我的代码,毕竟Python代码给出去,就真的收不回来了.学习Python中有不明白推荐加入交流群 号 ...

  2. 全网首份Nas-tool详细入门教程(包含一些问题的处理方法)

    前言: 何为Nas-tool 对于影音爱好者来说,一般观看影片需要这么几个步骤,寻找资源→使用BT工具(QBTR)进行下载→资源命名整理→硬链接→使用emby.jellyfin.plex等进行资源信息 ...

  3. 游戏角色坐标的保存间隔_使用C++编写飞机大战游戏【手把手教程】

    友情地提示本文较长,建议保存,慢慢学学.可以直接观看视频教程. C++干大事系列之游戏篇:Qt飞机大战​yun.itheima.com 1.项目简介 飞机大战是我们大家所熟知的一款小游戏,本教程就是教 ...

  4. Python自学第二十一天——飞机大战项目实践(四)

    作为新手自学Python的第二十一天,技术低微,希望可以通过这种方式督促自己学习. 个人学习环境:python3.9,PyCharm 2021.3.2 (Community Edition) 利用py ...

  5. Day18:C++飞机大战

    目录 一.思路与细节 二.具体实现: 公共头文件:common.h 计时器:timer.h 资源存放类: res.h 专门用于地图操作的类: graph.h 抽象出敌机.玩家(主机).子弹的共性类: ...

  6. 飞机大战html游戏全代码js、jquery操作

    飞机大战html游戏全代码 博主的话 运行图片 目录路径 飞机大战.html style.css 进行下一个游戏的开发! 注意事项 博主的话 当时博主只会html,css和原生JavaScript,假 ...

  7. 自己动手写游戏:飞机大战

    要说微信中最火爆的小游戏是哪款,可能既不是精心打造的3D大作,也不是<植物大战僵尸2>,而是微信5.0刚开启时的<飞机大战>. 就是这样一款铅笔手绘风格的简单到不能再简单的&q ...

  8. python语言实现飞机大战

    第一步:pygame的安装 同时按下win+R打开运行 Enter打开命令提示符,先输入pip -V查看pip版本号,主要是为了查看pip是否正常. 然后先尝试安装pygame测试下能否正常安装,输入 ...

  9. python飞机大战程序导入_Python飞机大战项目的准备 导入Pygame最全攻略~

    1.导入pygame 首先是导入pygame模块,下面介绍的是pycharm中导入 先建立一个项目 左上角File->Setting->project:飞机大战项目(你自己的文件名字)-& ...

最新文章

  1. [Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图
  2. C语言代码规范(编程规范)
  3. 长三角,也开始“东北化”了
  4. MS SQL数据库备份和恢复存储过程
  5. 东山再起?这将是锤子新手机?或搭配全键盘...
  6. mysql5.6安装配置教程_Centos6.8 Mysql5.6 安装配置教程
  7. Akka边学边写(3)-- ByteString介绍
  8. Mysql binlog入门
  9. 别再为了this发愁了:JS中的this机制
  10. Android Gradle配置资源前缀
  11. 一文看懂人工智能行业
  12. 3DMax 安装 超图 插件
  13. Python入门50个小程序
  14. PX4-固定翼的姿态控制
  15. android摄像头(camera)之buffer管理
  16. HTML基础课程笔记
  17. docker Starting MySQL database server mysqld fail解决办法
  18. Block Recurrent Transformer:结合了LSTM和Transformer优点的强大模型
  19. linux启动/停止/重启MySQL的命令
  20. 航空航天空气动力学高性能计算解决方案

热门文章

  1. 实习僧网站字体反爬破解思路及步骤分享
  2. rrpp协议如何修改_RRPP单环
  3. 盘点激光雷达技术在智能交通上的应用
  4. 如何在微信小程序里面退出小程序
  5. php 获取酷狗音乐真实地址
  6. 用JS实现猜数字游戏
  7. 华为官方模拟器eNSP_B500高速网盘下载——带CE系统
  8. ubuntu12.04 快捷键
  9. 知识图谱发展的难点 构建行业知识图谱的重要性
  10. 基于qiankun搭建ng-alain15微前端项目入门实践