python实现简单坦克大战


Posted in Python onMarch 27, 2020

基于对面向对象编程的思想完成简单的坦克大战游戏。主要目的锻炼面相对象编程思想
同样的在使用python进行游戏编写时需要安装pygame模块

安装方法:

pycharm安装方式:File --> setting

python实现简单坦克大战

游戏中的主要对象有:

坦克父类:BaseTank
我方坦克:HeroTank
敌方坦克:EnemyTank
子弹类:Bullet
爆炸类:Explode
墙类:Wall
主进程:MainGame

定义一个精灵类:

# 定义一个精灵类
class BaseItem(Sprite):
 def __init__(self, color, width, height):
 # Call the parent class (Sprite) constructor
 pygame.sprite.Sprite.__init__(self)

坦克父类:

# 坦克父类
class BaseTank(BaseItem):
 # 定义类属性,所有坦克对象高和宽都是一样
 width = 60
 height = 60

 def __init__(self, left, top):
 self.direction = 'U' # 坦克的方向默认向上
 # 存放图片的字典
 self.images = {
 'U': pygame.image.load('tank_img/p1tankU.gif'),
 'D': pygame.image.load('tank_img/p1tankD.gif'),
 'L': pygame.image.load('tank_img/p1tankL.gif'),
 'R': pygame.image.load('tank_img/p1tankR.gif')
 }
 self.image = self.images[self.direction] # 坦克的图片由方向决定
 self.speed = 5 # 坦克的速度
 self.rect = self.image.get_rect()
 # 设置放置的位置
 self.rect.left = left
 self.rect.top = top
 self.stop = True # 坦克是否停止
 self.live = True # 决定坦克是否消灭了

 # 保持原来的位置
 self.oldLeft = self.rect.left
 self.oldTop = self.rect.top

 # 射击方法
 def shot(self):
 return Bullet(self)

 # 坦克的移动
 def move(self):
 # 保持原来的状态
 self.oldLeft = self.rect.left
 self.oldTop = self.rect.top
 # 判断坦克的移动方向
 if self.direction == 'U':
 if self.rect.top > 0:
 self.rect.top -= self.speed
 elif self.direction == 'D':
 if self.rect.top + self.rect.height < WINDOW_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+self.rect.height < WINDOW_WIDTH:
 self.rect.left += self.speed
 
 # 加载坦克
 def displayTank(self):
 self.image = self.images[self.direction]
 MainGame.window.blit(self.image, self.rect)
 
 # 撞墙处理
 def hitWall(self):
 for wall in MainGame.wallList:
 if pygame.sprite.collide_rect(wall, self):
 self.stay()
 
 # 处理位置不变
 def stay(self):
 self.rect.left = self.oldLeft
 self.rect.top = self.oldTop

我方坦克类():

# 我方坦克
class HeroTank(BaseTank):
 def __init__(self, left, top):
 super().__init__(left, top)
 
 # 我方坦克碰撞敌方坦克
 def myTank_hit_enemyTank(self):
 for enemyTank in MainGame.EnemyTankList:
 if pygame.sprite.collide_rect(enemyTank, self):
 self.stay()

敌方坦克类():

# 敌方坦克
class EnemyTank(BaseTank):
 def __init__(self, left, top, speed):
 super(EnemyTank, self).__init__(left, top)
 self.images = {
 'U': pygame.image.load('tank_img/enemy1U.gif'),
 'D': pygame.image.load('tank_img/enemy1D.gif'),
 'L': pygame.image.load('tank_img/enemy1L.gif'),
 'R': pygame.image.load('tank_img/enemy1R.gif')
 }

 self.direction = self.RandomDirection()
 self.image = self.images[self.direction]
 self.rect = self.image.get_rect()
 self.rect.left = left
 self.rect.top = top
 self.speed = speed
 self.step = 60
 self.enemy_flag = False

 # 坦克出生随机方向
 def RandomDirection(self):
 num = random.randint(1, 4)
 if num == 1:
 return 'U'
 elif num == 2:
 return 'D'
 elif num == 3:
 return 'L'
 else:
 return 'R'
 
 # 坦克随机移动
 def randomMove(self):
 if self.step < 0:
 self.direction = self.RandomDirection()
 self.step = 60
 else:
 self.move()
 self.step -= 1
 
 # 坦克射击
 def shot(self):
 num = random.randint(1, 100)
 if num < 4:
 return Bullet(self)
 
 # 敌方坦克碰撞我方坦克
 def enemyTank_hit_MyTank(self):
 for enemy in MainGame.EnemyTankList:
 if MainGame.my_tank and MainGame.my_tank.live:
 if pygame.sprite.collide_rect(MainGame.my_tank, enemy):
 self.stay()

子弹类():

# 子弹类
class Bullet(BaseItem):
 def __init__(self, tank):
 self.image = pygame.image.load('tank_img/tankmissile.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.height / 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.height / 2 - self.rect.width / 2

 # 子弹的速度
 self.speed = 6
 # 子弹状态
 self.live = True
 
 # 加载子弹
 def displayBullet(self):
 MainGame.window.blit(self.image, self.rect)
 
 # 子弹的移动
 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 < WINDOW_WIDTH:
 self.rect.left += self.speed
 else:
 self.live = False
 elif self.direction == 'D':
 if self.rect.top + self.rect.height < WINDOW_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_enemy(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 enemyBullet_hit_myTank(self):
 if MainGame.my_tank and MainGame.my_tank.live:
 if pygame.sprite.collide_rect(MainGame.my_tank, self):
 MainGame.my_tank.live = False
 self.live = False

 # 创建爆炸对象
 explode = Explode(MainGame.my_tank)
 MainGame.explodeList.append(explode)
 
 # 射击墙壁
 def wall_bullet(self):
 for wall in MainGame.wallList:
 if pygame.sprite.collide_rect(wall, self):
 wall.hg -= 1
 self.live = False
 if wall.hg <= 0:
 wall.live = False

墙壁类():

# 墙壁类
class Wall:
 def __init__(self, left, top):
 self.image = pygame.image.load('tank_img/steels.gif')
 self.rect = self.image.get_rect()
 self.rect.left = left
 self.rect.top = top
 self.live = True
 self.hg = 100000000000000
 
 # 加载墙壁
 def displayWall(self):
 if self.live:
 MainGame.window.blit(self.image, self.rect)

爆炸类:

# 爆炸类
class Explode:
 def __init__(self, tank):
 # 爆炸的位置由坦克决定
 self.rect = tank.rect
 self.images = [
 pygame.image.load('tank_img/blast0.gif'),
 pygame.image.load('tank_img/blast1.gif'),
 pygame.image.load('tank_img/blast2.gif'),
 pygame.image.load('tank_img/blast3.gif'),
 pygame.image.load('tank_img/blast4.gif'),
 pygame.image.load('tank_img/blast5.gif'),
 pygame.image.load('tank_img/blast6.gif'),
 pygame.image.load('tank_img/blast7.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 MainGame:
 # 类属性
 window = None
 my_tank = None

 # 敌方坦克初始化
 EnemyTankList = []
 EnemyTankCount = 5

 # 存储我方子弹列表
 myBulleList = []
 # 存储敌方子弹的列表
 EnemyBulletList = []

 # 创建爆炸对象列表
 explodeList = []

 # 创建墙壁列表
 wallList = []

 # 游戏开始方法
 def start_game(self):
 # 初始化展示模块
 pygame.display.init()
 # 调用创建窗口的方法
 self.creat_window()
 # 设置游戏窗口标题
 pygame.display.set_caption('坦克大战')
 # 初始化我方坦克
 self.createMyTank()
 # 初始化敌方坦克
 self.creatEnemyTank()
 # 初始化墙壁
 self.creatWall()

 # 程序持续进行
 while True:
 # 更改背景颜色
 MainGame.window.fill(COLOR_GREEN)
 # 背景音乐

 # 获取事件
 self.getEvent()
 # 调用我方坦克进行显示
 if MainGame.my_tank and MainGame.my_tank.live:
 MainGame.my_tank.displayTank()
 if not MainGame.my_tank.stop:
 MainGame.my_tank.move()
 MainGame.my_tank.hitWall()
 MainGame.my_tank.myTank_hit_enemyTank()
 else:
 del MainGame.my_tank
 MainGame.my_tank = None
 # 加载我方子弹
 self.biltMyBullet()
 # 显示敌方坦克
 self.biltEnemyTank()
 # 显示敌方子弹
 self.biltEnemyBullet()
 # 显示墙壁
 self.blitWall()
 # 显示爆炸效果
 self.blitExplode()

 self.put_more_enemytank()

 # 窗口持续刷新
 pygame.display.update()
 time.sleep(0.02)

 # 重复添加敌方坦克
 def put_more_enemytank(self):
 while len(MainGame.EnemyTankList) < 5:
 self.more()

 # 创建游戏窗口方法:
 def creat_window(self):
 if not MainGame.window:
 # 创建窗口
 MainGame.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
 return MainGame.window

 # 创建我方坦克
 def createMyTank(self):
 MainGame.my_tank = HeroTank((WINDOW_WIDTH - HeroTank.width)/2, WINDOW_HEIGHT - HeroTank.height)
 music = Music('tank_img/start.wav')
 music.play()

 # 创建墙壁
 def creatWall(self):
 for i in range(60, WINDOW_WIDTH, 60):
 top = WINDOW_WIDTH // 3
 left = i
 wall = Wall(left, top)
 MainGame.wallList.append(wall)

 # 显示墙壁
 def blitWall(self):
 for b in MainGame.wallList:
 if b.live:
 b.displayWall()
 else:
 MainGame.wallList.remove(b)

 # 加载我方子弹
 def biltMyBullet(self):
 for bullet in MainGame.myBulleList:
 if bullet.live:
 bullet.displayBullet()
 bullet.move()
 bullet.myBullet_hit_enemy()
 bullet.wall_bullet()
 else:
 MainGame.myBulleList.remove(bullet)

 # 后续坦克的添加
 def more(self):
 top = 0
 for i in range(5 - len(MainGame.EnemyTankList)):
 left = random.randint(0, 750)
 speed = random.randint(1, 4)
 enemy = EnemyTank(left, top, speed)
 MainGame.EnemyTankList.append(enemy)

 # 创建敌方坦克
 def creatEnemyTank(self):
 top = 0
 for i in range(MainGame.EnemyTankCount):
 left = random.randint(0, 750)
 speed = random.randint(1, 4)
 enemy = EnemyTank(left, top, speed)
 MainGame.EnemyTankList.append(enemy)

 # 循环遍历显示敌方坦克
 def biltEnemyTank(self):
 for enemytank in MainGame.EnemyTankList:
 if enemytank.live:
 enemytank.displayTank()
 EnemyBullet = enemytank.shot()
 enemytank.randomMove()
 enemytank.hitWall()
 enemytank.enemyTank_hit_MyTank()

 # 存储敌方子弹
 if EnemyBullet:
 MainGame.EnemyBulletList.append(EnemyBullet)
 else:
 MainGame.EnemyTankList.remove(enemytank)
 MainGame.EnemyTankCount -= 1

 # 加载敌方子弹
 def biltEnemyBullet(self):
 for bullet in MainGame.EnemyBulletList:
 if bullet.live:
 bullet.displayBullet()
 bullet.move()
 bullet.enemyBullet_hit_myTank()
 bullet.wall_bullet()

 else:
 MainGame.EnemyBulletList.remove(bullet)

 # 加载爆炸效果
 def blitExplode(self):
 for explode in MainGame.explodeList:
 if explode.live:
 explode.displayExplode()
 else:
 MainGame.explodeList.remove(explode)

 # 获取游戏中的所有事件
 def getEvent(self):
 # 获取游戏中的事件列表
 even_list = pygame.event.get()
 for e in even_list:
 # 点击窗口的叉号实现游戏结束
 if e.type == pygame.QUIT:
 sys.exit()

 # 通过上下左右键控制坦克的移动
 if e.type == pygame.KEYDOWN:
 if MainGame.my_tank and MainGame.my_tank.live:
 if e.key == pygame.K_DOWN or e.key == pygame.K_s:
 MainGame.my_tank.direction = 'D'
 MainGame.my_tank.stop = False
 print("按下向下的键,向下移动")
 elif e.key == pygame.K_UP or e.key == pygame.K_w:
 MainGame.my_tank.direction = 'U'
 MainGame.my_tank.stop = False
 print("按下向上的键,向上移动")
 elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
 MainGame.my_tank.direction = 'L'
 MainGame.my_tank.stop = False
 print("按下向左的键,向左移动")
 elif e.key == pygame.K_RIGHT or e.key == pygame.K_d:
 MainGame.my_tank.direction = 'R'
 MainGame.my_tank.stop = False
 print("按下向右的键,向右移动")

 elif e.key == pygame.K_SPACE:
 print('发射子弹')
 # 创建我方子弹
 if len(MainGame.myBulleList) < 10:
 mybullet = Bullet(MainGame.my_tank)
 MainGame.myBulleList.append(mybullet)

 # 射击音效
 Shot_music = Music('tank_img/fire.wav')
 Shot_music.play()

 elif e.type == pygame.KEYUP:
 if e.key == pygame.K_UP or e.key == pygame.K_DOWN or e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT \
 or e.key == pygame.K_w or e.key == pygame.K_s or e.key == pygame.K_a or e.key == pygame.K_d:
 if MainGame.my_tank and MainGame.my_tank.live:
 MainGame.my_tank.stop = True

程序运行结果:

python实现简单坦克大战

源码下载:python实现简单坦克大战

更多关于python游戏的精彩文章请点击查看以下专题:

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

Python 相关文章推荐
Python MD5文件生成码
Jan 12 Python
Python实现的Kmeans++算法实例
Apr 26 Python
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 Python
python基础教程之常用运算符
Aug 29 Python
python获取本地计算机名字的方法
Apr 29 Python
用python处理图片实现图像中的像素访问
May 04 Python
获取Pytorch中间某一层权重或者特征的例子
Aug 17 Python
python3 mmh3安装及使用方法
Oct 09 Python
Tensorflow获取张量Tensor的具体维数实例
Jan 19 Python
利用Tensorflow的队列多线程读取数据方式
Feb 05 Python
win10下python3.8的PIL库安装过程
Jun 08 Python
Python如何把不同类型数据的json序列化
Apr 30 Python
Django实现从数据库中获取到的数据转换为dict
Mar 27 #Python
Python生成器实现简单&quot;生产者消费者&quot;模型代码实例
Mar 27 #Python
python数据库编程 Mysql实现通讯录
Mar 27 #Python
python数据库编程 ODBC方式实现通讯录
Mar 27 #Python
django 读取图片到页面实例
Mar 27 #Python
django ListView的使用 ListView中获取url中的参数值方式
Mar 27 #Python
django列表筛选功能的实现代码
Mar 27 #Python
You might like
教你如何解密 “ PHP 神盾解密工具 ”
2014/06/20 PHP
php中文字符串截取方法实例总结
2014/09/30 PHP
PHP 抽象方法与抽象类abstract关键字介绍及应用
2014/10/16 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
PHP类与对象后期静态绑定操作实例详解
2018/12/20 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
arguments对象
2006/11/20 Javascript
Javascript 解疑
2009/11/11 Javascript
js下关于onmouseout、事件冒泡的问题经验小结
2010/12/09 Javascript
jquery ajax 调用失败的原因示例介绍
2013/09/27 Javascript
Javascript变量作用域详解
2013/12/06 Javascript
JS实现一个列表中包含上移下移删除等功能
2014/09/24 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
Bootstrap项目实战之首页内容介绍(全)
2016/04/25 Javascript
简洁实用的BootStrap jQuery手风琴插件
2016/08/31 Javascript
深入理解Angular4订阅(Subscribe)与取消
2017/11/22 Javascript
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
vue 组件中使用 transition 和 transition-group实现过渡动画
2019/07/09 Javascript
微信小程序 wx:for遍历循环使用实例解析
2019/09/09 Javascript
js实现窗口全屏示例详解
2019/09/17 Javascript
vue制作抓娃娃机的示例代码
2020/04/17 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
Vue实现手机计算器
2020/08/17 Javascript
Python爬虫爬取美剧网站的实现代码
2016/09/03 Python
如何在python字符串中输入纯粹的{}
2018/08/22 Python
python3的url编码和解码,自定义gbk、utf-8的例子
2019/08/22 Python
Python实现银行账户资金交易管理系统
2020/01/03 Python
日本7net购物网:书籍、漫画、杂志、DVD、游戏邮购
2017/02/17 全球购物
荷叶母亲教学反思
2014/04/30 职场文书
毕业典礼演讲稿
2014/05/13 职场文书
党员个人查摆剖析材料
2014/10/16 职场文书
小学安全教育主题班会
2015/08/12 职场文书
2016年国庆节宣传标语
2015/11/25 职场文书
2016年员工政治思想表现评语
2015/12/02 职场文书
vue实现拖拽交换位置
2022/04/07 Vue.js
JavaScript实现九宫格拖拽效果
2022/06/28 Javascript