坦克大战小游戏的实现

1 设计任务
1.1设计目的
运用所学Python知识,完成坦克大战小游戏,通过实践加强对所学知识的理解和巩固。
1.2设计内容
坦克大战小游戏
1.3设计指标或者要求
坦克可以自由的移动和进行射击,敌方坦克消灭完即为胜利,已方坦克被击毁或者己方大本营被摧毁,即为游戏失败。
2 设计过程
游戏基本规则:按上下左右键移动我方坦克,按空格键进行发射子弹,击中坦克,坦克爆炸消失。若我方坦克被子弹击中或撞上,我方坦克死亡按ESC键可以重生。
敌方坦克功能:白色敌方坦克为一般坦克。白色较小敌方坦克速度快,射击子弹频繁。绿色坦克为我方坦克。
地图:白色“铁”墙壁,子弹不能穿过,坦克不能穿过。黑色“地图”子弹和坦克均可以穿过此地图。
程序包含六个类:主逻辑类(MainGame)、坦克类(Tank1包含敌方坦克类(EnemyTank)和我方坦克类(myTank))、子弹类(Bullet)、 爆炸效果类(Explode),墙壁类(Wall)、音效类(Music)。
2.1 开发环境
1、开发工具:pycharm 2020
2、开发环境:python 3.7.9
3、第三方模块:pygame
在联网的情况下,打开终端,输入pip install pygame,即可安装成功。
2.2程序基本流程
1、运行:run “Main_Game.py”,进入初始化界面
2、初始化:显示窗口大小及内容、加载图片和背景音乐,开始游戏。
3、游戏控件:玩家可以通过键盘和空格键来完成移动坦克,射击子弹。还可通过按ESC键重生
4、游戏结束:关闭窗口
2.3程序界面的展示
2.3.1开始游戏界面

2.3.2结束游戏界面

3各功能模块代码实现
模块导入:import random
import pygame,time
图片素材文件存入项目下的img文件夹

3.1主逻辑类(MainGame)
主要是游戏窗口的创建和调用其他类中方法的实现,并定义getEvent方法来获取程序期间的所有事件(鼠标事件,键盘事件),通过键盘操作不同的按键来执行不同的操作。
class MainGame():# 显示主窗口window = NoneSCREEN_height = 700SCREEN_width = 1000#创建我方坦克Tank_P1=None#存储所有敌方坦克EnemyTank_list=[]#要创建的地方坦克的数量EnemyTank_count=5#存储我方子弹的列表Bullet_list=[]#存储敌方坦克列表Enemy_Bullet_list=[]#爆炸效果列表Explode_list=[]#创建墙壁列表Wall_list=[]#创建我方老鹰Glede_P1=None#我方坦克的生命值MyT_liveCount=5# 开始游戏方法def startGame(self):pygame.display.init()#创建窗口加载窗口(借鉴官方文档)MainGame.window = pygame.display.set_mode([MainGame.SCREEN_width, MainGame.SCREEN_height])#创建我方坦克self.CreatMyTank()#创建敌方坦克self.creatEnemyTank()#创建墙壁self.creatWall()#初始化glede方法MainGame.Glede_P1=glede()# 设置一下游戏标题pygame.display.set_caption("坦克大战v1.0")# 让窗口持续刷新while True:# 给窗口一个刷新的颜色MainGame.window.fill(COLOR_BLACK)#在循环中持续完成事件的获取self.getEvent()#将绘制文字的小画布黏贴到窗口中MainGame.window.blit(self.getTextSurface("剩余敌方坦克%d辆"%len(MainGame.EnemyTank_list)),(5,5))if len(MainGame.EnemyTank_list)==0:MainGame.window.blit(self.getTextSurface2("你赢了!"), (420, 240))if MainGame.Glede_P1 and MainGame.Glede_P1.live==True:# 将我方的老鹰展示到窗口中self.Glede_P1.displayGlede()else:del MainGame.Glede_P1MainGame.Glede_P1 = None# 展示结束图片效果self.displayEndGame()if MainGame.Tank_P1 and MainGame.Tank_P1.live==True:# 将我方坦克加入到窗口中MainGame.Tank_P1.displayTank()else:del MainGame.Tank_P1MainGame.Tank_P1=Noneif MainGame.Glede_P1 and MainGame.Glede_P1.live and MainGame.MyT_liveCount>0 and len(MainGame.EnemyTank_list)>0:MainGame.window.blit(self.getTextSurface1("剩余生命数%d,按ESC键重生!" %MainGame.MyT_liveCount ),(330, 250))else:# 展示结束图片效果self.displayEndGame()
#判断事件类型是否为按键按下,如果是,继续判断是哪一个按键,来进行对应的处理     if event.type==pygame.KEYDOWN:if MainGame.Tank_P1 and MainGame.Tank_P1.live and MainGame.Glede_P1 and MainGame.Glede_P1.live:# 具体按哪一个键的处理if event.key == pygame.K_LEFT:print("坦克向左调头移动")# 修改坦克方向MainGame.Tank_P1.direction = 'L'# 完成移动操作(调用坦克移动方法)MainGame.Tank_P1.stop = False【省略其他方向移动的代码】elif event.key == pygame.K_SPACE:print("坦克发射子弹")if len(MainGame.Bullet_list) < 3:# 产生一颗子弹m = Bullet(MainGame.Tank_P1)# 将子弹加入子弹列表MainGame.Bullet_list.append(m)# 播放音乐# music = Music('img/fire.wav')# music.play()else:print("子弹数量不足")# 松开按键时坦克停止移动if event.type == pygame.KEYUP:#松开的是方向键才停止移动if event.key==pygame.K_LEFT or event.key==pygame.K_UP or event.key==pygame.K_DOWN or event.key==pygame.K_RIGHT:if MainGame.Tank_P1 and MainGame.Tank_P1.live:# 修改坦克的状态MainGame.Tank_P1.stop = True#左上角文字绘制功能def getTextSurface(self,text):#初始化字体模块pygame.font.init()#选中一个合适的字体font=pygame.font.SysFont('kaiti',18)#使用对应的字符完成相关内容的绘制textSurface=font.render(text,True,COLOR_RED)return textSurfacedef getTextSurface1(self, text):# 初始化字体模块pygame.font.init()# 选中一个合适的字体font = pygame.font.SysFont('kaiti', 28)# 使用对应的字符完成相关内容的绘制textSurface1 = font.render(text, True, COLOR_BLUE)return textSurface1def getTextSurface2(self, text):# 初始化字体模块pygame.font.init()# 选中一个合适的字体font = pygame.font.SysFont('kaiti', 35)# 使用对应的字符完成相关内容的绘制textSurface1 = font.render(text, True, COLOR_RED)return textSurface1# 结束游戏方法def endGame(self):print("Game over!!!")# 结束python解释器exit()#展示结束游戏图片def displayEndGame(self):self.image1=pygame.image.load("img/GameOver.jpg")#图片所在区域self.rect=self.image1.get_rect()self.rect.left=210self.rect.top=110MainGame.window.blit(self.image1, self.rect)3.2坦克类(Tank1,myTank,EnemyTank)
class Tank1(BaseItem):def __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='U'self.image=self.images[self.direction]#坦克所在区域self.rect=self.image.get_rect()#指定坦克初始化位置 分别距X,Y轴的位置self.rect.left=leftself.rect.top=top#速度属性self.speed=5#坦克的移动开关self.stop=True#新增步数属性self.step=15#新增属性live用来记录坦克是否活着self.live=True#新增属性:用来记录坦克移动之前的坐标(用于坐标还原时使用)self.oldLeft=self.rect.leftself.oldTop=self.rect.top#坦克移动的方法def move(self):self.oldLeft = self.rect.leftself.oldTop = self.rect.topif self.direction=='L':if self.rect.left>0:self.rect.left-=self.speed【省略其他方向移动的代码】def stay(self):self.rect.left=self.oldLeftself.rect.top=self.oldTop#新增碰撞墙壁的方法def hitWalls(self):for wall in MainGame.Wall_list:if pygame.sprite.collide_rect(wall,self):self.stay()#射击方法def shot(self):return Bullet(self)#展示展示 (将坦克这个surface绘制到窗口中  blit())def displayTank(self):#1.重新设置坦克的图片self.image=self.images[self.direction]#2.将坦克加入到窗口中MainGame.window.blit(self.image, self.rect)class MyTank(Tank1):def __init__(self,left,top):super(MyTank, self).__init__(left,top)#新增主动碰撞到敌方坦克的方法def hitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if pygame.sprite.collide_rect(eTank,self):self.stay()class EnemyTank(Tank1):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()# 指定坦克初始化位置 分别距X,Y轴的位置self.rect.left = leftself.rect.top = top# 速度属性self.speed = speed# 坦克的移动开关self.stop = True#步数属性self.step=35#判断方向def randDirection(self):num=random.randint(1,4)if num == 1:return 'U'elif num == 2:return 'D'elif num == 3:return 'L'elif num == 4:return 'R'#随机移动def randMove(self):if self.step <= 0:self.direction = self.randDirection()self.step = 35else:self.move()self.step -= 1#展示敌方坦克def displayEnemyTank(self):super().displayTank()#敌方坦克发射子弹的概率def shot(self):num=random.randint(0,1000)if num<=20:return Bullet(self)#敌方坦克碰到我方坦克时让其停下来def hitMyTank(self):if MainGame.Tank_P1 and MainGame.Tank_P1.live:if pygame.sprite.collide_rect(selfMainGame.Tank_P1):self.stay()3.3子弹类(Bullet)
class Bullet(BaseItem):def __init__(self,tank):#子弹速度属性self.speed=7#子弹是否活着self.live=True#图片self.image=pygame.image.load("img/enemymissile.gif")#方向self.direction=tank.direction#位置self.rect=self.image.get_rect()#子弹的移动方法def BulletMove(self):跟坦克移动方法类似#展示子弹的方法def dispalyBullet(self):MainGame.window.blit(self.image,self.rect)#我方子弹碰撞敌方坦克的方法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 hitMyTank(self):if pygame.sprite.collide_rect(self,MainGame.Tank_P1):#产生爆炸效果,并加入到爆炸效果列表中explode=Explode(MainGame.Tank_P1)MainGame.Explode_list.append(explode)#修改子弹状态self.live=False#修改我方坦克状态MainGame.Tank_P1.live=False#子弹与墙壁的碰撞def hitWalls(self):for wall in MainGame.Wall_list:#两个精灵之间的碰撞检测,使用矩形。if pygame.sprite.collide_rect(wall,self):#修改子弹的live属性self.live=Falsewall.hp-=1if wall.hp<=0:wall.live=False3.4爆炸效果类(Explode)
class Explode():def __init__(self,tank):self.rect=tank.rectself.step=0self.live=Trueself.images=[pygame.image.load('img/blast0.gif'),pygame.image.load('img/blast1.gif'),pygame.image.load('img/blast2.gif'),pygame.image.load('img/blast3.gif'),pygame.image.load('img/blast4.gif')]self.image=self.images[self.step]#展示爆炸效果def displayExplode(self):if self.step<len(self.images):MainGame.window.blit(self.image,self.rect)self.step+=1else:self.live=Falseself.step=03.5墙壁类(Wall)
class Wall():def __init__(self,left,top):#导入墙壁图像文件self.image=pygame.image.load('img/steels.gif')self.rect=self.image.get_rect()#图像在窗口中显示的位置self.rect.left=leftself.rect.top=top#用来判断是否在窗口中显示self.live=True#用来记录墙壁的生命值self.hp=3#展示墙壁的方法def displayWall(self):MainGame.window.blit(self.image,self.rect)3.6音效类(Music)
class Music():def __init__(self, fileName):self.fileName = fileName# 初始化混合器pygame.mixer.init()#导入音效文件pygame.mixer.music.load(self.fileName)# 开始播放音乐def play(self):pygame.mixer.music.load(self.fileName)

4 软件设计过程中遇到的问题以及解决办法
4.1我方子弹发射数量问题
如果只定义一个子弹属性的话,则玩来玩去只是一枚子弹,我们这时需要用容器。
在MainGame类属性中添加一个Bullet_list=[]用于存储子弹列表,然后在MainGame中的blitBullet方法中将其遍历,并将子弹加入到窗口中。
当然,我们也要在blitmyTank方法中遍历MainGame.myTank_list列表,并将子弹存储在我方坦克列表,其代码为MainGame.my_Bullet_list.append(eBullet),即可发射多枚子弹,但我们就游戏体验来说最好将子弹发射数量设置为每次只能发送3颗,以维持游戏的平衡。

4.2坦克移动问题
先用pygame.event.get()方法获取到程序期间的所有事件,然后赋值给eventList,遍历这个列表,对不同的键盘按键操作进行不同的处理。当按下上下左右键时,调用不同的方法,根据按键的不同,展示不同方向的坦克,当持续按一个方向键时,让坦克朝着这个方向按给定的速度进行平移,以达到坦克移动方法的实现。

4.3我方子弹与敌方坦克碰撞问题
我方子弹碰撞敌方坦克时,我方子弹和敌方坦克应均处于死亡(属性live=False)状态,要实现这个效果,即要调用pygame模块里的精灵类sprite,首先创建一个类BaseItem使其继承于精灵类,然后让Tank1类和Bullet类继承于BaseItem类,并用模块中的pygame.sprite.collide_rect方法检测两个精灵的碰撞,如果我方子弹,碰撞到了敌方坦克,即将敌方坦克的live属性改成False,即敌方坦克便不会显示在窗口中。

这里是引用
程序源码下载链接:https://download.csdn.net/download/qq_41787812/19967878

坦克大战小游戏的实现相关推荐

  1. Java实现的经典坦克大战小游戏

    Java实现的经典坦克大战小游戏 先看一下游戏结构: 有点多,没有耐心的可以不用看,这里先给出链接吧! 云链接:经典坦克大战 提取码:s9ai 这里就不介绍功能了,贴了一张游戏运行的截图,具体的功能自 ...

  2. 【JAVA程序设计】基于JAVA的坦克大战小游戏--入门级小游戏

    基于JAVA的坦克大战小游戏--入门级小游戏 零.项目获取 一.项目简介 二.开发环境 三.游戏玩法 四.运行截图 零.项目获取 获取方式(点击下载):是云猿实战 项目经过多人测试运行,可以确保100 ...

  3. html实现经典坦克大战小游戏

    文章目录 1.设计来源 1.1 游戏主界面 1.2 游戏界面 2.效果和源码 2.1 动态效果 2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/w ...

  4. C++实用编程——坦克大战小游戏

    C++实用编程--坦克大战小游戏 Warning: 转载类 原文地址:*HTML https://yq.aliyun.com/articles/683666 改变速度的玩意坏了 我们直接看代码吧,适于 ...

  5. 【180930】坦克大战小游戏源码

    坦克大战小游戏源码程序实现了小霸王游戏机上坦克大战的功能,主要功能是开火.移动.3种不同的敌方坦克.用户自制地图等,缺点是有些小细节还处理的不好,感觉画面不够好,还没实现自动的下一关功能(主要是嫌做默 ...

  6. canvas+js实现简单的坦克大战小游戏

    使用canvas和js实现经典的坦克大战并不难,坦克和炮弹的绘制可以使用canvas的里API画出,而坦克的移动和炮弹的发射可以依赖于键盘事件和定时器来实现. 在这里我要实现的坦克大战是双人模式,有木 ...

  7. 坦克大战小游戏关键技术总结

    这两天参照韩顺平的坦克大战游戏并在其基础上初步完善成一个小的页面游戏,最终js代码大约570行,html代码200多行,具体可参见https://github.com/Mrkaiyang/Art/tr ...

  8. 用HTML语言写一段坦克大战小游戏

    好的,我会尽力帮助你. 你可以使用 HTML 写一个坦克大战的小游戏,代码大概长这样: <!-- 这是 HTML 代码 --> <html><head><ti ...

  9. python3小游戏代码教程_Python3制作仿“经典90坦克大战”小游戏|python3教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 本文转载至知乎ID:Charles(白露未晞)知乎个人专栏 下载W3Cschool手机App,0基础随时随 ...

  10. Python3制作仿“经典90坦克大战”小游戏

    导语 本期我们将制作一个仿"经典90坦克大战"的小游戏.啊,想起来上一次玩这个游戏的时候才小学呢.T_T真是一款暴露年龄的游戏. 算了废话不多说,让我们愉快地开始吧~ 相关文件 百 ...

最新文章

  1. 超强TP-Link!北大清华联手开设通用AI实验班,朱松纯领衔
  2. Codeforces 1188E Problem from Red Panda (计数)
  3. java 银行项目对于金额的面试题_2019年面试题小结
  4. java获取文件名方法,利用Java获取文件名、类名、方法名和行号的方法小结
  5. 批量执行命令(SSH)
  6. c语言字符串算法判断实验原理,C语言第二次实验报告
  7. chrome postman插件_收集了一些Chrome插件神器,助你快速成为老司机
  8. 《大数据》2015年第3期“网络大数据专题”——网络表示学习(下)
  9. 终于把Redis场景设计搞清楚了,需要掌握的都在这了
  10. SQL Server索引简介:SQL Server索引级别1
  11. 原来Android还可以这样通过反射,获取jar包属性及方法
  12. 光机电一体化实训考核装置
  13. python pip源配置,pip配置文件存放位置的方法
  14. Busybox 1.17.4 编译及错误解决方案
  15. linux中help的用法
  16. 235款鼠标样式免费下载
  17. 二维离散沃尔什变换及matlab实现
  18. 建立一个复数类Complex,其私有数据成员mX和mY表示复数的实部和虚部,构造函数Complex用于对复数的实部和虚部初始化
  19. Docker实战-部署GPE微服务的监控体系
  20. Opencv连通域检测

热门文章

  1. 74HC138 芯片(38译码器)和74HC245 芯片(处理段码)
  2. oracle查看归档日志是否开启,Oracle 开启归档日志以及关闭归档日志
  3. 【java】面向程序员的 10 大 Java 书籍 — 历久弥新
  4. Linux命令大全(常用的命令解析)
  5. KindEditor上传图片及使用
  6. 乐忧商城项目总结-5
  7. P2P终结者和反P2P终结者如何使用
  8. 如何提高计算机软件的性能,如何提高计算机性能?
  9. 计算机四级网络工程师需要看哪些书,计算机四级网络工程师考试教材
  10. 毕设-基于SSM仓库管理系统