Python3——坦克大战
# coding=utf-8
# Version:python3.6.1
__date__ = '2018/9/20 18:51'
__author__ = 'Lgsp_Harold' import pygame, sys, time
from random import randint
from pygame.locals import * # 坦克大战主窗口
class TankMain(object):
width = 600
height = 500
my_tank_missile_list = [] # 我方子弹列表
my_tank = None
# enemy_list = [] # 敌方坦克列表
wall=None
enemy_list = pygame.sprite.Group() # 敌方坦克的组
explode_list = []
enemy_missile_list=pygame.sprite.Group() # 开始游戏的方法
def startGame(self):
pygame.init() # pygame模块初始化,加载系统的资源
# 创建一个窗口,窗口大小(宽,高)、窗口的特性(0,RESIZEBLE,RULLscreem)
screem = pygame.display.set_mode((TankMain.width, TankMain.height), 0, 32)
pygame.display.set_caption("坦克大战") # 创建一堵墙
TankMain.wall = Wall(screem,65,160,30,120) # my_tank=My_Tank(screem) # 创建一个我方坦克,坦克显示在屏幕的中下部位置
TankMain.my_tank = My_Tank(screem) # 创建一个我方坦克,坦克显示在屏幕的中下部位置
if len(TankMain.enemy_list)==0:
# enemy_list=[]
for i in range(1, 6): # 游戏开始时初始化5个敌方坦克
# TankMain.enemy_list.append(Enemy_Tank(screem))
TankMain.enemy_list.add(Enemy_Tank(screem)) # 把敌方坦克放到组里面 while True:
if len(TankMain.enemy_list) < 5:
TankMain.enemy_list.add(Enemy_Tank(screem)) # 把敌方坦克放到组里面
# color RGB(0,0,0)
# 设置窗口屏幕背景颜色
screem.fill((0, 0, 0)) # 面向过程的写法
# pygame.draw.rect(screem,(0,255,0),Rect(400,30,100,30),5) # 显示左上角的文字
for i, text in enumerate(self.write_text(), 0):
screem.blit(text, (0, 5 + (15 * i))) # 显示游戏中的墙,并且对墙和其他对象进行碰撞检测
TankMain.wall.display()
TankMain.wall.hit_tank() self.get_event(TankMain.my_tank,screem) # 获取事件,根据获取事件进行处理
if TankMain.my_tank:
TankMain.my_tank.hit_enemy_missile() # 我方坦克和敌方的炮弹碰撞检测
if TankMain.my_tank and TankMain.my_tank.live:
TankMain.my_tank.display() # 在屏幕上显示我方坦克
TankMain.my_tank.move() # 在屏幕上移动的我方坦克
else:
# del(TankMain.my_tank)
# TankMain.my_tank=None
# print("Game Over")
# sys.exit()
TankMain.my_tank=None
# 显示和随机移动所有的敌方坦克
for enemy in TankMain.enemy_list:
enemy.display()
enemy.random_move()
enemy.random_fire() # 显示所有的我方炮弹
for m in TankMain.my_tank_missile_list:
if m.live:
m.display()
m.hit_tank() # 炮弹打中敌方坦克
m.move()
else:
TankMain.my_tank_missile_list.remove(m) # 显示所有的敌方炮弹
for m in TankMain.enemy_missile_list:
if m.live:
m.display()
m.move()
else:
TankMain.enemy_missile_list.remove(m) for explode in TankMain.explode_list:
explode.display() # 显示重置
time.sleep(0.05) # 每次休眠0.05秒跳到下一帧
pygame.display.update() # 获取所有的事件(敲击键盘,鼠标点击事件)
def get_event(self, my_tank,screem):
for event in pygame.event.get():
if event.type == QUIT: # 程序退出
self.stopGame()
if event.type == KEYDOWN and (not my_tank) and event.key == K_n:
TankMain.my_tank = My_Tank(screem)
if event.type == KEYDOWN and my_tank:
if event.key == K_LEFT or event.key == K_a:
my_tank.direction = "L"
my_tank.stop = False
# my_tank.move()
if event.key == K_RIGHT or event.key == K_d:
my_tank.direction = "R"
my_tank.stop = False
# my_tank.move()
if event.key == K_UP or event.key == K_w:
my_tank.direction = "U"
my_tank.stop = False
# my_tank.move()
if event.key == K_DOWN or event.key == K_s:
my_tank.direction = "D"
my_tank.stop = False
# my_tank.move()
if event.key == K_ESCAPE:
self.stopGame()
if event.key == K_SPACE:
m = my_tank.fire()
m.good = True # 我方坦克发射的炮弹,好炮弹
TankMain.my_tank_missile_list.append(m) if event.type == KEYUP and my_tank:
if event.key == K_LEFT or K_RIGHT or K_UP or K_DOWN:
my_tank.stop = True if event.type == MOUSEBUTTONUP:
pass # 关闭游戏
def stopGame(self):
sys.exit() # 在游戏窗口内左上角显示文字内容
def write_text(self):
font = pygame.font.SysFont("方正兰亭超细黑简体", 16) # 定义一个字体
# 文字,抗锯齿,字体颜色
text_sf1 = font.render("敌方坦克数量为:%d" % len(TankMain.enemy_list), True, (255, 0, 0)) # 根据字体创建一个文件的图像
text_sf2 = font.render("我方坦克炮弹数量为:%d" % len(TankMain.my_tank_missile_list), True, (255, 0, 0)) # 根据字体创建一个文件的图像
return text_sf1, text_sf2 # 坦克大战游戏中所有对象的父类
class BaseItem(pygame.sprite.Sprite):
def __init__(self, screem):
pygame.sprite.Sprite.__init__(self)
# 所有对象共享的属性
self.screem = screem # 把坦克对应图片显示在游戏窗口上
# 在游戏屏幕中显示当前游戏的对象
def display(self):
if self.live:
self.image = self.images[self.direction]
self.screem.blit(self.image, self.rect) # 把图片画在屏幕上 # 坦克公共父类
class Tank(BaseItem):
# 定义类属性,所有坦克对象高和宽都是一样
width = 50
height = 50 def __init__(self, screem, left, top):
super().__init__(screem)
# self.screem=screem # 坦克在移动或者显示过程中需要用到当前游戏的屏幕
self.direction = 'D' # 坦克的方向,默认方向向下(上下左右)
self.speed = 5 # 坦克移动的速度
self.stop = False
self.images = {} # 坦克的所有图片,key:方向,value:图片路径(surface)
self.images['L'] = pygame.image.load("../img/p1tankL.gif")
self.images['R'] = pygame.image.load("../img/p1tankR.gif")
self.images['U'] = pygame.image.load("../img/p1tankU.gif")
self.images['D'] = pygame.image.load("../img/p1tankD.gif")
self.image = self.images[self.direction] # 坦克的图片由方向决定
self.rect = self.image.get_rect()
self.rect.left = left
self.rect.top = top
self.live = True # 决定坦克是否消灭了
self.oldTop=self.rect.top
self.oldLeft=self.rect.left def stay(self):
self.rect.left=self.oldLeft
self.rect.top=self.oldTop # 坦克移动方法
def move(self):
if not self.stop: # 如果坦克不是停止状态
self.oldLeft=self.rect.left
self.oldTop=self.rect.top
if self.direction == "L": # 如果坦克的方向向左,那么只需要改坦克的left就可以了,left在减少
if self.rect.left > 0: # 判断坦克是否在左边的边界上
self.rect.left -= self.speed
else:
self.rect.left = 0
elif self.direction == "R":
if self.rect.right < TankMain.width:
self.rect.right += self.speed
else:
self.rect.right = TankMain.width
elif self.direction == "U":
if self.rect.top > 0:
self.rect.top -= self.speed
else:
self.rect.top = 0
elif self.direction == "D":
if self.rect.bottom < TankMain.height:
self.rect.bottom += self.speed
else:
self.rect.bottom = TankMain.height def fire(self):
m = Missile(self.screem, self)
return m # 我方坦克类
class My_Tank(Tank):
def __init__(self, screem):
super().__init__(screem, 275, 400) # 创建一个我方坦克,坦克显示在屏幕的中下部位置
self.stop = True
self.live = True def hit_enemy_missile(self):
hit_list=pygame.sprite.spritecollide(self,TankMain.enemy_missile_list,False)
for m in hit_list: # 我方坦克中弹
m.live=False
TankMain.enemy_missile_list.remove(m)
self.live=False
explode = Explode(self.screem,self.rect)
TankMain.explode_list.append(explode) # 敌方坦克类
class Enemy_Tank(Tank): def __init__(self, screem):
super().__init__(screem, randint(1, 5) * 100, 200)
self.speed = 3
self.step = 12 # 坦克按照某个方向移动的步数
self.get_random_direction() def get_random_direction(self):
r = randint(0, 4) # 得到一个坦克移动方向和停止的随机数
if r == 4:
self.stop = True
elif r == 2:
self.direction = "L"
self.stop = False
elif r == 0:
self.direction = "R"
self.stop = False
elif r == 1:
self.direction = "U"
self.stop = False
elif r == 3:
self.direction = "D"
self.stop = False # 敌方坦克按照一个确定的随机方向,连续移动12步,然后再次改变方向
def random_move(self):
if self.live:
if self.step == 0:
self.get_random_direction()
self.step = 12
else:
self.move()
self.step -= 1 #随机开火
def random_fire(self):
r=randint(0,50)
if r==10:
m=self.fire()
TankMain.enemy_missile_list.add(m)
else:
return # 炮弹类
class Missile(BaseItem):
width = 5
height = 5 def __init__(self, screem, tank):
super().__init__(screem)
self.tank = tank
self.direction = tank.direction # 炮弹的方向由所发射的坦克方向决定
self.speed = 12 # 炮弹移动的速度
enemymissileImg = pygame.image.load("../img/enemymissile.gif")
self.images = {} # 炮弹的所有图片,key:方向,value:图片路径(surface)
self.images['L'] = enemymissileImg
self.images['R'] = enemymissileImg
self.images['U'] = enemymissileImg
self.images['D'] = enemymissileImg
self.image = self.images[self.direction] # 坦克的图片由方向决定
self.rect = self.image.get_rect() # 炮弹的边界
# 炮弹坐标
self.rect.left = tank.rect.left + (tank.width - self.width) / 2
self.rect.top = tank.rect.top + (tank.height - self.height) / 2
self.live = True # 决定炮弹是否消灭了
self.good = False def move(self):
if self.live: # 如果炮弹还存在
if self.direction == "L": # 如果坦克的方向向左,那么只需要改坦克的left就可以了,left在减少
if self.rect.left > 0: # 判断坦克是否在左边的边界上
self.rect.left -= self.speed
else:
self.live = False
elif self.direction == "R":
if self.rect.right < TankMain.width:
self.rect.right += self.speed
else:
self.live = False
elif self.direction == "U":
if self.rect.top > 0:
self.rect.top -= self.speed
else:
self.live = False
elif self.direction == "D":
if self.rect.bottom < TankMain.height:
self.rect.bottom += self.speed
else:
self.live = False # 炮弹击中坦克,第一种我方炮弹击中敌方坦克;第二种敌方炮弹击中我方坦克
def hit_tank(self):
if self.good: # 如果炮弹是我方的炮弹
hit_list = pygame.sprite.spritecollide(self,TankMain.enemy_list,False)
for e in hit_list:
e.live=False
TankMain.enemy_list.remove(e) # 如果敌方坦克被击中,从列表中删除敌方坦克
self.live=False
expload = Explode(self.screem,e.rect) # 产生一个爆炸对象
TankMain.explode_list.append(expload) # 爆炸类
class Explode(BaseItem):
def __init__(self, screem, rect):
super().__init__(screem)
self.live = True
self.images = [pygame.image.load("../img/blast1.gif"),\
pygame.image.load("../img/blast2.gif"),\
pygame.image.load("../img/blast3.gif"),\
pygame.image.load("../img/blast4.gif"),\
pygame.image.load("../img/blast5.gif"),\
pygame.image.load("../img/blast6.gif"),\
pygame.image.load("../img/blast7.gif"),\
pygame.image.load("../img/blast8.gif")]
self.step = 0
self.rect = rect # 爆炸的位置和发生爆炸前,炮弹碰到的坦克位置一样。在构建爆炸的时候把坦克的rect传递进来。 # display方法在整个游戏运行过程中,循环调用,每隔0.1秒调用一次
def display(self):
if self.live:
if self.step == len(self.images): # 最后一张爆炸图片已经显示
self.live = False
else:
self.image = self.images[self.step]
self.screem.blit(self.image, self.rect)
self.step+=1
else:
pass # 删除该对象 # 游戏中的墙
class Wall(BaseItem):
def __init__(self,screem,left,top,width,height):
super().__init__(screem)
self.rect=Rect(left,top,width,height)
# self.left=left
# self.top=top
# self.width=width
# self.height=height
self.color=(255,0,0)
def display(self):
self.screem.fill(self.color,self.rect) #针对墙和其他坦克或者炮弹的碰撞检测
def hit_tank(self):
if TankMain.my_tank:
is_hit=pygame.sprite.collide_rect(self,TankMain.my_tank)
if is_hit:
TankMain.my_tank.stop=True
TankMain.my_tank.stay() if len(TankMain.enemy_list)!=0:
hit_list=pygame.sprite.spritecollide(self,TankMain.enemy_list,False)
for e in hit_list:
e.stop=True
e.stay() # 敌方炮弹击中墙,子弹消失
if TankMain.enemy_missile_list:
enemy_missile_hit_list=pygame.sprite.spritecollide(self,TankMain.enemy_missile_list,False)
for e in enemy_missile_hit_list:
e.stop=True
e.live=False # 我方炮弹击中墙,子弹消失
if TankMain.my_tank_missile_list:
my_tank_missile_hit_list=pygame.sprite.spritecollide(self,TankMain.my_tank_missile_list,False)
for e in my_tank_missile_hit_list:
e.stop=True
e.live=False tankMain = TankMain()
tankMain.startGame() if __name__ == '__main__':
pass
图片下载:https://pan.baidu.com/s/1bqlGB0
Python3——坦克大战的更多相关文章
- Python3+pygame实现的90坦克大战 代码完整 有演示效果
我是一个典型的80后,年轻时玩过了特别多的游戏,所以这几天用Python3+pygame实现了一个另外小游戏"坦克大战"(其他的游戏,请翻阅我的博客) 本实例代码量有些多,完整的版 ...
- pygame小游戏之坦克大战
以前在学校的时候无聊的学了会pygame.看了大概一周的教学视频,做出来个坦克大战的小游戏 Python3.5 pycharm import pygame,sys,time from random ...
- 手把手教你用Python实现“坦克大战”,附详细代码!
小时候玩的“坦克大战”,你还记得吗? 满满的回忆 ! 今天,我们使用Python以及强大的第三方库来实现一个简单的坦克大战游戏. 整体效果 环境依赖 python3.7 pygame1.9.6 ...
- 3D坦克大战游戏源码
3D坦克大战游戏源码,该游戏是基于xcode 4.3,ios sdk 5.1开发.在xcode4.3.3上完美无报错.兼容ios4.3-ios6.0 ,一款ios平台上难得的3D坦克大战游戏源码,有2 ...
- 【blade04】用面向对象的方法写javascript坦克大战
前言 javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用 就单以C#与Java来说,要到真正理解面 ...
- 3D坦克大战游戏iOS源码
3D坦克大战游戏源码,该游戏是基于xcode 4.3,ios sdk 5.1开发.在xcode4.3.3上完美无报错.兼容ios4.3-ios6.0 ,一款ios平台上难得的3D坦克大战游戏源码,有2 ...
- 坦克大战,看你能坚持几秒 ~~Duang~~Duang
闲来无事,写了一个坦克大战的小游戏,打开页面就能看到源码,代码还没有来得及整理.大家闲来玩玩吧,看谁玩的时间长! http://xiaohaibaomu.com/home/index
- FC 坦克大战 老巢铁墙
老巢外围铁墙E2A9:AC 80 EFEF80:A5 10 85 45 A5 45 AC D2 E2 用十六进制编辑器打开坦克大战的游戏文件搜索A5 45 F0 25 A5 0B改为AC 80 EF ...
- nyoj 284 坦克大战 简单搜索
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=284 题意:在一个给定图中,铁墙,河流不可走,砖墙走的话,多花费时间1,问从起点到终点至少 ...
随机推荐
- Linux lvs-DR模式配置详解
本篇文档主要是记录DR模式实现过程,以及各配置步骤的原理.“lvs三种模式工作原理”中描述了LVS的NAT.DR.TUN三种模式的工作原理. DR模式是通过director将报文源和目标MAC地址修改 ...
- opencontrail—VXLAN模式下数据包的传输过程
在这篇文章中,我们将看到VM生成的数据包如何能够到达另一个VM或外部资源,Neutron使用OpenContrail插件的上下文中的关键概念/组件是什么. 我们将重点介绍OpenContrail,它如 ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- plink计算两个SNP位点的连锁不平衡值(LD)
PLINK提供了“--ld”的参数计算两个SNP位点的连锁不平衡值. 命令如下: plink --file file --ld rs123 rs134 --out rs123_rs134 生成如下数据 ...
- Ceph mimic
环境 系统:Centos 7(系统最小化安装)版本:Ceph mimic 系统配置 配置主机名hostname.hosts.关闭firewalld.ssh无密码登录.ntp时间同步等,过程略. 保存下 ...
- Apache Hadoop 2.9.2 完全分布式部署
Apache Hadoop 2.9.2 完全分布式部署(HDFS) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.环境准备 1>.操作平台 [root@node101.y ...
- 2. Java内存区域
Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区:另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存 2.1 程序计数器 程序计数器(Pr ...
- python之路(7)装饰器
前言 装饰器:为函数添加附属功能,本质为函数 原则:不修改被修饰函数的源代码 不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包 使用场景演示 定义下面函数 def cal(l): res ...
- 用SQL表达交并差操作
交-并-差的处理 SQL语言:并运算UNION,交运算INTERSECT,差运算EXCEPT 基本语法形式: 子查询{UNION [ALL] | INTERSECT [ALL] | EXPECT [A ...
- 自定义Maven Archetype模板
1. 目的 自定义Maven Archetype模板目的为了把自己辛苦搭建的基础项目可以作为模板, 方便以后可以快速的创建类似项目,免去每次搭建的麻烦 2.把基础项目打包生成archetype项目 在 ...