十三、坦克大战

#类
import pygame,time, random
from pygame.sprite import Sprite
SCREEN_WIDTH =800
SCREEN_HEIGHT =600
TEXT_COLOR = (0, 0, 0)
BG_COLOR =pygame.Color(255, 0, 0)
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
enemyTankList = []
enemyTankCount = 5
myBulletList = []
emeryBulletList =[]
explodeList = []
wallList = []
def __init__(self):
pass
#开始游戏
def startGame(self):
# 加载主窗口
pygame.display.init()
# 显示窗口大小,并且显示
MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) #返回一个窗口对象,surface对象
# 创建我方坦克
self.createMytank()
self.createEmeryTank()
self.createWall()
pygame.display.set_caption('坦克大战')
while True:
time.sleep(0.02)
MainGame.window.fill(BG_COLOR)
self.getEvent()
self.biltcreateWall()
#左上角显示
MainGame.window.blit(self.getTextSuface('Esc重生,espace射击,↑↓← →进行移动,当前坦克数量%d' %len(MainGame.enemyTankList)), (10, 10))
# 显示我方坦克
if MainGame.my_tank and MainGame.my_tank.live:
MainGame.my_tank.displayTank()
else:
del MainGame.my_tank
MainGame.my_tank = None
#显示我方子弹
self.CreateBullet()
# 显示敌方坦克
self.blitEmeryTank()
# 展示敌方坦克子弹列表
self.blitEmeryBulletList()
# 坦克移动
self.blitexplodeList()
if MainGame.my_tank and MainGame.my_tank.live:
if not MainGame.my_tank.stop:
MainGame.my_tank.moveTank()
MainGame.my_tank.bitWall()
MainGame.my_tank.mytank_hit_emerytank()
pygame.display.update()
def blitEmeryTank(self):
for emerytank in MainGame.enemyTankList:
if emerytank.live:
emerytank.displayTank()
emerytank.randMove()
emerytank.bitWall()
emerybullet = emerytank.shot()
if MainGame.my_tank and MainGame.my_tank.live:
emerytank.emery_hit_mytank()
if emerybullet:
MainGame.emeryBulletList.append(emerybullet)
else:
MainGame.enemyTankList.remove(emerytank)

def blitEmeryBulletList(self):
for emeryBullet in MainGame.emeryBulletList:
if emeryBullet.live:
emeryBullet.disployBullet()
emeryBullet.moveBullet()
emeryBullet.emeryBullet_hit_myTank()
emeryBullet.BullethitWall()
else:
MainGame.emeryBulletList.remove(emeryBullet)

def CreateBullet(self):
for myBullet in MainGame.myBulletList:
if myBullet.live:
myBullet.disployBullet()
myBullet.moveBullet()
myBullet.myBullet_hit_emeryTank()
myBullet.BullethitWall()
else:
self.myBulletList.remove(myBullet)
def blitexplodeList(self):
for explode in MainGame.explodeList:
if explode.live:
explode.displayExplode()
else:
MainGame.explodeList.remove(explode)

def createMytank(self):
MainGame.my_tank = myTank(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
music = Music("img/start.wav")
music.play()
#初始化敌方坦克,添加到列表中
def createEmeryTank(self):
top = random.randint(50, SCREEN_HEIGHT-100)
for i in range(MainGame.enemyTankCount):
left = random.randint(0, SCREEN_WIDTH-100)
speed = random.randint(1, 4)
enemy = EmeryTank(left, top, speed)
MainGame.enemyTankList.append(enemy)

def createWall(self):
top = 200
for i in range(6):
wall = Wall(142*i,top)
MainGame.wallList.append(wall)
def biltcreateWall(self):
for wall in MainGame.wallList:
if wall.live:
wall.disployWall()
else:
MainGame.wallList.remove(wall)
#结束游戏
def endGame(self):
print("你好呀,再见")
exit()
#左上角文字描述
def getTextSuface(self,text):
#初始化字体模块
pygame.font.init()
#查看所有字体
#print(pygame.font.get_fonts())
#获取字体类型对象
font=pygame.font.SysFont('kaiti', 18)
#绘制文字信息
sextSurFace=font.render(text, True, TEXT_COLOR)
return sextSurFace

#添加事件,点击关闭,关闭窗口;按下键盘的时候,判断键盘按下的是什么键
def getEvent(self):
#获取所有事件
eventList = pygame.event.get()
#遍历事件
for event in eventList:
#判断按下的键是关闭还是键盘按下
if event.type == pygame.QUIT:
self.endGame()
#如果是键盘的按键
if event.type == pygame.KEYDOWN:
if not MainGame.my_tank:
if event.key == pygame.K_ESCAPE:
self.createMytank()
if MainGame.my_tank and MainGame.my_tank.live:
if event.key == pygame.K_LEFT:
MainGame.my_tank.direction = 'L'
self.my_tank.stop = False
# MainGame.my_tank.moveTank()
print('按下左键,坦克向左移动')
elif event.key == pygame.K_RIGHT:
MainGame.my_tank.direction = 'R'
self.my_tank.stop = False
# MainGame.my_tank.moveTank()
print('按下右键,坦克向右移动')
elif event.key == pygame.K_UP:
MainGame.my_tank.direction = 'U'
self.my_tank.stop = False
# MainGame.my_tank.moveTank()
print('按下上键,坦克向上移动')
elif event.key == pygame.K_DOWN:
MainGame.my_tank.direction = 'D'
self.my_tank.stop = False
# MainGame.my_tank.moveTank()
print('按下下键,坦克向下移动')
elif event.key == pygame.K_SPACE:
if len(self.myBulletList) < 3:
print('发射子弹')
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_RIGHT or event.key == pygame.K_LEFT:
if MainGame.my_tank and MainGame.my_tank.live:
self.my_tank.stop = True


class Tank(BaseItem):
def __init__(self, left, top):
self.images = {
'U': pygame.image.load('img/p1tankU.gif'),
'R': pygame.image.load('img/p1tankR.gif'),
'L': pygame.image.load('img/p1tankL.gif'),
'D': pygame.image.load('img/p1tankD.gif')
}
#方向
self.direction = 'L'
#根据当前图片的方向,获取图片
self.image = self.images[self.direction]
#获取图片的区域
self.rect = self.image.get_rect()
#设置区域的left,top
self.rect.left = left
self.rect.top = top
#速度
self.speed = 5
# 移动开关
self.stop = True
# 增加坦克存活开关
self.live = True
#增加原来的坐标
self.oldleft = self.rect.left
self.oldtop = self.rect.top
#移动
def moveTank(self):
self.oldtop = self.rect.top
self.oldleft = self.rect.left
if self.direction == 'U' and self.rect.top>0:
self.rect.top -= self.speed
elif self.direction == 'L'and self.rect.left>0:
self.rect.left -=self.speed
elif self.direction == 'R'and self.rect.left+self.rect.height<SCREEN_WIDTH:
self.rect.left +=self.speed
elif self.direction == 'D'and self.rect.top+self.rect.height<SCREEN_HEIGHT:
self.rect.top += self.speed
#射击
def shot(self):
return Bullet(self)
def bitWall(self):
for wall in MainGame.wallList:
if pygame.sprite.collide_rect(self, wall):
self.stay()
def stay(self):
self.rect.left = self.oldleft
self.rect.top = self.oldtop
#显示
def displayTank(self):
# 获取展示的对象
self.image = self.images[self.direction]
# 调用blit方法展示
MainGame.window.blit(self.image, self.rect)
class myTank(Tank):
def __init__(self,left,top):
super(myTank, self).__init__(left,top)
def mytank_hit_emerytank(self):
for emery in MainGame.enemyTankList:
if pygame.sprite.collide_rect(self,emery):
self.stay()

class EmeryTank(Tank):

def __init__(self, left, top, speed):
super(EmeryTank, self).__init__(left,top)
# 加载图片集
self.images = {
'U': pygame.image.load('img/enemy1U.gif'),
'D': pygame.image.load('img/enemy1D.gif'),
'L': pygame.image.load('img/enemy1L.gif'),
'R': pygame.image.load('img/enemy1R.gif')
}
#坦克的方向
self.direction = self.directionRandom()
#敌方坦克的图片
self.image = self.images[self.direction]
#获取区域
self.rect = self.image.get_rect()
#设置坦克的区域
self.rect.left = left
self.rect.top = top
#速度
self.speed = speed
#移动开关
self.stop = True
self.step = 60

def directionRandom(self):
randomNum = random.randint(1, 4)
if randomNum == 1:
return 'U'
elif randomNum == 2:
return 'L'
elif randomNum == 3:
return 'R'
elif randomNum == 4:
return 'D'
def randMove(self):
if self.step <=0:
self.direction = self.directionRandom()
self.step = 60
else:
self.moveTank()
self.step -= 1

def shot(self):
n = random.randint(1, 100)
if n < 5:
return Bullet(self)
def emery_hit_mytank(self):
if pygame.sprite.collide_rect(self,MainGame.my_tank):
self.stay()

class Wall():
def __init__(self,left,top):
self.image = pygame.image.load("img/steels.gif")
self.rect = self.image.get_rect()
self.rect.left = left
self.rect.top = top
self.live = True
#续命时间
self.hg =3
#展示墙壁
def disployWall(self):
MainGame.window.blit(self.image, self.rect)

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()
#子弹的top left
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.width / 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.width / 2 - self.rect.width / 2
self.speed = 6
#子弹展示的开关
self.live = True
#子弹移动
def moveBullet(self):
if self.direction == 'U':
if self.rect.top >0:
self.rect.top -= self.speed
else:
self.live = False
elif self.direction == 'D':
if self.rect.top + self.rect.width < SCREEN_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
elif self.direction == 'R':
if self.rect.left +self.rect.width <SCREEN_WIDTH:
self.rect.left +=self.speed
else:
self.live = False
#展示子弹
def disployBullet(self):
# 将图片surface加载到窗口
MainGame.window.blit(self.image, self.rect)
def myBullet_hit_emeryTank(self):
for emerytank in MainGame.enemyTankList:
if pygame.sprite.collide_rect(emerytank, self):
emerytank.live = False
self.live = False
explode = Explode(emerytank)
MainGame.explodeList.append(explode)
def emeryBullet_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 BullethitWall(self):
for wall in MainGame.wallList:
if pygame.sprite.collide_rect(wall, self):
self.live = False
wall.hg -= 1
if wall.hg < 0:
wall.live = False
music = Music("img/hit.wav")
music.play()
class Explode():
def __init__(self,Tank):
self.rect = Tank.rect
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
#展示爆炸效果
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 Music():
def __init__(self, filename):
self.filename = filename
pygame.mixer.init()
pygame.mixer.music.load(self.filename)
#播放方法
def play(self):
pygame.mixer.music.play()

if __name__ =='__main__':
MainGame().startGame()

 

posted @ 2020-02-15 21:47  小熊尤里  阅读(150)  评论(0编辑  收藏  举报