《坦克大战》
import pygame
import sys
import time
from random import randint
from pygame.locals import *
#坦克游戏中所有对象的父类
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):
#self.screem = screem
super().init(screem)
self.direction=“D”#默认图片方向下
self.speed=5#坦克移动的速度
self.stop=False
self.images={}
“”"
从此处拿走图片
“”"
self.images[“L”] = pygame.image.load(“images/EL.gif”)
self.images[“R”] = pygame.image.load(“images/Er.gif”)
self.images[“U”] = pygame.image.load(“images/EU.gif”)
self.images[“D”] = pygame.image.load(“images/ED.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.top=self.oldtop
self.rect.left=self.oldleft
def move(self):
if not self.stop:
self.oldleft = self.rect.left
self.oldtop = self.rect.top
if self.direction == "L":
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 = Missle(self.screem,self)#
return m
class My_Tank(Tank):
def __init__(self,screem):
super().__init__(screem,275,400)#我方坦克的初始位置,屏幕中下方位置
self.stop = True
self.live = True
self.direction = "D" # 默认图片方向下
#self.speed = 5 # 坦克移动的速度
#self.stop = False
self.images = {}
self.images["L"] = pygame.image.load("images/WL.gif")
self.images["R"] = pygame.image.load("images/WR.gif")
self.images["U"] = pygame.image.load("images/WU.gif")
self.images["D"] = pygame.image.load("images/WD.gif")
#self.image = self.images[self.direction] # 坦克的图像由方向决定
# self.rect = self.image.get_rect()
# self.rect.left = left
#self.rect.top = top
#self.live = True
#enermy_missle_list
def hit_enermy_missile(self):
hit_list = pygame.sprite.spritecollide(self,tankMain.enermy_missle_list,False)
for m in hit_list:
m.live=False
tankMain.enermy_missle_list.remove(m)
self.live=False
explode = Explode(self.screem,self.rect)
tankMain.explode_list.append(explode)
class Enermy_Tank(Tank):
def __init__(self,screem):
super().__init__(screem,randint(1,5)*100,50)
self.step=6#坦克按照某个方向移动的步数
def get_random_direction(self):
r = randint(0, 4) # 坦克移动停止的随机数
if r == 4:
self.stop = True
elif r == 1:
self.direction = "L"
self.stop=False
elif r == 2:
self.direction = "R"
self.stop = False
elif r == 0:
self.direction = "U"
self.stop = False
elif r == 3:
self.direction = "D"
self.stop = False
#敌方坦克按照确定的随机方向连续移动6步再改为其他方向
def random_move(self):
if self.live:
if self.step==0:
self.get_random_direction()
self.step=6
else:
self.move()
self.step-=1
def random_fire(self):
r = randint(0,60)
if r==10 or r==20 or r==40 or r==40:
m = self.fire()
tankMain.enermy_missle_list.add(m)
else:
return
class Missle(BaseItem):
width=12
height=12
def init(self,screem,tank):
super().init(screem)
self.tank=tank
self.direction = tank.direction # 炮弹的方向有坦克决定
self.speed = 12 # 坦克移动的速度
self.images = {}
self.images["L"] = pygame.image.load("images/ML.gif")
self.images["R"] = pygame.image.load("images/MR.gif")
self.images["U"] = pygame.image.load("images/MU.gif")
self.images["D"] = pygame.image.load("images/MD.gif")
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":
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.enermy_list,False)
for e in hit_list:
e.live=False
tankMain.enermy_list.remove(e)
self.live=False
explode=Explode(self.screem,e.rect)
tankMain.explode_list.append(explode)
class Explode(BaseItem):
def init(self,screem,rect):
super().init(screem)
self.live=True
self.images=[pygame.image.load("images/0.gif"),\
pygame.image.load("images/1.gif"),\
pygame.image.load("images/2.gif"),\
pygame.image.load("images/3.gif"),\
pygame.image.load("images/4.gif"),\
pygame.image.load("images/5.gif"),\
pygame.image.load("images/5.gif"),\
pygame.image.load("images/7.gif")]
self.step=0
self.rect=rect#爆炸的位置和发生位置前,坦克碰到炮弹的位置一样
#display是循环调用的
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 tankMain():
width=600
height=500
my_tank_missile_list = []
my_tank = None
wall=None
# enermy_list = []
enermy_list = pygame.sprite.Group()#敌方坦克的
explode_list=[]
enermy_missle_list = pygame.sprite.Group()
#for i in range(1,6):
# enermy_list.add(Enermy_Tank(screem))#把地方坦克放到组里面
def startGame(self):
pygame.init()#模块初始化
#创建一个屏幕,大小为600 ,500(宽和高)
screem=pygame.display.set_mode((tankMain.width,tankMain.height),0,32)
pygame.display.set_caption("坦克大战")
tankMain.wall = Wall(screem,150,150)#,250,50
tankMain.my_tank = My_Tank(screem)
if len(tankMain.enermy_list)== 0:
for i in range(1,6):
tankMain.enermy_list.add(Enermy_Tank(screem))
while True:
if len(tankMain.enermy_list) < 5 :
tankMain.enermy_list.add(Enermy_Tank(screem))
screem.fill((0,0,0))#设置屏幕背景为黑
for i,text in enumerate(self.write_text(),0):
screem.blit(text,(0,5+(15*i)))
#显示墙和其他的进行碰撞检测
tankMain.wall.display()
tankMain.wall.hit_other()
self.get_event(tankMain.my_tank,screem)
if tankMain.my_tank:
#tankMain.my_tank.hit_enermy_missile()
tankMain.my_tank.hit_enermy_missile()
if tankMain.my_tank and tankMain.my_tank.live:
tankMain.my_tank.display()
tankMain.my_tank.move()
else:
#sys.exit()
#tankMain.my_tank=None
tankMain.my_tank=None
for enermy in tankMain.enermy_list:
enermy.display()
enermy.random_move()
enermy.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.enermy_missle_list:
if m.live:
m.display()
m.move()
else:
tankMain.enermy_list.remove(m)
for explode in tankMain .explode_list:
explode.display()
time.sleep(0.07)#每次休眠0.07秒,跳到下一帧
pygame.display.update()#重复设置
def overGame(self):
pygame.quit()
sys.exit()
def write_text(self):
font = pygame.font.SysFont("simsunnsimsun",12)#定义一个字体
txt_sf1 = font.render("敌方坦克数量为:%d"%len(tankMain.enermy_list),True,(255,0,0))#根据字体创建一个文字的图像
txt_sf2 = font.render("我方子弹数量为:%d"%len(tankMain.my_tank_missile_list), True, (255, 0, 0))
return txt_sf1,txt_sf2
def get_event(self,my_tank,screem):#获得事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.overGame()
#if event.type == pygame.KEYDOWN:
# self.overGame()
if event.type==KEYDOWN and (not my_tank) and event.key == K_n:
print("按 n键 复活")
tankMain.my_tank = My_Tank(screem)
if event.type == pygame.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==pygame.K_ESCAPE:
self.overGame()
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 event.key==K_RIGHT or event.key==K_UP or event.key==K_DOWN:
my_tank.stop = True
class Wall(BaseItem):
def __init__(self,screem,left,top):#,width,height
super().__init__(screem)
#self.rect = Rect(left,top,width,height)
#self.color = (255, 0, 0)
self.image = pygame.image.load("images/walll.gif")
self.rect = self.image.get_rect()
self.rect.left=left
self.rect.top=top
#self.rect.bottom = top+hight
#self.rect.right = left+width
self.screem.blit(self.image, self.rect)
def display(self):
self.screem.blit(self.image,self.rect)
#self.color=(255,0,0)
#针对墙和其他坦克的碰撞检测
def hit_other(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.enermy_list)!=0:
hit_list=pygame.sprite.spritecollide(self,tankMain.enermy_list ,False )
for e in hit_list:
e.stop=True
e.stay()
if len(tankMain.my_tank_missile_list)!=0 :
hit_list=pygame.sprite.spritecollide(self,tankMain.my_tank_missile_list ,False )
for e in hit_list:
e.stop=True
if len(tankMain.enermy_missle_list)!=0:
hit_list = pygame.sprite.spritecollide(self,tankMain.enermy_missle_list, False)
for e in hit_list:
e.stop = True
game = tankMain()
game.startGame()
game.overGame()
图片百度云连接
mima:fz63