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中的元类(metaclass)
Feb 14 Python
Python实现的数据结构与算法之双端队列详解
Apr 22 Python
Python 通过URL打开图片实例详解
Jun 01 Python
Python实现输出程序执行进度百分比的方法
Sep 16 Python
Python AES加密实例解析
Jan 18 Python
python修改list中所有元素类型的三种方法
Apr 09 Python
python模糊图片过滤的方法
Dec 14 Python
Django密码系统实现过程详解
Jul 19 Python
利用Python实现手机短信监控通知的方法
Jul 22 Python
python字典setdefault方法和get方法使用实例
Dec 25 Python
Python 2种方法求某个范围内的所有素数(质数)
Jan 31 Python
使用Pytorch搭建模型的步骤
Nov 16 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
将数组写入txt文件 var_export
2009/04/21 PHP
PHP实现抓取Google IP并自动修改hosts文件
2015/02/12 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
TreeView 用法(有代码)(asp.net)
2011/07/15 Javascript
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
Extjs中RowExpander控件的默认展开问题示例探讨
2014/01/24 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
js实现网页抽奖实例
2015/08/05 Javascript
jQuery文字提示与图片提示效果实现方法
2016/07/04 Javascript
利用Node.js制作爬取大众点评的爬虫
2016/09/22 Javascript
bootstrap的3级菜单样式,支持母版页保留打开状态实现方法
2016/11/10 Javascript
微信小程序之picker日期和时间选择器
2017/02/09 Javascript
bootstrap是什么_动力节点Java学院整理
2017/07/14 Javascript
使用pm2部署node生产环境的方法步骤
2019/03/09 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
2020/07/19 Javascript
uni-app使用countdown插件实现倒计时
2020/11/01 Javascript
video.js添加自定义组件的方法
2020/12/09 Javascript
[01:30:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第二场 2月2日
2021/03/11 DOTA
Python实现的Google IP 可用性检测脚本
2015/04/23 Python
python实现文本文件合并
2015/12/29 Python
Python的re模块正则表达式操作
2016/05/25 Python
Python 操作mysql数据库查询之fetchone(), fetchmany(), fetchall()用法示例
2019/10/17 Python
使用Python实现正态分布、正态分布采样
2019/11/20 Python
Pandas-Cookbook 时间戳处理方式
2019/12/07 Python
python 连续不等式语法糖实例
2020/04/15 Python
Python实现手势识别
2020/10/21 Python
基于IE10/HTML5 开发
2013/04/22 HTML / CSS
公共汽车、火车和飞机票的通用在线预订和销售平台:INFOBUS
2019/11/30 全球购物
如何手工释放资源
2013/12/15 面试题
MYSQL相比于其他数据库有哪些特点
2013/07/19 面试题
大学毕业生自荐书怎么写?
2014/01/06 职场文书
目标管理责任书
2014/04/15 职场文书
2015年元旦活动总结
2014/05/09 职场文书