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正则表达式的使用范例详解
Aug 08 Python
在Python中用has_key()方法查找键是否存在的教程
May 21 Python
浅析Python 中整型对象存储的位置
May 16 Python
python 读取视频,处理后,实时计算帧数fps的方法
Jul 10 Python
Python3爬虫学习之将爬取的信息保存到本地的方法详解
Dec 12 Python
python time.sleep()是睡眠线程还是进程
Jul 09 Python
Python实现Singleton模式的方式详解
Aug 08 Python
30秒学会30个超实用Python代码片段【收藏版】
Oct 15 Python
Python 项目转化为so文件实例
Dec 23 Python
python3中sorted函数里cmp参数改变详解
Mar 12 Python
Python爬取英雄联盟MSI直播间弹幕并生成词云图
Jun 01 Python
Python测试框架pytest高阶用法全面详解
Jun 01 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
综合图片计数器
2006/10/09 PHP
PHP+DBM的同学录程序(5)
2006/10/09 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
详解no input file specified 三种解决方法
2019/11/29 PHP
Thinkphp 框架扩展之应用模式实现方法分析
2020/04/27 PHP
JavaScript监测ActiveX控件是否已经安装过的代码
2008/09/02 Javascript
无阻塞加载脚本分析[全]
2011/01/20 Javascript
jQuery bind事件使用详解
2011/05/05 Javascript
JavaScript通过Date-Mask将日期转换成字符串的方法
2015/06/04 Javascript
jQuery下拉美化搜索表单效果代码分享
2015/08/25 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
2018/06/20 jQuery
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
js序列化和反序列化的使用讲解
2019/01/19 Javascript
解决layui的radio属性或别的属性没显示出来的问题
2019/09/26 Javascript
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
2020/07/26 Javascript
JavaScript实现原型封装轮播图
2020/12/27 Javascript
Python的Tornado框架异步编程入门实例
2015/04/24 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
python利用百度AI实现文字识别功能
2018/11/27 Python
python 定时任务去检测服务器端口是否通的实例
2019/01/26 Python
Python嵌套式数据结构实例浅析
2019/03/05 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
python异步实现定时任务和周期任务的方法
2019/06/29 Python
pygame实现俄罗斯方块游戏(基础篇1)
2019/10/29 Python
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
Bodum官网:咖啡和茶壶、玻璃器皿、厨房电器等
2018/08/01 全球购物
数字漫画:comiXology
2020/06/13 全球购物
闭幕式主持词
2014/04/02 职场文书
关于读书的演讲稿
2014/05/07 职场文书
师德先进个人材料
2014/12/20 职场文书
住房公积金贷款工资证明
2015/06/12 职场文书
婚礼必备主持词范本!
2019/07/23 职场文书
mysql5.7的安装及Navicate长久免费使用的实现过程
2021/11/17 MySQL
JavaScript架构localStorage特殊场景下二次封装操作
2022/06/21 Javascript