【Python的魅力】:利用Pygame实现游戏坦克大战——含完整源码

文章目录

      • 一、游戏运行效果
      • 二、代码实现
        • 2.1 项目搭建
        • 2.2 加载我方坦克
        • 2.3 加载敌方坦克
        • 2.4 添加爆炸效果
        • 2.5 坦克大战之音效处理
      • 三、完整代码

一、游戏运行效果

二、代码实现

坦克大战游戏

2.1 项目搭建

本游戏主要分为两个对象,分别是我方坦克和敌方坦克。用户可以通过控制我方的坦克来摧毁敌方的坦克保护自己的“家”,把所有的敌方坦克消灭完达到胜利。敌方的坦克在初始的时候是默认 5 个的(这可以自己设置),当然,如果我方坦克被敌方坦克的子弹打中,游戏结束。从面向对象分析该项目有以下类组成:
在这里插入图片描述

  • 主类:主要包括开始游戏、结束游戏的功能。
class MainGame():def __init__(self):pass# 开始游戏def startGame(self):pass# 结束游戏def endGame(self):pass
  • 坦克类:主要包括坦克的创建、显示、移动及射击的功能。
class Tank():def __init__(self):pass# 移动def move(self):pass# 射击def shot(self):pass# 展示坦克的方法def displayTank(self):pass
  • 我方坦克类继承坦克类,主要包括创建、与敌方坦克的碰撞方法。
# 我方坦克
class MyTank(Tank):def __init__(self):pass
  • 敌方坦克类继承坦克类,主要包括创建、与我方坦克碰撞方法。
# 敌方坦克
class EnemyTank(Tank):def __init__(self):pass
  • 子弹类:主要包括子弹的创建、显示及移动的功能。
# 子弹类
class Bullet():def __init__(self):pass# 移动def move(self):pass# 展示子弹的方法def displayBullet(self):pass
  • 墙壁类:主要包括墙壁的创建、显示的功能。
class Wall():def __init__(self):pass# 展示墙壁的方法def displayWall(self):pass
  • 爆炸效果类:主要展示爆炸效果。
class Explode():def __init__(self):pass# 展示爆炸效果的方法def displayExplode(self):pass
  • 音效类:主要播放音乐。
class Music():def __init__(self):pass# 播放音乐def play(self):pass

显示游戏窗口

在游戏设计的前期,要先创建游戏的界面,也就是要为所设计的游戏创建一个窗口。
【示例】:显示游戏窗口

def startGame(self):# 加载主窗口# 初始化窗口pygame.display.init()# 设置窗口的大小及显示MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])# 设置窗口的标题pygame.display.set_caption('坦克大战1.03')while True:# 给窗口设置填充色MainGame.window.fill(BG_COLOR)pygame.display.update()
MainGame().startGame()

运行效果:
在这里插入图片描述

添加提示文字
在运行代码时会发现,创建的窗口没有任何提示。然而在实际中希望窗口提示敌方坦克的数量,因此,需要在现有窗口进行必须的改进,添加敌方坦克数量提示。

# 文字显示
def getTextSuface(self, text):pygame.font.init()  # 字体初始化font = pygame.font.SysFont('kaiti', 16)# 绘制文字信息textSurface = font.render(text, True, TEXT_COLOR)return textSurface

在这里插入图片描述

2.2 加载我方坦克

通过加载一张图片来表示游戏中的坦克,此坦克代表我方坦克,完善坦克类。

class Tank():# 添加距离左边left 距离上边topdef __init__(self, left, top):# 保存加载的图片self.images = {'U': pygame.image.load('img/p1tankU.gif'),'D': pygame.image.load('img/p1tankD.gif'),'L': pygame.image.load('img/p1tankL.gif'),'R': pygame.image.load('img/p1tankR.gif'),}# 方向self.direction = 'L'# 根据当前图片的方向获取图片 surfaceself.image = self.images[self.direction]# 根据图片获取区域self.rect = self.image.get_rect()# 设置区域的left 和topself.rect.left = leftself.rect.top = top

在这里插入图片描述
添加事件监听

上面创建的坦克还不能动,显示不是创建游戏的目的,因此,要给创建的坦克赋予“生命”。添加事件监听,控制上、下、左、右四个方向键,实现针对不同的键改变坦克的方向及移动功能,点击关闭退出游戏。

实现退出方法:

# 结束游戏def endGame(self):print('游戏结束')exit()  # 退出游戏

坦克类中添加移动开关属性,按下上、下、左、右四个方向键修改坦克的方向及开关状态,按下关闭键,调用关闭方法退出游戏。

# 获取程序期间所有事件(鼠标事件,键盘事件)def getEvent(self):# 获取所有事件eventList = pygame.event.get()# 遍历事件for event in eventList:# 判断按下的键是关闭还是键盘按下# 如果按的是退出,关闭窗口if event.type == pygame.QUIT:self.endGame()# 如果是键盘的按下if event.type == pygame.KEYDOWN:# 判断按下的是上、下、左、右if event.key == pygame.K_LEFT:print('按下左键,坦克向左移动')elif event.key == pygame.K_RIGHT:print('按下右键,坦克向右移动')elif event.key == pygame.K_UP:print('按下上键,坦克向上移动')elif event.key == pygame.K_DOWN:print('按下左键,坦克向下移动')

在这里插入图片描述
按下上、下、左、右之后控制台上会打印对应的信息。

随机生成敌方坦克

初始化敌方坦克,随机在不同坐标生成敌方坦克。

# 敌方坦克
class EnemyTank(Tank):def __init__(self, left, top, speed):super(EnemyTank, self).__init__(left, top)# 加载图片集self.images = {'U': pygame.image.load('img/enemy1U.gif'),'D': pygame.image.load('img/enemy1D.gif'),'L': pygame.image.load('img/enemy1L.gif'),'R': pygame.image.load('img/enemy1R.gif'),}# 随机生成方向self.direction = self.randDirection()self.image = self.images[self.direction]  # 根据方向获取图片self.rect = self.image.get_rect()  # 获取区域self.rect.left, self.rect.top = left, top  # 对left和top赋值self.speed = speed  # 速度self.flag = True  # 坦克移动开关self.step = 50  # 敌方坦克步数
2.3 加载敌方坦克

MainGame类中创建敌方坦克:

    def createEnemyTank(self):  # 初始化敌方坦克, 将敌方坦克添加到列表中top = 100for i in range(self.enemyTankCount):  # 生成指定敌方坦克数量left = random.randint(0, 600)speed = random.randint(1, 4)enemy = EnemyTank(left, top, speed)MainGame.enemyTankList.append(enemy)

在敌方坦克类中实现敌方坦克的随机移动

    def randMove(self):  # 坦克的随机方向移动if self.step < 0:  # 步数小于0, 随机改变方向self.direction = self.randDirection()self.step = 50  # 步数复位else:self.move()self.step -= 1

在开始游戏方法,加载敌方坦克

self.creatEnemyTank()

在这里插入图片描述
我方坦克发射子弹
在子弹类中初始化子弹,每个子弹在不同的方向发射会有不同的运动轨迹,每个子弹在坦克方向上的不同子弹发射的坐标也会有所不同。需要计算四个不同方向上的子弹发射坐标。

    def __init__(self, tank):self.image = pygame.image.load('img/enemymissile.gif')  # 图片加载self.direction = tank.direction  # 子弹的方向self.rect = self.image.get_rect()  # 获取区域if self.direction == 'U':  # 子弹的left和top与方向有关self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2self.rect.top = tank.rect.top - self.rect.heightelif self.direction == 'D':self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2self.rect.top = tank.rect.top + tank.rect.heightelif self.direction == 'L':self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2elif self.direction == 'R':self.rect.left = tank.rect.left + tank.rect.widthself.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2self.speed = 5   # 子弹的速度self.live = True  # 子弹的状态

敌方坦克随机发射子弹

def shot(self):num = random.randint(1,1000)if num <= 20:return Bullet(self)

我方法子弹与敌方坦克的碰撞检测
在游戏开发中,通常把显示图像的对象叫做精灵 Spire,精灵需要有两个属性 image 要
显示的图像,rect 图像要显示在屏幕的位置。
在 Pygame 框架中,使用 pygame. sprite 模块中的内置函数可以实现碰撞检测。代码如
下:

pygame.sprite.collide_rect(first, second) #返回布尔值

pygame.sprite.Sprite 是 pygame 精灵的基类,一般来说,总是需要写一个自己的精灵类继承 pygame.sprite.Sprite。让坦克类、子弹类都继承编写的精灵类。
在子弹类中增加我方子弹碰撞敌方坦克的方法,如果发生碰撞,修改我方子弹及敌方坦克 live 属性的状态值。

#新增我方子弹碰撞敌方坦克的方法
def hitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if pygame.sprite.collide_rect(eTank,self):self.live = FalseeTank.live = False
2.4 添加爆炸效果

在我方子弹碰撞敌方坦克的方法中,如果检测到碰撞,产生爆炸类,并将爆炸效果添加到爆炸列表。

#新增我方子弹碰撞敌方坦克的方法
def hitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if pygame.sprite.collide_rect(eTank,self):#产生一个爆炸效果explode = Explode(eTank)#将爆炸效果加入到爆炸效果列表MainGame.Explode_list.append(explode)self.live = FalseeTank.live = False

我方坦克的消亡
子弹类中,新增敌方子弹与我方坦克的碰撞。如果发生碰撞,修改敌方子弹、我方坦克的状态及产生爆炸效果。
添加敌方子弹到窗口中时候,如果子弹还活着,显示子弹、调用子弹移动并判断敌方子弹是否与我方坦克发生碰撞。

    def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示for enemyBullet in MainGame.enemyBulletList:if enemyBullet.live:enemyBullet.displayBullet()enemyBullet.move()enemyBullet.enemyBullet_hit_myTank()enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞else:MainGame.enemyBulletList.remove(enemyBullet)

子弹不能穿墙
子弹类中新增方法,子弹与墙壁的碰撞,如果子弹与墙壁碰撞,修改子弹的状态,墙壁的生命值减少,如果墙壁的生命值小于等于零时候修改墙壁的状态。

坦克不能穿墙
如果坦克与墙壁碰撞,则坦克不能继续移动,需要修改坦克的坐标为移动之前的。因此在坦克类中新增属性 oldLeft、oldTop 记录移动之前的坐标,新增 stay()、hitWalls()方法。

    def hitWall(self):for wall in MainGame.WallList:  # 循环遍历墙壁列表if pygame.sprite.collide_rect(self, wall):  # 检测子弹是否碰撞墙壁self.live = False  # 修改子弹状态wall.hp -= 1  # 碰撞后墙壁生命值减少if wall.hp <= 0:wall.live = False

双方坦克之间的碰撞检测
如果我方坦克碰撞到敌方坦克,则我方坦克再不能继续移动。同理如果敌方坦克碰撞到
我方坦克也不能继续移动。
在我方坦克类中新增我方坦克与敌方坦克碰撞的方法。

class MyTank(Tank):def __init__(self, left, top):super(MyTank, self).__init__(left, top)def myTank_hit_enemyTank(self):for enemyTank in MainGame.enemyTankList:if pygame.sprite.collide_rect(self, enemyTank):self.stay()

我方坦克移动后,调用是否与敌方坦克发生碰撞。在敌方坦克类中,新增敌方坦克碰撞我方坦克的方法。敌方坦克添加到窗口时候,调用是否与我方坦克碰撞。

    def blitEnemyBullet(self):  # 循环敌方子弹列表, 并展示for enemyBullet in MainGame.enemyBulletList:if enemyBullet.live:enemyBullet.displayBullet()enemyBullet.move()enemyBullet.enemyBullet_hit_myTank()enemyBullet.hitWall()  # 检测敌方坦克子弹是否碰撞else:MainGame.enemyBulletList.remove(enemyBullet)
2.5 坦克大战之音效处理

music 是 pygame 中控制流音频的 pygame 模块,音乐模块与 pygame.mixer 紧密相连,pygame.mixer 是一个用来处理声音的模块,其含义为“混音器”。游戏中对声音的处理一般包括制造声音和播放声音两部分。使用 pygame.mixer.music.load()加载一个播放音乐的文件,pygame.mixer.music.play() 开始播放音乐流。

初始化音效类

class Music():def __init__(self, filename):self.filename = filenamepygame.mixer.init()pygame.mixer.music.load(self.filename)  # 加载音乐# 音乐播放def play(self):pygame.mixer.music.play()
music.play()

创建坦克时,添加音效和在我方坦克发射子弹时,添加音效。

三、完整代码

注意因为代码过长,且含音频和图片,不方便复制,可使用下方码云链接直接下载就好啦
https://gitee.com/bow-elongation/tank-battle.git
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4818.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

告别盲目投放,Xinstall让App广告效果一目了然

在移动互联网时代&#xff0c;App广告的投放已经成为企业营销的重要手段。然而&#xff0c;广告主在投放广告后&#xff0c;如何有效追踪广告效果、衡量广告ROI&#xff0c;一直是困扰他们的难题。今天&#xff0c;我们就来聊聊Xinstall这家国内专业的App全渠道统计服务商&…

计算一个结构的平方

在行列可自由变换的平面上计算3a1*3a1 得到的结构应该有9个点&#xff0c;并且点的分布有3a1的特征 这个9点结构可以化简成 1 1 1 1 1 1 1 1 1 显然这个结构可以再次平方&#xff0c;得到 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 …

python:reportlab 生成pdf:基本用法。

1.首先&#xff0c;打开cmd&#xff0c;安装reportlab pip install -i https://pypi.tuna.tsinghua.edu.cn/simple reportlab #从清华镜像安装更快 然后就可以使用其基本用法。 from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvasdef genera…

小程序评分/关键词/UV优化助力小程序登顶

随着小程序市场的日益繁荣&#xff0c;小程序搜索排名优化成为了众多开发者关注的焦点。小程序搜索排名被很多因素影响着&#xff0c;关键词、评分还有uv&#xff08;授权&#xff09;等。在本文小柚和各位老板分享如何有效优化小程序搜索排名的经验。 一、关键词策略 关键词是…

Python | Leetcode Python题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution:def canJump(self, nums: List[int]) -> bool:n, rightmost len(nums), 0for i in range(n):if i < rightmost:rightmost max(rightmost, i nums[i])if rightmost > n - 1:return Truereturn False

Web3的可持续性:构建环境友好的去中心化系统

引言 随着全球对可持续发展和环境问题的日益关注&#xff0c;Web3技术作为一种新型的互联网模式&#xff0c;也开始受到社区和开发者的关注。但很少有人关注到Web3对环境可持续性的潜在影响。本文将探讨Web3如何构建一个环境友好的去中心化系统&#xff0c;以及这如何促进一个…

偏微分方程算法之五点菱形差分法

目录 一、研究目标 二、理论推导 三、算例实现 四、结论 一、研究目标 上个专栏我们介绍了双曲型偏微分方程的主要算法及实现。从今天开始&#xff0c;我们在新的专栏介绍另一种形式偏微分方程-椭圆型的解法。 研究目标选取经典的二维椭圆型方程&#xff08;也称泊松Poisso…

马斯克突击访华;谷歌 Python 基础团队全数被裁;丨 RTE 开发者日报 Vol.195

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

python基础学习之写入csv文件

前言 在Python编程中&#xff0c;经常会遇到要将数据存到csv文件中&#xff0c;今天来详细讲一下。 一.功能目的 将以下数据存到csv文件中。 data [ {name: Alice, age: 25, city: New York}, {name: Bob, age: 30, city: Los Angeles}, {name: Charlie, age: 35, city:…

DS:单链表的实现

欢迎各位来到 Harper.Lee 的编程学习小世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客 我将在这里分享我的学习过程等心得 创作不易&#xff0c;码字不易&#xff0c;兄弟们养成先赞后看的好习惯哦&#xff01; 想一同进步的uu&#xff0c;可以来后来找我哦&…

Selenium IDE 常见错误笔记

错误1&#xff1a;Failed:Exceeded waiting time for new window to appear 2000ms 这个错误通常出现在第一次运行时&#xff0c;有两个原因&#xff1a; Firefox阻止了弹出式窗口&#xff0c;在浏览器设置里允许这个操作即可。 有些网站设置了反扒机制&#xff0c;脚本运行…

解决Blender导出FBX文件到Unity坐标轴错误的问题

发现Blender的模型导入到Unity里面有问题,简单研究了下发现是坐标系不同,Unity使用的是左手坐标系,Blender使用的是右手坐标系 。 下面直接将如何解决 首先忽略Blender的右手坐标系以及Z轴朝上的事&#xff0c;依照unity坐标系情况修改模型物体的旋转&#xff0c;以Blender猴…

算法工程师——算法岗的分类及要求汇总

算法岗工程师 根据 Talent Seer 人才报告显示,全球 AI 从业者总人数约有 30 万,还是供不应求,其中 AI 技术专家(具有相关领域博士学位及 3 年以上工作经验的)约有 3.65 万。 简介 对于计算机专业的毕业生而言,算法岗基本上就是 「高薪」 的代名词。 在当今 IT 行业,算…

【城市】2023深圳市定居与生活相关政策(含租房、租车)

【城市】2023深圳市定居与生活相关政策&#xff08;含租房、租车&#xff09; 文章目录 一、户籍身份1、深圳市居住登记凭证、居住证&#xff08;点击就送&#xff09;2、深圳落户&#xff08;点击就送1&#xff09; 二、人才补贴人才引进补贴&#xff08;含应届生&#xff09;…

vue3左树的全选和反选

<el-input v-model"filterText" placeholder"" style"width: 48%"/><el-button type"primary" click"handleSearch" class"ml-2">查找</el-button><el-radio-group v-model"form.choic…

学习笔记:能量信号与功率信号(一)

目录 一、能量信号&#xff08;Energy Signal&#xff09; 二、功率信号&#xff08;Power Signal&#xff09; 三、信号关系图 四、总结 能量信号和功率信号是信号分析中两个基本的概念&#xff0c;它们主要用来描述信号在时间域中能量分布的特性&#xff0c;对于理解信号…

Faststone Capture:一触即发的效率革命【AI写作】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

苹果发布开源模型;盘古大模型5.0将亮相;英伟达将收购 Run:ai

苹果首次发布开源语言模型 近期&#xff0c;苹果在 Hugging Face 发布了 OpenELM 系列模型。OpenELM 的关键创新是逐层扩展策略&#xff0c;该策略可在 transformer 模型的每一层中有效地分配参数&#xff0c;从而提高准确性。 与具有统一参数分配的传统语言模型不同&#xff…

【免费Java系列】给大家出一些JavaSE基础第八天的内容案例 , 让大家更好的理解与掌握

String字符串 案例一 求取字符串的长度 public class Main {public static void main(String[] args) {String str "Hello World";String substring str.substring(6);System.out.println("截取后的字符串为&#xff1a;" substring);} }输出结果&…

windows下pysqlite3安装

pysqlite3 下载地址&#xff1a;SQLite Download Page windows下安装 首先在官网中下载以下文件 sqlite-amalgamation-3450300.zip #源码文件 sqlite-dll-win-x64-3450300.zip # 根据系统选择32或者64&#xff0c;可通过查看我的电脑属性中查看 sqlite-tools-win-x64-345…