侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python实现坦克大战游戏 附详细注释

Python  /  管理员 发布于 7年前   184

本文实例为大家分享了python实现坦克大战的具体代码,供大家参考,具体内容如下

#功能实现游戏主窗口import pygame,time,random#导入模块_display = pygame.display#赋值给一个变量 调用时方便color_red = pygame.Color(255,0,0)#同上  vclass MainGame(object): screen_width = 900#游戏界面宽度 screen_height = 550#界面的高度 Tank_p1 = None#坦克对象 window = None #窗口对象 EnemyTank_list = []# 存储所有敌方坦克 EnemTank_count = 10# 要创建的敌方坦克的数量 Bullet_list = [] #创建我方子弹列表 EnemyTank_bullet_list = [] Explode_list= [] wall_list = [] def startGame(self):  pygame.display.init()#初始化游戏模块的显示  MainGame.window = _display.set_mode([MainGame.screen_width,MainGame.screen_height])#生成并加载游戏窗口、\  #pygame.display模块及set_mode方法和pygame相关方法调用设置  # 见<<https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode>> UC浏览器实现自动翻译  pygame.display.set_caption("坦克大战v1.0")#s设置游戏标题  self.creatEnemyTank()#类中调用初始敌方坦克方法  self.creatMyTank()#创建我方坦克  self.creatWalls()#创建障碍物   while True:#无限循环 所有行为方法都要无限制的显示   MainGame.window.fill(pygame.Color(0,0,0))#窗口颜色设置 Window在开始方法已设置为游戏窗口   self.getEvent()#死循环中 获取事件的值 对其进行相应处理   MainGame.window.blit(self.drawText("剩余敌方数量%d" %len(MainGame.EnemyTank_list)),(7, 7))#循环游戏窗口加载文本 bilt方法在页面写入另一个    self.blitWalls()   if MainGame.Tank_p1 and MainGame.Tank_p1.alive:    MainGame.Tank_p1.displayTank()#循环调用生成的坦克对象(显示)方法     self.blitEnemyTank()# 此类中用self 循环展示敌方坦克    if MainGame.Tank_p1 and not MainGame.Tank_p1.stop:    MainGame.Tank_p1.move()# 移动    MainGame.Tank_p1.hitWall()#撞击墙壁    MainGame.Tank_p1.hitEnemyTank()#撞击敌方坦克方法   self.blitEnemyBullet()#显示敌方坦克子弹   self.blitBullet()#显示炮弹   self.blitExplode()#显示爆炸效果   time.sleep(0.02)   _display.update()#获取更新   #将带有文字的surface 绘制到窗口中 循环  # 创建敌方坦克  def creatEnemyTank(self):#创建敌方坦克   top = 100   for i in range(MainGame.EnemTank_count):#MainGame.EnemTank_count=5 五次循环创建敌方坦克   speed = random.randint(3, 6) # 随机模块 random.randint   # 每次都随机生成一个left值   left = random.randint(1, 7)   eTank = EnemyTank(left * 100, top, speed)#生成敌方坦克类对象 传入参数 left为随机   MainGame.EnemyTank_list.append(eTank)#将创建的每一个敌方坦克添加到列表  # 将坦克加入到窗口中 def creatMyTank(self):  MainGame.Tank_p1 = MyTank(400, 480) # 生成一个坦克类的实例对象  music = Music("img/start.wav")  music.play() def creatWalls(self):  for i in range(1,10):   wall = Wall(60*i,250)   MainGame.wall_list.append(wall) def blitWalls(self):  for wall in MainGame.wall_list:   if wall.live == True:    wall.displayWall()   else:    MainGame.wall_list.remove(wall) def blitEnemyTank(self):#显示敌方坦克 若出现坦克图片重叠也是符合逻辑  for eTank in MainGame.EnemyTank_list:   if eTank.live :    eTank.displayTank()#将列表中每一个进行显示 eTank为敌方坦克类对象 调用父类Tank类中显示方法    eTank.randMove()    eTank.hitWall()    eTank.hitMyTank()    ebullet = eTank.shot()     if ebullet:#如果不为空     MainGame.EnemyTank_bullet_list.append(ebullet)   else:    MainGame.EnemyTank_list.remove(eTank) def blitEnemyBullet(self):#将敌方坦克加入到窗口中  for ebullet in MainGame.EnemyTank_bullet_list:   if ebullet.alive:    ebullet.display_bullet()    ebullet.bulletMove()    ebullet.hitWalls()    if MainGame.Tank_p1.alive:     ebullet.hitMyTank()   else:    MainGame.EnemyTank_bullet_list.remove(ebullet) def blitBullet(self):#显示子弹  for bullet in MainGame.Bullet_list:#事件中获的子弹的列表进行遍历 类似显示坦克方法 逐个展示   if bullet.alive:#Bullet类中设置的标签 来判断子弹的存活 True为生 根据炮弹移动方法bulletmove()中所加限制条件    bullet.display_bullet()#调用列表中子弹对象的显示方法    bullet.bulletMove()#子弹的移动    bullet.hitEnemyTank()#调用与敌方坦克的碰撞检测方法    bullet.hitWalls()#d调用子弹碰撞墙壁   else:     MainGame.Bullet_list.remove(bullet)#如果为False bulletmove()中触碰墙壁就是False 就从列表删除 循环执行 def blitExplode(self):  for explode in MainGame.Explode_list:   if explode.live:    explode.display_explode()    music = Music("img/blast.wav")    music.play()   else:    MainGame.Explode_list.remove(explode) def drawText(self,content):#文本 写入游戏窗口  pygame.font.init()#初始化字体  font = pygame.font.SysFont("kaiti",18)#创建字体对象  text_sf = font.render(content,True,color_red)#字体样式对象  return text_sf #返回内容的surface def getEvent(self):#获取所有事件  eventlist = pygame.event.get()#所有事件列表  for event in eventlist:#遍历每一个事件进行判断 键盘输入的字符   #type属性   if event.type == pygame.QUIT:#如果是QUIT(就是点击窗口的退出按钮 叉号)    print("退出游戏")    self.gameOver()#退出方法   if event.type == pygame.KEYUP:#如果键盘按钮抬起 并且是上下左右键    if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP\    or event.key == pygame.K_DOWN:     if MainGame.Tank_p1 and MainGame.Tank_p1.alive:      MainGame.Tank_p1.stop = True#stop为True 按钮抬起就停止 start方法中的开关 实现坦克按住按钮持续移动    if event.type == pygame.KEYDOWN:#如果事件的类型为按下按键进行如下判断    if event.key == pygame.K_ESCAPE :     self.creatMyTank()    if MainGame.Tank_p1 and MainGame.Tank_p1.alive:     if event.key == pygame.K_LEFT:#如果为左方向键 如下为同一类型      print("向左移动")      MainGame.Tank_p1.direction = "L"#设置坦克方向进行判断向左就是L,      # 并设置游戏窗口的界限 还可以利用方向作为字典的键获取坦克图片 坦克的移动方向      #就是加载不同方向的坦克图片 呈现出移动的效果      MainGame.Tank_p1.stop = False#坦克移动的开关 循环使用 False为移动     if event.key == pygame.K_RIGHT:      print("向右移动")      MainGame.Tank_p1.direction = "R"      MainGame.Tank_p1.stop = False     if event.key ==pygame.K_UP:      print("向上移动")      MainGame.Tank_p1.direction = "U"      MainGame.Tank_p1.stop = False     if event.key == pygame.K_DOWN:      print("向下移动")      MainGame.Tank_p1.direction = "D"      MainGame.Tank_p1.stop = False     if event.key == pygame.K_SPACE:#空格键发射子弹      if len(MainGame.Bullet_list) < 3:#控制子弹在屏幕显示的数量 太多没有游戏体验 列表中存储三个       m = Bullet(MainGame.Tank_p1)#子弹类对象 添加到列表 开始方法调用显示子弹 子弹触碰墙壁列表内移除对象       MainGame.Bullet_list.append(m)       music =Music("img/fire.wav")       music.play() def gameOver(self):#游戏结束方法  exit()class BaseItem(pygame.sprite.Sprite): def __init__(self):  pygame.sprite.Sprite.__init__(self)class Tank(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]  #坦克的区域(left,top,width,height)坦克位置以及坦克的大小  self.rect = self.image.get_rect()  self.rect.left = left#坦克距离左边位置修改默认参数指定的位置  self.rect.top = top#将坦克距离上边的位置修改我指定的位置  self.speed = 15#设置坦克的速度  self.stop = True #设置移动的开关  self.oldtop = self.rect.top  self.oldleft = self.rect.left def move(self):  self.oldtop = self.rect.top  self.oldleft = self.rect.left  if self.direction == "U":#向上时   if self.rect.top > 0:#self.rect = self.image.get_rect()    # self.rect.top = top#将坦克距离上边的位置修改我指定的位置    self.rect.top -= self.speed#坦克的速度距离每一次调用时相减 直到<0时  elif self.direction == "D":#向下时   if self.rect.top < MainGame.screen_height-MainGame.Tank_p1.rect.height:#下边界小于窗口的高度减去坦克自身的高度的距离    self.rect.top += self.speed #距离加速度的距离 循环一次添加一次  elif self.direction == "L":   if self.rect.left > 0:    self.rect.left -= self.speed  elif self.direction == "R":   if self.rect.left < MainGame.screen_width -MainGame.Tank_p1.rect.width:    self.rect.left += self.speed def stay(self):  self.rect.left = self.oldleft  self.rect.top = self.oldtop def hitWall(self):  for wall in MainGame.wall_list:   if pygame.sprite.collide_rect(wall,self):    self.stay() def shot(self):  return Bullet(self) def displayTank(self):#坦克显示方法  #1.重新设置坦克的图片  self.image = self.images[self.direction]  #2.将坦克加入到窗口中  MainGame.window.blit(self.image,self.rect)#调用MainGame window方法  # 传入图片和位置 self.rect = self.image.get_rect()class MyTank(Tank): 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(Tank):#敌方坦克类 def __init__(self,left,top,speed):#初始化敌方坦克 三个参数  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]#坦克的信息 从字典中以键获得值  # 坦克所在的区域 Rect->  self.rect = self.image.get_rect()#获得坦克图片的距离 距左和距上  # 指定坦克初始化位置 分别距x,y轴的位置  self.rect.left = left#距左的位置>>形参  self.rect.top = top#距上的位置  # 新增速度属性  self.speed = speed #速度>>初始化时设置  self.stop = True  self.step = 50#设置步数  self.live = True 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:#如果步数为0   self.direction = self.randDirection()#方向为随机方向   self.step = 30# 重置步数  else:   self.move()#移动 坦克位置不断改变   self.step -= 1#步数每次循环减一 def shot(self):  s = random.randint(1,1000)  if s <30:   return Bullet(self) def hitMyTank(self):  if pygame.sprite.collide_rect(self,MainGame.Tank_p1):   self.stay()class Bullet(BaseItem):#炮弹类 def __init__(self,tank):  self.image = pygame.image.load("img\enemymissile.gif")  self.direction = tank.direction  #子弹速度  self.speed = 18  self.rect = self.image.get_rect()#获得子弹的对象的坐标 只计算距离左侧和和上面  #子弹初始化位置要根据坦克大方向进行调整 可以自己画图计算  if self.direction == "U":   #子弹的位置 left += 坦克宽度的一半 - 子弹的宽度的一半   self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2   self.rect.top = tank.rect.top - self.rect.height  elif self.direction == "D":   self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2   self.rect.top = tank.rect.top - self.rect.height  elif self.direction == "L":   self.rect.left = tank.rect.left - tank.rect.width / 2 - self.rect.width / 2   self.rect.top = tank.rect.top + tank.rect.width/2 -self.rect.width/2  elif self.direction == "R":   self.rect.left = tank.rect.left + tank.rect.width / 2   self.rect.top = tank.rect.top + tank.rect.width/2 -self.rect.width/2  speed = 10#速度  alive = True#设置一个小标签 作判断 def bulletMove(self):#炮弹移动  if self.direction == "U":   if self.rect.top > 0 :#距离限制计算 self子弹对象本身 rect.top距离窗口上方 rect.left左侧    self.rect.top -= self.speed   else:    self.alive = False#此为<0时的情况 同下都是触碰墙壁时的情况  elif self.direction == "D":   if self.rect.top < MainGame.screen_height - self.rect.height:#屏幕高度 - 子弹的高度    self.rect.top += self.speed   else:    self.alive = False  elif self.direction == "L":   if self.rect.left > 0:    self.rect.left -= self.speed   else:    self.alive = False  elif self.direction == "R":   if self.rect.left < MainGame.screen_width - self.rect.width:    self.rect.left += self.speed   else:    self.alive = False def hitEnemyTank(self):#我方子弹与敌方坦克相碰  for etank in MainGame.EnemyTank_list:#敌方坦克列表   if pygame.sprite.collide_rect(etank,self):#sprite中的相撞测试    explode = Explode(etank)#产生一个爆炸效果    MainGame.Explode_list.append(explode)    self.alive = False    etank.live = False def hitMyTank(self):  if pygame.sprite.collide_rect(self,MainGame.Tank_p1):   explode = Explode(MainGame.Tank_p1)   MainGame.Explode_list.append(explode)   MainGame.Tank_p1.alive = False   self.alive = False def hitWalls(self):  for wall in MainGame.wall_list:   if pygame.sprite.collide_rect(wall,self):    self.alive = False    wall.hp -= 1    if wall.hp <= 0:     wall.live = False def display_bullet(self):#显示子弹方法  MainGame.window.blit(self.image,self.rect)#窗口写入class Explode:#爆炸效果 def __init__(self,tank):  self.step = 0  self.rect = tank.rect  self.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"),      pygame.image.load("img/blast5.gif"),      pygame.image.load("img/blast6.gif"),      pygame.image.load("img/blast7.gif"),]  self.live = True  self.image = self.images[self.step] def display_explode(self):#显示爆炸效果  if self.step < len(self.images):   MainGame.window.blit(self.image,self.rect)   self.image = self.images[self.step]   self.step += 1  else:   self.live = False   self.step = 0class Wall: def __init__(self,left,top):  self.image = pygame.image.load("img/steels.gif")  self.rect = self.image.get_rect()   self.rect.left = left  self.rect.top = top  self.live = True  self.hp = 3 def displayWall(self):#显示障碍物  MainGame.window.blit(self.image,self.rect) class Music:#音效 def __init__(self,filename):  self.filename = filename  pygame.mixer.init()#混合器的初始  pygame.mixer.music.load(self.filename)#加载音乐文件 def play(self):  pygame.mixer.music.play(loops=0)#播放音乐 MainGame().startGame()

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


  • 上一条:
    如何用C代码给Python写扩展库(Cython)
    下一条:
    六行python代码的爱心曲线详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客