import pygame
import time
from random import *
#界面宽度和高度
Screen_width=900
Screen_Height=600
#背景颜色(白色)
bg = pygame.Color(255,255,255)####这里要用RGB值
#左上角文字颜色
zcolor = pygame.Color(255,0,0)
#使用pygame的精灵类
Sprite=pygame.sprite.Sprite
#初始化精灵类
class BaseItem(Sprite):
def init(self, color, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.init(self)
#主函数
class MainGame():
#初始化窗口
window = None
#初始化
my_tank=None
MyTankStop=True
#敌方坦列表
EnemyList = []
#敌方坦克数量
EnemyCount = 5
#我方子弹列表
MyBulletList=[]
#敌方子弹列表
EnemyBulletList=[]
#爆炸效果列表
ExplodeList=[]
#存留的墙体
WallList=[]
#我方是否活着
IamLive=None
def __int__(self):
pass
#开始游戏
def StartGame(self):
#初始化pygame
pygame.display.init()
#创建窗口
MainGame.window=pygame.display.set_mode([Screen_width,Screen_Height])######
#生成我方坦克
MainGame.my_tank =self.CreatMyTank()
#窗口标题
pygame.display.set_caption('坦克大战v1.0')
#创建敌方坦克
self.CreatEnemy()
#创建墙体
self.CreatWall()
#循环显示窗口
while True:
time.sleep(0.05)
#窗口背景色填充
MainGame.window.fill(bg)
#获取事件
self.GetEvent()####################调用才能生效
#左上角展示剩余敌人
MainGame.window.blit(self.GetTextSurface('敌方坦克数量{}'.format(len(MainGame.EnemyList))),(10,10))
#展示我方坦克
if MainGame.IamLive:
MainGame.my_tank.display()
self.BlitEnemy()#############刷新显示敌人
#显示我方子弹
self.BlitMyBullet()
#显示敌方子弹
self.BlitEnemyBullet()
#判断敌方爆炸
self.CreatEnemyExplode()
#显示敌方爆炸
self.ShowExplode()
#我方是否阵亡
self.IamHit()
#显示墙体
self.BlitWall()
#我方坦克移动
if MainGame.IamLive and MainGame.my_tank:
if not MainGame.MyTankStop:
MainGame.my_tank.Move()
#刷新窗口
pygame.display.update()
#结束游戏
def EndGame(self):
print('谢谢使用,欢迎下次使用!')
exit()
#获取事件
def GetEvent(self):
#事件列表
eventList = pygame.event.get()
for event in eventList:
#判断按下的键是否是退出
if event.type==pygame.QUIT:
self.EndGame()
if not (MainGame.my_tank and MainGame.IamLive):
if event.type==pygame.KEYDOWN:
#我方阵亡后按下ESC键重生
if event.key==pygame.K_ESCAPE:
self.CreatMyTank()
#如果按下键盘
if MainGame.my_tank and MainGame.IamLive:
if event.type==pygame.KEYDOWN:
#判断按下的是哪个方向键
if event.key == pygame.K_LEFT:
print('坦克向左移动')
MainGame.my_tank.direction='L'
MainGame.MyTankStop = False
elif event.key==pygame.K_RIGHT:
print('坦克向右移动')
MainGame.my_tank.direction='R'
MainGame.MyTankStop = False
elif event.key == pygame.K_UP:
print('坦克向上移动')
MainGame.my_tank.direction='U'
MainGame.MyTankStop = False
elif event.key == pygame.K_DOWN:
print('坦克向下移动')
MainGame.my_tank.direction='D'
MainGame.MyTankStop = False
elif event.key==pygame.K_SPACE:
print('发射子弹')
if len(MainGame.MyBulletList)<3:
#生成子弹添加到我方子弹列表
MyBullet = Bullet(MainGame.my_tank)
self.MyBulletList.append(MyBullet)
#播放射击声
music = Music('../img/fire.wav')
music.play()
#方向键抬起则停止移动
if event.type==pygame.KEYUP:
if event.key==pygame.K_UP or event.key==pygame.K_DOWN or event.key==pygame.K_LEFT or event.key==pygame.K_RIGHT:
##!!!!!这里要用4个event.key判断
MainGame.MyTankStop=True
#左上角文字
def GetTextSurface(self,Text):
#初始化字体模块
pygame.font.init()
#查看所有字体名称
#print(pygame.font.get_fonts())
#根据系统字体创建一个font对象
My_font=pygame.font.SysFont('kaiti',18)
TextSurface=My_font.render(Text,True,zcolor,pygame.image.load('../01.gif'))
return TextSurface
def CreatEnemy(self):
top =100
for i in range(MainGame.EnemyCount):
#生成敌方坦克的横向位置
left = randint(0, 800)
#敌方坦克随机移动速度
speed = randint(4,7)
#添加到敌方坦克列表
Enemy =EnemyTank(left,top,speed)
MainGame.EnemyList.append(Enemy)
#显示敌方坦克
def BlitEnemy(self):
for i in MainGame.EnemyList:
if i.live:
i.display()
i.RandMove()
else:
MainGame.EnemyList.remove(i)
#显示我方子弹
def BlitMyBullet(self):
for bullet in MainGame.MyBulletList:
bullet.shotwall()
if bullet.live==True:
bullet.display()
bullet.move()
else:
MainGame.MyBulletList.remove(bullet)
#显示敌方子弹
def BlitEnemyBullet(self):
for bullet in MainGame.EnemyBulletList:
bullet.shotwall()
if bullet.live==True:
bullet.display()
bullet.move()
#判断是否命中敌方并生成爆炸效果
def CreatEnemyExplode(self):
for enemy in MainGame.EnemyList:
for mybullet in MainGame.MyBulletList:
#pygame的sprite类判断两个矩形是否碰撞
if pygame.sprite.collide_rect(mybullet,enemy):
enemy.live=False
mybullet.live=False
music= Music('../img/hit.wav')
music.play()
#在敌方坦克位置生成爆炸并添加到爆炸列表
boom=Explode(enemy)
MainGame.ExplodeList.append(boom)
#展示爆炸
def ShowExplode(self):
for boom in MainGame.ExplodeList:
if boom.live:
boom.display()
else:
boom.live=False
#我方阵亡
def IamHit(self):
for enemybullet in MainGame.EnemyBulletList:
if MainGame.IamLive and MainGame.my_tank:
if pygame.sprite.collide_rect(MainGame.my_tank,enemybullet):
MainGame.IamLive=False
enemybullet.live=False
music = Music('../img/hit.wav')
music.play()
#我方爆炸
bang = Explode(MainGame.my_tank)
MainGame.ExplodeList.append(bang)
if MainGame.my_tank:
del MainGame.my_tank
MainGame.my_tank = None
#生成我方坦克
def CreatMyTank(self):
MainGame.my_tank=MyTank(370,350)
MainGame.IamLive=True
music = Music('../img/start.wav')
music.play()
return MainGame.my_tank
#展示墙体
def BlitWall(self):
for wall in MainGame.WallList:
if wall.hp<=0:
wall.live=False
if wall.live :
wall.display()
else:
MainGame.WallList.remove(wall)
print(len(MainGame.WallList))
#生成一横排墙体
def CreatWall(self):
for i in range(6):
wall1=Wall(i*150,225)
MainGame.WallList.append(wall1)
#Tank类继承来自Sprite的BaseItem类
class Tank(BaseItem):
def init(self,t_x,t_y):
#4个图片代表坦克4个方向
self.images={
‘U’:pygame.image.load(’…/img/p1tankU.gif’),
‘D’:pygame.image.load(’…/img/p1tankD.gif’),
‘L’:pygame.image.load(’…/img/p1tankL.gif’),
‘R’:pygame.image.load(’…/img/p1tankR.gif’)
}
self.direction = ‘U’
#根据当前图片方向获取图片
self.image=self.images[self.direction]
#获取图片区域对象
self.rect=self.image.get_rect()
#设置图片的坐标
self.rect.x=t_x############
self.rect.y=t_y##############
#移动速度
self.speed = 10
#是否存活
self.live=True
#判断撞墙
self.Hitwall=False
#展示坦克
def display(self):
self.image=self.images[self.direction]
MainGame.window.blit(self.image,self.rect)
#移动
def Move(self):
self.oldrect_x=self.rect.x
self.oldrect_y=self.rect.y
if self.direction=='L' and self.rect.x>0:
self.rect.x-=self.speed
if self.direction=='R' and self.rect.x+self.rect.height<Screen_width:
self.rect.x+=self.speed
if self.direction=='U' and self.rect.y>0:
self.rect.y-=self.speed
if self.direction=='D' and self.rect.y+self.rect.height<Screen_Height:
self.rect.y+=self.speed
#如果移动会撞墙则停止移动
self.hitwall()
#如果移动会撞坦克则停止移动
self.hittank()
#射击
def Shot(self):
pass
移动后撞墙则回到移动前位置
def hitwall(self):
for wall in MainGame.WallList:
if pygame.sprite.collide_rect(self,wall):
self.rect.x=self.oldrect_x
self.rect.y=self.oldrect_y
与撞墙同理
def hittank(self):
for tank in MainGame.EnemyList:
if tank!=self:
if pygame.sprite.collide_rect(self,tank):
self.rect.x = self.oldrect_x
self.rect.y = self.oldrect_y
#我方坦克继承自Tank类
class MyTank(Tank):
def init(self,x,y):
super().init(x,y)
MainGame.IamLive=True
#敌方坦克jic自Tank类
class EnemyTank(Tank):
def init(self,rect_x,rect_y,speed):
super().init(rect_x,rect_y)
self.images={
‘U’:pygame.image.load(’…/img/enemy1U.gif’),
‘D’:pygame.image.load(’…/img/enemy1D.gif’),
‘R’:pygame.image.load(’…/img/enemy1R.gif’),
‘L’:pygame.image.load(’…/img/enemy1L.gif’),
}
#敌方坦克生成时方向随机
self.direction = self.randdirection()
self.image = self.images[self.direction]
#坦克的rect位置
self.rect = self.image.get_rect()
self.rect.x=rect_x
self.rect.y=rect_y
self.speed=speed
#移动开关键
self.Flag=True
#走70步后随机改变方向
self.step=70
#生成随机方向
def randdirection(self):
self.direc = randint(1,4)
if self.direc == 1:
return ‘U’
elif self.direc ==2:
return ‘L’
elif self.direc ==3:
return ‘D’
elif self.direc ==4:
return ‘R’
#敌方坦克随机移动
def RandMove(self):
if self.step<=0:
self.direction=self.randdirection()
self.step=70
else:
self.Move()
self.step-=1
self.Shot()
#敌方坦克随机开火
def Shot(self):
num = randint(0,200)
if num<10:
EnenyBullet = Bullet(self)
MainGame.EnemyBulletList.append(EnenyBullet)
#墙体类继承自Sprite
class Wall(BaseItem):
def init(self,x,y):
self.image=pygame.image.load(’…/img/steels.gif’)
self.rect=self.image.get_rect()
self.live=True
self.hp=3
self.rect.x=x
self.rect.y=y
#显示墙体
def display(self):
MainGame.window.blit(self.image,self.rect)
#爆炸类
class Explode():
def init(self,tank):
self.rect=tank.rect
#爆炸过程由从小到大5张图片构成
self.images=[
pygame.image.load(’…/img/blast0.gif’),
pygame.image.load(’…/img/blast1.gif’),
pygame.image.load(’…/img/blast2.gif’),
pygame.image.load(’…/img/blast3.gif’),
pygame.image.load(’…/img/blast4.gif’)
]
self.step = 0
self.image=self.images[self.step]
self.live=True
#逐渐显示爆炸的5张图片,获得爆炸效果
def display(self):
if self.live:
if self.step<5:
self.image = self.images[self.step]
MainGame.window.blit(self.image,self.rect)
self.step+=1
else:
self.live=False
self.step=0
#声音类
class Music():
#初始化pygame.mixer
def init(self,filename):
pygame.mixer.init()
#加载音乐
pygame.mixer.music.load(filename)
#播放
def play(self):
pygame.mixer.music.play()
#子弹类
class Bullet(BaseItem):
def init(self,tank):
#加载图片
self.image = pygame.image.load(’…/img/enemymissile.gif’)
#子弹方向
self.direction = tank.direction
#获取区域
self.rect = self.image.get_rect()
#子弹移动速度
self.speed = 10
#子弹是否存在
self.live =True
#子弹的初始坐标和坦克方向有关
if self.direction == 'U':
self.rect.x=tank.rect.x + tank.rect.width/2 - self.rect.width/2
self.rect.y=tank.rect.y - self.rect.height
if self.direction == 'D':
self.rect.x=tank.rect.x + tank.rect.width/2 - self.rect.width/2
self.rect.y=tank.rect.y + self.rect.height + tank.rect.height
if self.direction == 'L':
self.rect.x=tank.rect.x - self.rect.height
self.rect.y=tank.rect.y - self.rect.width/2 + tank.rect.width/2
if self.direction == 'R':
self.rect.x=tank.rect.x + self.rect.height + tank.rect.height
self.rect.y=tank.rect.y - self.rect.width/2 + tank.rect.width/2
#子弹的移动和碰撞
def move(self):
if self.direction=='U':
if self.rect.y>0:
self.rect.y-=self.speed
else:
self.live=False
if self.direction=='D':
if self.rect.y<(Screen_Height-self.rect.height):
self.rect.y+=self.speed
else:
self.live=False
if self.direction=='L':
if self.rect.x>0:
self.rect.x-=self.speed
else:
self.live=False
if self.direction=='R':
if self.rect.x<(Screen_width-self.rect.height):
self.rect.x+=self.speed
else:
self.live=False
def display(self):
#展示子弹
MainGame.window.blit(self.image,self.rect)
#子弹撞墙
def shotwall(self):
for wall in MainGame.WallList:
if pygame.sprite.collide_rect(self,wall):
self.live=False
wall.hp-=1
if name==‘main’:
MainGame().StartGame()
‘’‘有个小BUG 自己有时候会无缘无故爆炸’’’