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 28 Python
Python自动化测试ConfigParser模块读写配置文件
Aug 15 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
Aug 28 Python
Python中如何获取类属性的列表
Dec 26 Python
python实现遍历文件夹修改文件后缀
Aug 28 Python
Python实现iOS自动化打包详解步骤
Oct 03 Python
Python Web框架之Django框架文件上传功能详解
Aug 16 Python
python实现ftp文件传输系统(案例分析)
Mar 20 Python
python实现人工蜂群算法
Sep 18 Python
Python Charles抓包配置实现流程图解
Sep 29 Python
Python实现http接口自动化测试的示例代码
Oct 09 Python
解决Python字典查找报Keyerror的问题
May 26 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使用SAE原生Mail类实现各种类型邮件发送的方法
2016/10/10 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
Ext grid 添加右击菜单
2009/11/26 Javascript
原来Jquery.load的方法可以一直load下去
2011/03/28 Javascript
JavaScript实现彩虹文字效果的方法
2015/04/16 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
JavaScript+html5 canvas制作色彩斑斓的正方形效果
2016/01/27 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
2016/04/13 Javascript
javascript 广告移动特效的实现代码
2016/06/25 Javascript
jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法
2016/10/14 Javascript
AngulerJS学习之按需动态加载文件
2017/02/13 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
详解vuex的简单使用
2018/03/12 Javascript
Vuex的基本概念、项目搭建以及入坑点
2018/11/04 Javascript
ES6的解构赋值实例详解
2019/05/06 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
Python 解析XML文件
2009/04/15 Python
在Python中操作日期和时间之gmtime()方法的使用
2015/05/22 Python
让python在hadoop上跑起来
2016/01/27 Python
python计算auc指标实例
2017/07/13 Python
Python中的单继承与多继承实例分析
2018/05/10 Python
python生成1行四列全2矩阵的方法
2018/08/04 Python
Pytorch 实现sobel算子的卷积操作详解
2020/01/10 Python
python实现无边框进度条的实例代码
2020/12/30 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
巴西男士个人护理产品商店:SHOP4MEN
2017/08/07 全球购物
英国创新设计文具、卡片和礼品包装网站:Paperchase
2018/07/14 全球购物
西班牙手机之家:Phone House
2018/10/18 全球购物
大学生专科毕业生自我评价
2013/11/17 职场文书
未受刑事制裁公证证明
2014/09/20 职场文书
活动简报范文
2015/07/22 职场文书
升学宴祝酒词
2015/08/11 职场文书
党员学习中国梦心得体会
2016/01/05 职场文书
Python Numpy库的超详细教程
2022/04/06 Python
正则表达式基础与常用验证表达式
2022/06/16 Javascript