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使用稀疏矩阵节省内存实例
Jun 27 Python
Python的加密模块md5、sha、crypt使用实例
Sep 28 Python
python opencv3实现人脸识别(windows)
May 25 Python
python2.7实现爬虫网页数据
May 25 Python
python用pandas数据加载、存储与文件格式的实例
Dec 07 Python
Python编程深度学习绘图库之matplotlib
Dec 28 Python
python3+selenium自动化测试框架详解
Mar 17 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
Apr 30 Python
python numpy 反转 reverse示例
Dec 04 Python
python Paramiko使用示例
Sep 21 Python
python APScheduler执行定时任务介绍
Apr 19 Python
Python实现Matplotlib,Seaborn动态数据图
May 06 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测试框架PHPUnit组织测试操作示例
2018/05/28 PHP
javascript 哈希表(hashtable)的简单实现
2010/01/20 Javascript
老鱼 浅谈javascript面向对象编程
2010/03/04 Javascript
jQuery 获取URL参数的插件
2010/03/04 Javascript
Draggable Elements 元素拖拽功能实现代码
2011/03/30 Javascript
JQuery切换显示的效果实例代码
2013/02/27 Javascript
JavaScript Promise启示录
2014/08/12 Javascript
JQuery实现左右滚动菜单特效
2015/09/28 Javascript
分享自己用JS做的扫雷小游戏
2016/02/17 Javascript
jQuery插件formValidator实现表单验证
2016/05/23 Javascript
JavaScript中数据类型转换总结
2016/12/25 Javascript
javascript数据类型详解
2017/02/07 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
javascript 中select框触发事件过程的分析
2017/08/01 Javascript
JS中的多态实例详解
2017/10/15 Javascript
解析vue data不可以使用箭头函数问题
2018/07/03 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
2018/08/17 Javascript
python在html中插入简单的代码并加上时间戳的方法
2018/10/16 Python
pygame游戏之旅 添加游戏介绍
2018/11/20 Python
Python实现查找二叉搜索树第k大的节点功能示例
2019/01/24 Python
Python搭建代理IP池实现存储IP的方法
2019/10/27 Python
Python字节单位转换实例
2019/12/05 Python
使用Python实现分别输出每个数组
2019/12/06 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
Python利用Faiss库实现ANN近邻搜索的方法详解
2020/08/03 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
python代码实现图书管理系统
2020/11/30 Python
酒后驾驶检讨书
2014/01/27 职场文书
2013年研究生毕业感言
2014/02/06 职场文书
售后求职信范文
2014/03/15 职场文书
倡议书范文格式
2014/05/12 职场文书
世博会口号
2014/06/20 职场文书
单位消防安全责任书
2014/07/23 职场文书
信仰心得体会
2014/09/05 职场文书
基于go interface{}==nil 的几种坑及原理分析
2021/04/24 Golang