python+pygame实现坦克大战


Posted in Python onSeptember 10, 2019

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

一、首先导入pygame库

python+pygame实现坦克大战

python+pygame实现坦克大战

python+pygame实现坦克大战

二、源码分享

#coding=utf-8

import pygame
import time
import random
from pygame.sprite import Sprite

SCREEN_WIDTH=800
SCREEN_HEIGHT=500
BG_COLOR=pygame.Color(0,0,0)
TEXT_COLOR=pygame.Color(255,0,0)
#定义一个基类
class BaseItem(Sprite):
 def __init__(self,color,width,height):
 pygame.sprite.Sprite.__init__(self)
class MainGame():
 window=None
 my_tank = None
 #存储敌方坦克的列表
 enemyTankList=[]
 enemyTankCount=5
 # 存储我方坦克子弹的列表
 myBulletList = []
 #存储敌方子弹的列表
 enemyBulletList=[]
 explodeList = []

 #创建墙壁列表
 wallList = []

 def __init__(self):
 pass
 def startGame(self):
 pygame.display.init() #初始化窗口
 MainGame.window=pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])
 #初始化我方坦克
 self.createMyTank()
 pygame.display.set_caption('坦克大战1.03')
 #初始化敌方坦克
 self.createEnemyTank()

 self.createWall()

 while True:
  time.sleep(0.02)
  #给窗口设置填充色
  MainGame.window.fill(BG_COLOR)
  self.getEvent()
  #绘制文字
  MainGame.window.blit(self.getTextSuface('敌方坦克剩余数量%d'%len(MainGame.enemyTankList)),(10,10))
  #调用坦克显示方法
  if MainGame.my_tank and MainGame.my_tank.live:
  MainGame.my_tank.displayTank()
  else:
  del MainGame.my_tank
  MainGame.my_tank = None
  #循环遍历列表显示敌方坦克
  self.blitEnemyTank()
  #循环遍历爆炸列表
  self.blitExplode()
  #循环遍历墙壁
  self.blitWall()

  #循环遍历我方坦克的子弹
  self.blitMyBullet()
  #循环遍历子弹列表,展示敌方子弹
  self.blitEnemyBullet()
  if MainGame.my_tank and MainGame.my_tank.live:
  if not MainGame.my_tank.stop:
   MainGame.my_tank.move()
   #检测我方坦克是否与墙壁发生碰撞
   MainGame.my_tank.hitWall()
   MainGame.my_tank.myTank_hit_enemyTank()

  pygame.display.update()
 def blitWall(self):
 for wall in MainGame.wallList:
  if wall.live:
  wall.displayWall()
  else:
  MainGame.wallList.remove(wall)
 def createWall(self):
 #初始化墙壁
 for i in range(6):
  wall = Wall(i*130,220)
  MainGame.wallList.append(wall)
 def createMyTank(self):
 MainGame.my_tank = MyTank(350, 300)
 #创建music对象
 music = Music('img/start.wav')
 music.play()
 def createEnemyTank(self):
 top=100
 for i in range(MainGame.enemyTankCount):
  left = random.randint(0,600)
  speed = random.randint(1,4)
  enemy=EnemyTank(left,top,speed)
  MainGame.enemyTankList.append(enemy)
 def blitExplode(self):
 for explode in MainGame.explodeList:
  if explode.live:
  explode.displayExplode()
  else:
  MainGame.explodeList.remove(explode)
 def blitEnemyTank(self):
 for enemyTank in MainGame.enemyTankList:
  if enemyTank.live:
  EnemyTank.displayTank(enemyTank)
  enemyTank.randMove()
  enemyTank.hitWall()

  if MainGame.my_tank and MainGame.my_tank.live:
   enemyTank.enemyTank_hit_myTank()
  #发射子弹
  enemyBullet=enemyTank.shot()
  if enemyBullet:
   MainGame.enemyBulletList.append(enemyBullet)
  else:#不活着 删除
  MainGame.enemyTankList.remove(enemyTank)
  music = Music('img/fire.wav')
  music.play()

 def blitMyBullet(self):
 for myBullet in MainGame.myBulletList:
  if myBullet.live:
  myBullet.displayBullet()
  myBullet.move()
  #调用检测我方子弹是否与敌方坦克碰撞
  myBullet.myBullet_hit_enemyTank()
  myBullet.hitWall()
  else:
  MainGame.myBulletList.remove(myBullet)
 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)
 def endGame(self):
 print('谢谢使用,欢迎再次使用')
 exit()
 def getTextSuface(self,text):
 #初始化字体模块
 pygame.font.init()
 font=pygame.font.SysFont('kaiti',18)
 textSurface=font.render(text,True,TEXT_COLOR)
 return textSurface

 #获取事件
 def getEvent(self):
 eventList=pygame.event.get()
 for event in eventList:
  if event.type == pygame.QUIT:
  self.endGame()
  if event.type == pygame.KEYDOWN:#如果按下下键
  if not MainGame.my_tank:
   if event.key== pygame.K_ESCAPE:
   self.createMyTank()

  if MainGame.my_tank and MainGame.my_tank.live:
   #判断上下左右
   if event.key == pygame.K_LEFT:
   MainGame.my_tank.direction='L'
   #修改坦克开关状态
   MainGame.my_tank.stop=False
   #MainGame.my_tank.move()
   print('按下左键,坦克向左移动')
   elif event.key == pygame.K_RIGHT:
   MainGame.my_tank.direction='R'
   MainGame.my_tank.stop = False
   #MainGame.my_tank.move()
   print('按下右键,坦克向右移动')
   elif event.key == pygame.K_UP:
   MainGame.my_tank.direction='U'
   MainGame.my_tank.stop = False
   # MainGame.my_tank.move()
   print('按下上键,坦克向上移动')
   elif event.key == pygame.K_DOWN:
   MainGame.my_tank.direction='D'
   MainGame.my_tank.stop = False
   #MainGame.my_tank.move()
   print('按下下键,坦克向下移动')
   elif event.key == pygame.K_SPACE:
   print('发送子弹')
   if len(MainGame.myBulletList)<3:#最多发射3个子弹
    myBullet=Bullet(MainGame.my_tank)
    MainGame.myBulletList.append(myBullet)
    music = Music('img/hit.wav')
    music.play()
  if event.type == pygame.KEYUP:
  if MainGame.my_tank and MainGame.my_tank.live:
   #判断释放键是上下左右才停止
   if event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
   MainGame.my_tank.stop = True

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='L'

 self.image = self.images[self.direction]
 #根据图片获取区域
 self.rect = self.image.get_rect()
 #设置区域的left和TOP
 self.rect.left=left
 self.rect.top=top

 self.speed = 5
 #坦克移动的开关
 self.stop=True

 #是否活着
 self.live=True
 #距离原来坐标
 self.oldLeft = self.rect.left
 self.oldTop = self.rect.top

 #tank move
 def move(self):
 self.oldLeft = self.rect.left
 self.oldTop = self.rect.top
 #判断坦克方向
 if self.direction == 'L':
  if self.rect.left>0:
  self.rect.left -=self.speed
 elif self.direction == 'U':
  if self.rect.top>0:
  self.rect.top -=self.speed
 elif self.direction == 'D':
  if self.rect.top+self.rect.height<SCREEN_HEIGHT:
  self.rect.top +=self.speed
 elif self.direction == 'R':
  if self.rect.left+self.rect.height<SCREEN_WIDTH:
  self.rect.left += self.speed
 #tank shottint
 def shot(self):
 return Bullet(self)
 def stay(self):
 self.rect.left = self.oldLeft
 self.rect.top = self.oldTop
 #检测坦克是否与墙壁发生碰撞
 def hitWall(self):
 for wall in MainGame.wallList:
  if pygame.sprite.collide_rect(self,wall):
  self.stay()
 def displayTank(self):
 #获取展示的对象
 #调用blit方法展示
 self.image = self.images[self.direction]
 MainGame.window.blit(self.image,self.rect)


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()

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()
 #根据方向获取image
 self.image = self.images[self.direction]
 self.rect = self.image.get_rect()

 self.rect.left=left
 self.rect.top=top

 self.speed=speed
 self.flag=True

 self.step=60
 def enemyTank_hit_myTank(self):
 if pygame.sprite.collide_rect(self,MainGame.my_tank):
  self.stay()
 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.step=60
  self.direction = self.randDirection()
 else:
  self.move()
  self.step-=1
 def shot(self):
 #随机生成100以内的数
 num = random.randint(1,100)
 if num<10:
  return Bullet(self)
class Bullet(BaseItem):
 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':
  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 + tank.rect.height
 elif self.direction == 'L':
  self.rect.left = tank.rect.left - self.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
  self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2

 #子弹的速度
 self.speed=6

 #子弹的姿态,是否碰到墙壁,如果是墙壁,修改此状态
 self.live=True
 #move
 def move(self):
 if self.direction == 'U':
  if self.rect.top>0:
  self.rect.top-=self.speed
  else:
  #修改子弹的状态
  self.live=False
 elif self.direction == 'R':
  if self.rect.left+self.rect.width<SCREEN_WIDTH:
  self.rect.left+=self.speed
  else:
  self.live=False
 elif self.direction == 'D':
  if self.rect.top+self.rect.height<SCREEN_HEIGHT:
  self.rect.top+=self.speed
  else:
  self.live=False
 elif self.direction == 'L':
  if self.rect.left>0:
  self.rect.left-=self.speed
  else:
  self.live=False
 #我方坦克和敌方子弹的碰撞
 def myBullet_hit_enemyTank(self):
 #循环遍历敌方坦克列表,判断是否发生碰撞
 for enemyTank in MainGame.enemyTankList:
  if pygame.sprite.collide_rect(enemyTank,self):
  #修改敌方坦克和我方子弹的状态
  enemyTank.live = False
  self.live = False
  #创建爆炸对象
  explode = Explode(enemyTank)
  MainGame.explodeList.append(explode)

 #子弹是否碰撞墙壁
 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
 #show
 def displayBullet(self):
 MainGame.window.blit(self.image,self.rect)
 def enemyBullet_hit_myTank(self):
 if MainGame.my_tank and MainGame.my_tank.live:
  if pygame.sprite.collide_rect(MainGame.my_tank,self):
  explode = Explode(MainGame.my_tank)
  MainGame.explodeList.append(explode)
  self.live=False
  MainGame.my_tank.live=False


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 Explode():
 def __init__(self,tank):
 #爆炸的位置有当前子弹打中的位置确定
 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'),
   ]
 self.step=0
 self.image = self.images[self.step]

 self.live=True
 def displayExplode(self):
 #根据索引获取爆炸对象
 if self.step < len(self.images):
  self.image = self.images[self.step]
  self.step+=1
  MainGame.window.blit(self.image,self.rect)
 else:
  self.live=False
  self.step=0


class Music():
 def __init__(self,fileName):
 self.fileName = fileName
 #play music
 pygame.mixer.init()
 pygame.mixer.music.load(self.fileName)

 def play(self):
 pygame.mixer.music.play()


if __name__ == '__main__':
 MainGame().startGame()
 #MainGame().getTextSuface()

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

Python 相关文章推荐
Python的Flask框架应用调用Redis队列数据的方法
Jun 06 Python
用python处理图片实现图像中的像素访问
May 04 Python
Django数据库连接丢失问题的解决方法
Dec 29 Python
Python3转换html到pdf的不同解决方案
Mar 11 Python
提升Python程序性能的7个习惯
Apr 14 Python
python获取点击的坐标画图形的方法
Jul 09 Python
详解python实现小波变换的一个简单例子
Jul 18 Python
Python列表倒序输出及其效率详解
Mar 04 Python
keras实现多种分类网络的方式
Jun 11 Python
接口自动化多层嵌套json数据处理代码实例
Nov 20 Python
python3通过subprocess模块调用脚本并和脚本交互的操作
Dec 05 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
Jun 05 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
Sep 10 #Python
Python将视频或者动态图gif逐帧保存为图片的方法
Sep 10 #Python
python使用PIL和matplotlib获取图片像素点并合并解析
Sep 10 #Python
Python字符串中添加、插入特定字符的方法
Sep 10 #Python
详解python uiautomator2 watcher的使用方法
Sep 09 #Python
一行Python代码制作动态二维码的实现
Sep 09 #Python
python制作英语翻译小工具代码实例
Sep 09 #Python
You might like
php笔记之:数据类型与常量的使用分析
2013/05/14 PHP
php使用qr生成二维码的示例分享
2014/01/20 PHP
PHP中怎样防止SQL注入分析
2014/10/23 PHP
php循环table实现一行两列显示的方法
2015/06/04 PHP
PHP使用array_merge重新排列数组下标的方法
2015/07/22 PHP
CI框架常用方法小结
2016/05/17 PHP
thinkphp中的多表关联查询的实例详解
2017/10/12 PHP
jquery validate使用攻略 第四步
2010/07/01 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
动态获取复选框checkbox选中个数的jquery代码
2013/06/25 Javascript
Iframe 自动适应页面的高度示例代码
2014/02/26 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
angularJs 表格添加删除修改查询方法
2018/02/27 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
layui实现给某一列加点击事件
2019/10/26 Javascript
javascript实现获取中文汉字拼音首字母
2020/05/19 Javascript
Vue中component标签解决项目组件化操作
2020/09/04 Javascript
小程序实现密码输入框
2020/11/16 Javascript
python读取json文件并将数据插入到mongodb的方法
2015/03/23 Python
python开发之list操作实例分析
2016/02/22 Python
用python写的一个wordpress的采集程序
2016/02/27 Python
Python基于回溯法解决01背包问题实例
2017/12/06 Python
python3操作注册表的方法(Url protocol)
2020/02/05 Python
python 字符串格式化的示例
2020/09/21 Python
手工制作的音乐盒:Music Box Attic
2019/09/05 全球购物
linux面试题参考答案(6)
2014/08/29 面试题
模范教师事迹材料
2014/02/10 职场文书
企业管理毕业生求职信
2014/03/11 职场文书
会计求职自荐信
2014/06/20 职场文书
加强作风建设演讲稿
2014/10/24 职场文书
学雷锋倡议书
2015/01/19 职场文书
世界环境日活动总结
2015/02/11 职场文书
离职信范本
2015/06/23 职场文书
2015大学生暑假调查报告
2015/07/13 职场文书
Python实现列表拼接和去重的三种方式
2021/07/02 Python
如何避免mysql启动时错误及sock文件作用分析
2022/01/22 MySQL