import pygame, time, random
BG_COLOR = pygame.Color(0, 0, 0)
TEXT_COLOR = pygame.Color(255, 0, 0)
W_WIDTH = 700
W_HIGHT = 500
# 1、初始化
class MainTanke():
window = None
myTK = None
# 创建列表储存敌方坦克
diTanKeList = []
# 定义敌方坦克的初始数量
diTanKeCount = 5
# 存储子弹列表
BulletList = []
# 敌方子弹列表
diBulletList = []
# 爆炸列表
blastList = []
# 墙壁列表
wallList = []
# 开始游戏
def startGame(self):
# 初始化
pygame.display.init()
# 设置长宽
MainTanke.window = pygame.display.set_mode([W_WIDTH, W_HIGHT])
# 加载坦克、初始化
self.creatMyTanKe()
# 初始化敌方坦克,并加入列表中
self.creatDiTanKe()
# 创建墙壁
self.creatWalls()
# 设置窗口标题
pygame.display.set_caption('坦克1.1.1')
# 一直显示窗口
while True:
# 循环频率降低
time.sleep(0.02)
# 设置窗口填充色
MainTanke.window.fill(BG_COLOR)
# 调用事件处理方法
self.event()
MainTanke.window.blit(self.getDiTanKeText('敌方坦克剩余数量:%d' % len(MainTanke.diTanKeList)), (10, 10))
# 调用显示墙壁
self.biltWalls()
if MainTanke.myTK and MainTanke.myTK.live:
# 显示坦克
MainTanke.myTK.displayTanKe()
else:
del MainTanke.myTK
MainTanke.myTK = None
# 循环遍历敌方坦克列表展示敌方坦克
self.blitDTK()
# 判断坦克是否要移动
if MainTanke.myTK and MainTanke.myTK.live:
if not MainTanke.myTK.stop:
# 调用坦克移动方法
MainTanke.myTK.moveTanKe()
# 调用坦克碰撞墙壁的方法
MainTanke.myTK.hitWallTK()
# 调用子弹方法
self.blitBullet()
# 调用敌方坦克子弹
self.dBlitBullet()
# 展示爆炸效果
self.displayBlast()
pygame.display.update()
# 创建我方坦克
def creatMyTanKe(self):
MainTanke.myTK = TanKe(320, 420)
# 初始化敌方坦克,加入列表
def creatDiTanKe(self):
top = 80
for i in range(MainTanke.diTanKeCount):
left = random.randint(0, 640)
seep = random.randint(1, 6)
diTanKe = EnemyTanKe(left, top, seep)
MainTanke.diTanKeList.append(diTanKe)
# 将子弹加入到窗口
def blitBullet(self):
for buf in MainTanke.BulletList:
# 如果子弹活着显示,false则不显示删除
if buf.live:
buf.displayBullet()
buf.moveBullet()
# 调用子弹与坦克的碰撞
buf.hitTanKe()
# 子弹与墙壁的碰撞
buf.hitWall()
else:
MainTanke.BulletList.remove(buf)
# 循环遍历敌方坦克列表展示敌方坦克
def blitDTK(self):
for diTK in MainTanke.diTanKeList:
if diTK.live:
diTK.displayTanKe()
diTK.randMove()
diTK.hitWallTK()
# 调用敌方坦克射击方法
dBullet = diTK.fireBullet()
# 将敌方子弹存入列表
# 如果敌方子弹返回值为none则不加入列表
if dBullet:
MainTanke.diBulletList.append(dBullet)
else:
MainTanke.diTanKeList.remove(diTK)
# 将敌方子弹加入到窗口
def dBlitBullet(self):
for dbuf in MainTanke.diBulletList:
# 如果子弹活着显示,false则不显示删除
if dbuf.live:
dbuf.displayBullet()
dbuf.moveBullet()
if MainTanke.myTK and MainTanke.myTK.live:
dbuf.hitMyTanKe()
dbuf.hitWall()
else:
MainTanke.diBulletList.remove(dbuf)
# 展示爆炸效果
def displayBlast(self):
for blas in MainTanke.blastList:
if blas.live:
blas.displayBlast()
else:
MainTanke.blastList.remove(blas)
# 创建墙壁
def creatWalls(self):
for i in range(6):
wall = Wall(130 * i, 240)
MainTanke.wallList.append(wall)
# 显示墙壁
def biltWalls(self):
for wall in MainTanke.wallList:
if wall.live:
wall.displayWall()
else:
MainTanke.wallList.remove(wall)
# 获取敌方坦克数量
def getDiTanKeText(self, text):
# 初始化字体模块
pygame.font.init()
# 查看当前系统自带字体
# pygame.font.get_fonts()
# 获取字体对象
font = pygame.font.SysFont('kaiti', 18)
# 绘制文本信息
diTanKeN = font.render(text, True, TEXT_COLOR)
return diTanKeN
# 获取事件
def event(self):
# 获取事件列表
eventList = pygame.event.get()
# 遍历事件
for event in eventList:
# 判断遍历的哪个事件(关闭、按键上、下、左、右)
if event.type == pygame.QUIT:
self.endGame()
# 判断按下的键是什么
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE and not MainTanke.myTK:
# 创建我方坦克
self.creatMyTanKe()
if MainTanke.myTK and MainTanke.myTK.live:
# 上
if event.key == pygame.K_UP:
# 切换坦克方向并且调用移动方法
MainTanke.myTK.direction = 'U'
MainTanke.myTK.stop = False
# MainTanke.myTK.moveTanKe()
print("坦克向上")
# 下
if event.key == pygame.K_DOWN:
# 切换坦克方向并且调用移动方法
MainTanke.myTK.stop = False
MainTanke.myTK.direction = 'D'
# MainTanke.myTK.moveTanKe()
print("坦克向下")
# 左
if event.key == pygame.K_LEFT:
# 切换坦克方向并且调用移动方法
MainTanke.myTK.direction = 'L'
MainTanke.myTK.stop = False
# MainTanke.myTK.moveTanKe()
print("坦克向左")
# 右
if event.key == pygame.K_RIGHT:
# 切换坦克方向并且调用移动方法
MainTanke.myTK.direction = 'R'
MainTanke.myTK.stop = False
# MainTanke.myTK.moveTanKe()
print("坦克向右")
# 空格
if event.key == pygame.K_SPACE:
print('发射子弹')
if len(MainTanke.BulletList) < 3:
# 产生一个子弹
m = Bullet(MainTanke.myTK)
# 存入列表
MainTanke.BulletList.append(m)
else:
print('正在填装子弹')
# 键盘松开stop值改为True
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN:
if MainTanke.myTK and MainTanke.myTK.live:
MainTanke.myTK.stop = True
# 结束游戏
def endGame(self):
print("成功关闭")
exit()
# 中介商,继承精灵类
class BaseItem(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
# 2、坦克
class TanKe(BaseItem):
# 坦克的位置left,top
def __init__(self, left, top):
self.images = {
'U': pygame.image.load('imgs/p1tankU.gif'),
'D': pygame.image.load('imgs/p1tankD.gif'),
'L': pygame.image.load('imgs/p1tankL.gif'),
'R': pygame.image.load('imgs/p1tankR.gif')
}
# 设置坦克默认方向
self.direction = 'U'
# 根据方向获取图片
self.image = self.images[self.direction]
# 根据图片获取区域
self.rect = self.image.get_rect()
# 设置区域的位置
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 moveTanKe(self):
# 判断坦克方向并进行移动
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= self.speed
elif self.direction == 'D':
if self.rect.top < 440:
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 < 640:
self.rect.left += self.speed
# 还原方法
def stay(self):
self.rect.left = self.oldLeft
self.rect.top = self.oldTop
# 碰撞墙壁方法
def hitWallTK(self):
for wall in MainTanke.wallList:
if pygame.sprite.collide_rect(self, wall):
self.stay()
# 发射子弹
def fireBullet(self):
return Bullet(self)
# 展示坦克
def displayTanKe(self):
# 获取坦克对象
self.image = self.images[self.direction]
# 将坦克放入画布中
MainTanke.window.blit(self.image, self.rect)
# 2.1我方坦克
class MyTanke(TanKe):
def __init__(self):
pass
# 2.2敌方坦克
class EnemyTanKe(TanKe):
def __init__(self, left, top, seep):
super(EnemyTanKe, self).__init__(left, top)
# 获取敌方坦克图片
self.images = {
'U': pygame.image.load('imgs/enemy1U.gif'),
'D': pygame.image.load('imgs/enemy1D.gif'),
'L': pygame.image.load('imgs/enemy1L.gif'),
'R': pygame.image.load('imgs/enemy1R.gif')
}
# 设置坦克默认方向
self.direction = self.randDirection()
# 根据方向获取图片
self.image = self.images[self.direction]
# 根据图片获取区域
self.rect = self.image.get_rect()
# 设置区域的位置
self.rect.left = left
self.rect.top = top
# 设置坦克的速度
self.speed = random.randint(2, 6)
# 坦克的移动开关
self.stop = True
# 设置坦克移动部署
self.step = random.randint(40, 60)
def randDirection(self):
num = random.randint(1, 4)
if num == 1:
return 'U'
if num == 2:
return 'D'
if num == 3:
return 'L'
if num == 4:
return 'R'
def randMove(self):
if self.step <= 0:
self.direction = self.randDirection()
self.step = random.randint(40, 60)
else:
self.moveTanKe()
self.step -= 1
def fireBullet(self):
num = random.randint(1, 50)
if num == 50:
return Bullet(self)
# 3、子弹
class Bullet(BaseItem):
def __init__(self, tanke):
# 加载图片
self.image = pygame.image.load('imgs/enemymissile.gif')
# 获取子弹位置
# 子弹发射方向根据坦克方向决定
self.direction = tanke.direction
# 获取区域
self.rect = self.image.get_rect()
if self.direction == 'U':
self.rect.top = tanke.rect.top - self.rect.height
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
if self.direction == 'D':
self.rect.top = tanke.rect.top + tanke.rect.height
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
if self.direction == 'L':
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.width / 2
self.rect.left = tanke.rect.left - self.rect.width
if self.direction == 'R':
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.height / 2
self.rect.left = tanke.rect.left + tanke.rect.width
# 子弹的速度
self.sppe = 7
# 记录子弹状态
self.live = True
# 子弹移动
def moveBullet(self):
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= self.sppe
else:
self.live = False
if self.direction == 'D':
if self.rect.top < W_HIGHT - self.rect.height:
self.rect.top += self.sppe
else:
self.live = False
if self.direction == 'L':
if self.rect.left > 0:
self.rect.left -= self.sppe
else:
self.live = False
if self.direction == 'R':
if self.rect.left < W_WIDTH - self.rect.width:
self.rect.left += self.sppe
else:
self.live = False
# 显示子弹
def displayBullet(self):
# 将图片加载到窗口
MainTanke.window.blit(self.image, self.rect)
# 子弹碰撞坦克
def hitTanKe(self):
for diTanke in MainTanke.diTanKeList:
if pygame.sprite.collide_rect(diTanke, self):
# 产生爆炸效果,将爆炸效果加入爆炸列表中
blast = Blast(diTanke)
MainTanke.blastList.append(blast)
self.live = False
diTanke.live = False
# 子弹碰撞我方坦克
def hitMyTanKe(self):
if pygame.sprite.collide_rect(self, MainTanke.myTK):
# 产生爆炸效果
# 爆炸效果加入列表
blast = Blast(MainTanke.myTK)
MainTanke.blastList.append(blast)
# 修改子弹状态
self.live = False
# 修稿我方坦克状态
MainTanke.myTK.live = False
# 子弹与墙壁碰撞
def hitWall(self):
for wall in MainTanke.wallList:
if pygame.sprite.collide_rect(wall, self):
# 修改子弹属性
self.live = False
# 碰撞减少生命值
wall.hp -= 1
# 生命值为0墙壁消失
if wall.hp <= 0:
wall.live = False
# 4、爆炸效果
class Blast():
def __init__(self, tanke):
self.rect = tanke.rect
self.step = 0
self.images = [
pygame.image.load('imgs/blast0.gif'),
pygame.image.load('imgs/blast1.gif'),
pygame.image.load('imgs/blast2.gif'),
pygame.image.load('imgs/blast3.gif'),
pygame.image.load('imgs/blast4.gif')
]
self.image = self.images[self.step]
self.live = True
# 显示爆炸效果方法
def displayBlast(self):
if self.step < len(self.images):
MainTanke.window.blit(self.image, self.rect)
self.image = self.images[self.step]
self.step += 1
else:
self.live = False
self.step = 0
# 5、墙壁
class Wall():
def __init__(self, left, top):
self.image = pygame.image.load('imgs/steels.gif')
self.rect = self.image.get_rect()
self.rect.left = left
self.rect.top = top
# 判断墙壁是否展示
self.live = True
# 墙壁生命值
self.hp = 3
# 显示墙壁
def displayWall(self):
MainTanke.window.blit(self.image, self.rect)
# 6、音效
class Acoustics():
def __init__(self):
pass
# 播放音效方法
def startAcoustics(self):
pass
if __name__ == '__main__':
MainTanke().startGame()
老师,现在坦克碰到墙壁就会返回出生点,是坐标只记录了出生坐标吗