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

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

#功能实现游戏主窗口
import pygame,time,random#导入模块
_display = pygame.display#赋值给一个变量 调用时方便
color_red = pygame.Color(255,0,0)#同上  v
class 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 = 0
class 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()

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

(0)

相关推荐

  • python使用pygame模块实现坦克大战游戏

    本文实例为大家分享了pygame模块实现坦克大战游戏的具体代码,供大家参考,具体内容如下 首先,第一步,游戏简单素材的准备. 炮弹,炮弹,坦克移动.音乐-开火素材. 其次,思路整理. 我们需要几个类,分别是玩家类,敌人类,炮弹类及地图类,开始游戏界面以及结束界面,血条等等. 开始coding. 主函数,new一个对象(java乱入emmm),声明一个对象. # encoding : utf-8 # anthor : comi from gameloop import * from pygame

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

    本文实例为大家分享了python实现坦克大战的具体代码,供大家参考,具体内容如下 #功能实现游戏主窗口 import pygame,time,random#导入模块 _display = pygame.display#赋值给一个变量 调用时方便 color_red = pygame.Color(255,0,0)#同上 v class MainGame(object): screen_width = 900#游戏界面宽度 screen_height = 550#界面的高度 Tank_p1 = No

  • 基于python实现坦克大战游戏

    本文实例为大家分享了python实现坦克大战游戏的具体代码,供大家参考,具体内容如下 游戏界面 pygame游戏引擎的安装 pip安装 windows + R --> cmd --> 命令行输入 pip install 模块名==版本号 pycharm中安装 File --> setting --> Project --> Project Interpreter --> 右侧 + install --> 搜索框输入pygame --> 下方 installP

  • Vue3+Canvas实现坦克大战游戏

    目录 前言 架构搭建 Canvas构造函数 画布绘制 文本渲染 画布重绘前的clear 核心:绘制函数 BattleCity构造函数 实现坦克的移动 坦克发射子弹的逻辑 总结 前言 记得几年前刚做前端开发的时候,跟着师傅用纯 es5 实现了这款坦克大战,可以说我入行前端是从 javaScript 小游戏开始的,时间已匆匆过去了数年,前端发展日新月异,各种新框架.新概念层出不穷,很容易就迷失在对各种新技术的盲目学习和应用中,真正的编程是什么呢?值得思考的问题. 我准备用 vue3 重新实现一下这款

  • python实现双人版坦克大战游戏

    游戏介绍: 双人版的<坦克大战>的基本规则是玩家消灭出现的敌方坦克保卫我方基地. 中间还会随机出现很多特殊道具吸收可获得相应的功能,消灭玩即可进入下一关. 方向键:上下左右移动即可.另一个方向键则是:WSAD. 环境配置: Python3. Pycharm .Pygame. 第三方库的安装:pip  install pygame 效果展示: 开始界面一一 开始即可上手玩游戏,还有背景音乐辅助!游戏玩儿起来更带感!  游戏界面-- 代码演示: 1)游戏主程序 import pygame impo

  • python实现坦克大战

    本文实例为大家分享了python实现坦克大战的具体代码,供大家参考,具体内容如下 本游戏制作代码量较大 具体代码与图片声源可以在我的GitHub中下载 github地址 下面来看看然后利用python做一个坦克大战游戏 创建子弹类 import pygame class Bullet(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.bullet_up = pygame.imag

  • Pytorch实现图像识别之数字识别(附详细注释)

    使用了两个卷积层加上两个全连接层实现 本来打算从头手撕的,但是调试太耗时间了,改天有时间在从头写一份 详细过程看代码注释,参考了下一个博主的文章,但是链接没注意关了找不到了,博主看到了联系下我,我加上 代码相关的问题可以评论私聊,也可以翻看博客里的文章,部分有详细解释 Python实现代码: import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transf

  • Vue3+Canvas实现坦克大战游戏(二)

    目录 前言 敌方坦克的生成 坦克移动的算法 子弹击中物体的算法 爆炸效果的实现 生成障碍物(石墙.砖墙等) 总结 前言 接着上篇讲,本篇主要给大家讲解一下子弹击中物体.物体销毁.敌方坦克构建生成.运动算法.爆炸效果.以及障碍物的生成:了解了这些我相信你可以不依赖游戏引擎实现大部分小游戏的开发. Es5版本: 在线游戏 源代码 W/上 S/下 A/左 D/右 F/射击 让我们开始吧! 敌方坦克的生成 我们可以使用 for 循环和Tank 构造函数,批量制造多个敌方坦克,x,y 为其在画布中的坐标,

  • Vue3+Canvas实现坦克大战游戏(一)

    目录 前言 架构搭建 Canvas 构造函数 画布绘制 文本渲染 画布重绘前的 clear 核心:绘制函数 BattleCity 构造函数 实现坦克的移动 坦克发射子弹的逻辑 总结 前言 记得几年前刚做前端开发的时候,跟着师傅用纯 es5 实现了这款坦克大战,可以说我入行前端是从 javaScript 小游戏开始的,时间已匆匆过去了数年,前端发展日新月异,各种新框架.新概念层出不穷,很容易就迷失在对各种新技术的盲目学习和应用中,真正的编程是什么呢?值得思考的问题. 我准备用 vue3 重新实现一

  • Java实现飞机大战游戏 附完整源码

    目录 飞机大战详细文档 实现效果: 结构设计 详细分析 Main界面类使用边框布局,给面板分三个区,如图所示 绘制背景地图 飞行道具类UML图 绘制线程: 如何让我们的游戏动起来 背景的绘制 我的飞机的绘制 移动线程 如何控制我的飞机移动? 敌方飞机线程 : 如何生成敌方飞机呢? 敌方子弹线程 : 使每一个敌方飞机开火 检测碰撞线程 : 在子弹与敌机碰撞时,移除敌机 其他功能:显示玩家hp,掉落道具,得分,升级,更换地图 飞机大战详细文档 文末有源代码,以及本游戏使用的所有素材,将plane2文

随机推荐