老师,按原代码,加载不出来墙壁,不知道哪里出来问题
'''
新增优化功能:完善墙壁类
'''
import pygame, time, random
from pygame.sprite import Sprite
SCREEN_WIDTH = 700
SCREEN_HEIGHT = 500
BG_COLOR = pygame.Color(0, 0, 0)
COLOR_RED = pygame.Color(255, 0, 0)
# 定义一个基类,该类继承精灵类,就有精灵的所有方法
# 要发生碰撞的坦克类,子弹类就继承该类,就能继承精灵类的方法,实现碰撞
class BsaeItem(Sprite):
def __init__(self, color, width, height):
pygame.sprite.Sprite.__init__(self)
# 主类,定义了开始游戏、结束游戏、获取事件、文字绘制的方法
# 增加初始化敌坦克方法、
class MainGame():
window = None
# 创建我方坦克
TANKE_P1 = None
# 定义一个列表,存储敌方坦克
diTankeList = []
# 定义敌方坦克的数量
diTankeCount = 5
# 定义存储我方子弹的列表
myBulletList = []
# y定义存储敌方坦克子弹的列表
diBulletList = []
# 定义一个存储爆炸效果的列表
explodeList = []
# 定义一个存储墙壁的列表
wallList = []
def __init__(self):
pass
# 定义游戏开始的方法
def startGame(self):
# 加载主窗口
# 初始化窗口
pygame.display.init()
# 设置窗口的大小及显示
MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption('坦克大战1.0')
# 初始化我方坦克
self.createmyTanke()
# 初始化敌方坦克
self.creatediTanke()
while True:
# 使坦克移动得速度慢一点
time.sleep(0.02)
# 给窗口设置填充色
MainGame.window.fill(BG_COLOR)
# 事件要一直监听
self.getEvnet()
# 将绘制文字得到的小画布粘贴到窗口
MainGame.window.blit(self.getTextSurface('剩余敌方坦克%d辆' % len(MainGame.diTankeList)), (5, 5))
# 调用坦克显示方法
# 需要判断我方坦克是否存活
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
MainGame.TANKE_P1.display()
else:
# 删除我方坦克
del MainGame.TANKE_P1
MainGame.TANKE_P1 = None
# 循环遍历敌方坦克列表,展示敌方坦克
self.blitdiTanke()
# 循环遍历显示我方坦克子弹
self.blitMyBullet()
# 循环遍历敌方子弹列表,展示敌方子弹
self.blitDiBullet()
# 循环遍历爆炸效果列表,展示爆炸效果
self.blitExplode()
# 循环遍历墙壁列表,展示墙壁
self.blitWall()
# 首先判断坦克是否存在
# 调用坦克移动方法,由坦克的开关决定,开始默认静止是true,
# 所以要移动就是判断为false
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
if not MainGame.TANKE_P1.stop:
MainGame.TANKE_P1.move()
# 窗口持续刷新
pygame.display.update()
# 初始化我方坦克,
def createmyTanke(self):
MainGame.TANKE_P1 = Tanke(400, 300)
# 初始化敌坦克,并将敌方坦克添加到列表中
def creatediTanke(self):
# 固定随机生成敌方坦克在屏幕中的高度top
top = 100
for i in range(MainGame.diTankeCount):
# 随机生成敌方坦克在屏幕的left值及速度值,并定义di元组接受left、top、speed
# 把di加入到列表中
left = random.randint(0, 600)
speed = random.randint(1, 4)
di = diTanke(left, top, speed)
MainGame.diTankeList.append(di)
# 循环遍历敌方坦克列表,展示敌方坦克
def blitdiTanke(self):
for diTanke in MainGame.diTankeList:
# 判读当前坦克是否活着,活着展示坦克、展示子弹,否则,从敌坦克列表中移除,坦克被打掉
if diTanke.live:
# 展示敌方坦克图片
diTanke.display()
# 展示敌方坦克移动
diTanke.randMove()
# 发射子弹
diBullet = diTanke.shot()
# 子弹随机产生,有可能不存在,所以需要加入判断子弹是否为空
# 若不为空,则添加到敌方子弹列表中
if diBullet:
# 将敌方子弹存储到敌方子弹列表中
MainGame.diBulletList.append(diBullet)
else: # 不活着,从敌方坦克列表中移除
MainGame.diTankeList.remove(diTanke)
# 循环遍历敌方子弹列表,展示敌方子弹
def blitDiBullet(self):
for diBullet in MainGame.diBulletList:
# 判断敌方坦克是否存活,若存活,则调用子弹的展示和移动方法,若不存在,则从子弹列表中移去
if diBullet.live:
diBullet.displayBullet()
diBullet.bulletMove()
# 调用敌方子弹与我方坦克碰撞的方法(攻击方法)
diBullet.diBullet_hit_myTanke()
else:
MainGame.diBulletList.remove(diBullet)
# 循环遍历我方子弹的存储列表
def blitMyBullet(self):
for myBullet in MainGame.myBulletList:
# 判断当前的子弹是否是活着状态,如果是则进行显示及移动,否则,从列表中删除
if myBullet.live:
# 调用子弹类中的展示子弹的方法
myBullet.displayBullet()
# 展示完后就要子弹移动,调用子弹移动的方法
myBullet.bulletMove()
# 有移动就要检测是否发生碰撞
# 调用检测我方子弹是否与敌方坦克发生碰撞
myBullet.myBullet_hit_ditanke()
else:
MainGame.myBulletList.remove(myBullet)
# 循环展示爆炸效果
def blitExplode(self):
for explode in MainGame.explodeList:
# 判断是否活着
if explode.live:
explode.display()
else:
MainGame.explodeList.remove(explode)
# 初始化墙壁
def createWall(self):
for i in range(5):
# 初始化墙壁
wall = Wall(i*130,220)
# 将墙壁添加到列表中
MainGame.wallList.append(wall)
# 循环遍历墙壁列表,展示墙壁
def blitWall(self):
for wall in MainGame.wallList:
wall.displayWall()
# 定义游戏结束的方法
def endGame(self):
print('谢谢使用,欢迎下次继续!')
exit()
# 增加获取事件的方法
def getEvnet(self):
evnetlist = pygame.event.get()
for event in evnetlist:
# 如果是退出
if event.type == pygame.QUIT:
self.endGame()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.endGame()
# 判断当坦克不在,按下某键时,创建坦克,坦克重生
if not MainGame.TANKE_P1:
# 判断按下的时enter键,让坦克重生
if event.key == pygame.K_RETURN:
self.createmyTanke()
# 判断我方坦克是否存活,存活才能进行移动及攻击
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
# 判断具体按下哪个键
if event.key == pygame.K_a:
# 按下左键,坦克方向向左
MainGame.TANKE_P1.direction = 'L'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
# 至此,不在单独执行坦克的移动方法,移动方法在开关处执行
MainGame.TANKE_P1.stop = False
# 执行移动的方法
# MainGame.TANKE_P1.move()
print('按下a键,左移')
if event.key == pygame.K_w:
MainGame.TANKE_P1.direction = 'U'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false,由开关控制移动
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下w键,上移')
if event.key == pygame.K_d:
MainGame.TANKE_P1.direction = 'R'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下d键,右移')
if event.key == pygame.K_s:
MainGame.TANKE_P1.direction = 'D'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下s键,下移')
if event.key == pygame.K_SPACE:
print('发射子弹')
# 如果当前的子弹列表的大小小于等于5时,才可以创建子弹
if len(MainGame.myBulletList) <= 5:
# 创建我方坦克发射的子弹
myBullet = Bullet(MainGame.TANKE_P1)
MainGame.myBulletList.append(myBullet)
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_w or event.key == pygame.K_s or event.key == pygame.K_d:
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
MainGame.TANKE_P1.stop = True
# 左上角文字绘制的功能
def getTextSurface(self, text):
# 初始化字体模块
pygame.font.init()
# 选择合适的字体
font = pygame.font.SysFont('kaiti', 18)
# 使用对应的字符完成相关内容的绘制
textSurface = font.render(text, True, COLOR_RED)
return textSurface
# 坦克类
class Tanke(BsaeItem):
def __init__(self, left, top):
# 保存加载得图片
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()
# 分别指定坦克初始化的位置,分别距X,Y轴的位置
self.rect.left = left
self.rect.top = top
# 设置坦克的速度
self.speed = 5
# 设置坦克移动的开关,一开始为true,为静止状态
self.stop = True
# 设置存活标记
self.live = True
# 展示坦克(将坦克这个surface绘制到窗口中的blit())
def display(self):
# 1.重新设置坦克的图片
self.image = self.images[self.direction]
# 2.将坦克加入到窗口中
MainGame.window.blit(self.image, self.rect)
# 移动方法
def move(self):
# 判断坦克方向
if self.direction == 'L':
# 判断坦克在该方向上移动的条件
if self.rect.left > 0:
self.rect.left -= self.speed
if self.direction == 'R':
if self.rect.left + self.rect.height < SCREEN_WIDTH:
self.rect.left += self.speed
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= self.speed
if self.direction == 'D':
if self.rect.top + self.rect.height < SCREEN_HEIGHT:
self.rect.top += self.speed
# 射击方法
def shot(self):
return Bullet(self)
# 我方坦克
class myTanke(Tanke):
def __init__(self):
pass
# 敌方坦克
class diTanke(Tanke):
# 定义敌坦克初始化方法,传入左,上坐标,绘制坦克位置,出入速度
# 可参考我方坦克的初始化方法
def __init__(self, left, top, speed):
# 加载敌坦克图片集
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')
}
# 坦克方向,随机生成,导入random模块,调用随机生成坦克方向的方法
self.direction = self.randDirection()
# 根据方向获取坦克图片
self.image = self.images[self.direction]
# 获得区域
self.rect = self.image.get_rect()
# 对区域的left和top进行赋值
self.rect.left = left
self.rect.top = top
# 定义敌坦克的速度
self.speed = speed
# 定义坦克移动开关键
self.flag = True
# 新增加一个步数变量 step
self.step = 60
# 定义一个敌坦克是否存活的标记
self.live = True
# 定义随机生成坦克方向的方法
def randDirection(self):
num = random.randint(1, 4)
if num == 1:
return 'U'
if num == 2:
return 'L'
if num == 3:
return 'D'
if num == 4:
return 'R'
# 定义敌方坦克随机移动的方法,并在敌方坦克展示方法中调用展示
def randMove(self):
if self.step <= 0:
# 小于0,则修改方向,让步数复位
self.direction = self.randDirection()
self.step = 60
else:
self.move()
# 让步数递减,以达到改变方向的要求
self.step -= 1
# 重写父类中的shot方法,即定义敌方坦克随机产生子弹的方法
def shot(self):
num = random.randint(1, 100)
if num < 4:
return Bullet(self)
# 墙壁类
class Wall():
# 墙壁的位置也是通过top、和left确定
def __init__(self,left,top):
# 加载墙壁的图片
self.image = pygame.image.load('../img/steels.gif')
# 获取墙壁的区域
self.rect = self.image.get_rect()
# 设置left和top的值
self.rect.left = left
self.rect.top = top
# 是否存活
self.live = True
# 设置生命值
self.hp = 3
# 展示墙壁
def displayWall(self):
MainGame.window.blit(self.image,self.rect)
# 子弹类
class Bullet(BsaeItem):
# 坦克的方向决定子弹的方向,所以要传入一个tanke参数
def __init__(self, tanke):
# 加载子弹图片
self.image = pygame.image.load('../img/enemymissile.gif')
# 坦克的方向决定了子弹的方向
self.direction = tanke.direction
# 获取区域
self.rect = self.image.get_rect()
# 子弹的left和top与方向有关
if self.direction == 'U':
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top - self.rect.height
elif self.direction == 'D':
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top + tanke.rect.height
elif self.direction == 'L':
self.rect.left = tanke.rect.left - self.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.width / 2
elif self.direction == 'R':
self.rect.left = tanke.rect.left + tanke.rect.width
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.width / 2
# 定义子弹的速度
self.speed = 6
# 定义子弹的存活状态
self.live = True
# 子弹移动
def bulletMove(self):
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= 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
elif self.direction == 'D':
if self.rect.top + self.rect.height < 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
# 子弹展示
def displayBullet(self):
# 将子弹图片surface加载到窗口
MainGame.window.blit(self.image, self.rect)
# 我方子弹与敌坦克的碰撞
def myBullet_hit_ditanke(self):
# 循环遍历敌方坦克列表,判断是否与列表中的坦克发生碰撞
for diTanke in MainGame.diTankeList:
if pygame.sprite.collide_rect(diTanke, self):
# 修改敌坦克与我方子弹的状态
diTanke.live = False
self.live = False
# 创建爆炸对象,调用展示爆炸效果的方法
explode = Explode(diTanke)
# 将爆炸对象添加到爆炸列表中来
MainGame.explodeList.append(explode)
# 敌方子弹与我方坦克的碰撞
def diBullet_hit_myTanke(self):
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
if pygame.sprite.collide_rect(MainGame.TANKE_P1, self):
# 产生爆炸对象
explode = Explode(MainGame.TANKE_P1)
# 将爆炸对象添加到爆炸列表中
MainGame.explodeList.append(explode)
# 修改敌方子弹与我方坦克的状态
self.live = False
MainGame.TANKE_P1.live = False
# 音效类
class music():
def __init__(self):
pass
# 音乐播放
def play(self):
pass
# 爆炸效果类
class Explode():
# 爆炸的位置由当前子弹打中的坦克位置决定,所以要把坦克作为参数传递进来
def __init__(self, tanke):
self.rect = tanke.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 display(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
if __name__ == '__main__':
MainGame().startGame()
有什么类,类中有什么方法:
1、坦克类(我方坦克、敌方坦克)
移动、射击、显示坦克
2、墙壁类
允许是否通过
3、音效类
播放音乐
4、子弹类
移动
显示子弹移动的方法
5、爆炸效果类
展示爆炸效果
6、主类
开始游戏
结束游戏
'''
'''
新增优化功能:完善墙壁类
'''
import pygame, time, random
from pygame.sprite import Sprite
SCREEN_WIDTH = 700
SCREEN_HEIGHT = 500
BG_COLOR = pygame.Color(0, 0, 0)
COLOR_RED = pygame.Color(255, 0, 0)
# 定义一个基类,该类继承精灵类,就有精灵的所有方法
# 要发生碰撞的坦克类,子弹类就继承该类,就能继承精灵类的方法,实现碰撞
class BsaeItem(Sprite):
def __init__(self, color, width, height):
pygame.sprite.Sprite.__init__(self)
# 主类,定义了开始游戏、结束游戏、获取事件、文字绘制的方法
# 增加初始化敌坦克方法、
class MainGame():
window = None
# 创建我方坦克
TANKE_P1 = None
# 定义一个列表,存储敌方坦克
diTankeList = []
# 定义敌方坦克的数量
diTankeCount = 5
# 定义存储我方子弹的列表
myBulletList = []
# y定义存储敌方坦克子弹的列表
diBulletList = []
# 定义一个存储爆炸效果的列表
explodeList = []
# 定义一个存储墙壁的列表
wallList = []
def __init__(self):
pass
# 定义游戏开始的方法
def startGame(self):
# 加载主窗口
# 初始化窗口
pygame.display.init()
# 设置窗口的大小及显示
MainGame.window = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption('坦克大战1.0')
# 初始化我方坦克
self.createmyTanke()
# 初始化敌方坦克
self.creatediTanke()
while True:
# 使坦克移动得速度慢一点
time.sleep(0.02)
# 给窗口设置填充色
MainGame.window.fill(BG_COLOR)
# 事件要一直监听
self.getEvnet()
# 将绘制文字得到的小画布粘贴到窗口
MainGame.window.blit(self.getTextSurface('剩余敌方坦克%d辆' % len(MainGame.diTankeList)), (5, 5))
# 调用坦克显示方法
# 需要判断我方坦克是否存活
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
MainGame.TANKE_P1.display()
else:
# 删除我方坦克
del MainGame.TANKE_P1
MainGame.TANKE_P1 = None
# 循环遍历敌方坦克列表,展示敌方坦克
self.blitdiTanke()
# 循环遍历显示我方坦克子弹
self.blitMyBullet()
# 循环遍历敌方子弹列表,展示敌方子弹
self.blitDiBullet()
# 循环遍历爆炸效果列表,展示爆炸效果
self.blitExplode()
# 循环遍历墙壁列表,展示墙壁
self.blitWall()
# 首先判断坦克是否存在
# 调用坦克移动方法,由坦克的开关决定,开始默认静止是true,
# 所以要移动就是判断为false
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
if not MainGame.TANKE_P1.stop:
MainGame.TANKE_P1.move()
# 窗口持续刷新
pygame.display.update()
# 初始化我方坦克,
def createmyTanke(self):
MainGame.TANKE_P1 = Tanke(400, 300)
# 初始化敌坦克,并将敌方坦克添加到列表中
def creatediTanke(self):
# 固定随机生成敌方坦克在屏幕中的高度top
top = 100
for i in range(MainGame.diTankeCount):
# 随机生成敌方坦克在屏幕的left值及速度值,并定义di元组接受left、top、speed
# 把di加入到列表中
left = random.randint(0, 600)
speed = random.randint(1, 4)
di = diTanke(left, top, speed)
MainGame.diTankeList.append(di)
# 循环遍历敌方坦克列表,展示敌方坦克
def blitdiTanke(self):
for diTanke in MainGame.diTankeList:
# 判读当前坦克是否活着,活着展示坦克、展示子弹,否则,从敌坦克列表中移除,坦克被打掉
if diTanke.live:
# 展示敌方坦克图片
diTanke.display()
# 展示敌方坦克移动
diTanke.randMove()
# 发射子弹
diBullet = diTanke.shot()
# 子弹随机产生,有可能不存在,所以需要加入判断子弹是否为空
# 若不为空,则添加到敌方子弹列表中
if diBullet:
# 将敌方子弹存储到敌方子弹列表中
MainGame.diBulletList.append(diBullet)
else: # 不活着,从敌方坦克列表中移除
MainGame.diTankeList.remove(diTanke)
# 循环遍历敌方子弹列表,展示敌方子弹
def blitDiBullet(self):
for diBullet in MainGame.diBulletList:
# 判断敌方坦克是否存活,若存活,则调用子弹的展示和移动方法,若不存在,则从子弹列表中移去
if diBullet.live:
diBullet.displayBullet()
diBullet.bulletMove()
# 调用敌方子弹与我方坦克碰撞的方法(攻击方法)
diBullet.diBullet_hit_myTanke()
else:
MainGame.diBulletList.remove(diBullet)
# 循环遍历我方子弹的存储列表
def blitMyBullet(self):
for myBullet in MainGame.myBulletList:
# 判断当前的子弹是否是活着状态,如果是则进行显示及移动,否则,从列表中删除
if myBullet.live:
# 调用子弹类中的展示子弹的方法
myBullet.displayBullet()
# 展示完后就要子弹移动,调用子弹移动的方法
myBullet.bulletMove()
# 有移动就要检测是否发生碰撞
# 调用检测我方子弹是否与敌方坦克发生碰撞
myBullet.myBullet_hit_ditanke()
else:
MainGame.myBulletList.remove(myBullet)
# 循环展示爆炸效果
def blitExplode(self):
for explode in MainGame.explodeList:
# 判断是否活着
if explode.live:
explode.display()
else:
MainGame.explodeList.remove(explode)
# 初始化墙壁
def createWall(self):
for i in range(5):
# 初始化墙壁
wall = Wall(i*130,220)
# 将墙壁添加到列表中
MainGame.wallList.append(wall)
# 循环遍历墙壁列表,展示墙壁
def blitWall(self):
for wall in MainGame.wallList:
wall.displayWall()
# 定义游戏结束的方法
def endGame(self):
print('谢谢使用,欢迎下次继续!')
exit()
# 增加获取事件的方法
def getEvnet(self):
evnetlist = pygame.event.get()
for event in evnetlist:
# 如果是退出
if event.type == pygame.QUIT:
self.endGame()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.endGame()
# 判断当坦克不在,按下某键时,创建坦克,坦克重生
if not MainGame.TANKE_P1:
# 判断按下的时enter键,让坦克重生
if event.key == pygame.K_RETURN:
self.createmyTanke()
# 判断我方坦克是否存活,存活才能进行移动及攻击
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
# 判断具体按下哪个键
if event.key == pygame.K_a:
# 按下左键,坦克方向向左
MainGame.TANKE_P1.direction = 'L'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
# 至此,不在单独执行坦克的移动方法,移动方法在开关处执行
MainGame.TANKE_P1.stop = False
# 执行移动的方法
# MainGame.TANKE_P1.move()
print('按下a键,左移')
if event.key == pygame.K_w:
MainGame.TANKE_P1.direction = 'U'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false,由开关控制移动
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下w键,上移')
if event.key == pygame.K_d:
MainGame.TANKE_P1.direction = 'R'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下d键,右移')
if event.key == pygame.K_s:
MainGame.TANKE_P1.direction = 'D'
# 键盘按下,修改坦克的状态,由静止的true改为移动的false
MainGame.TANKE_P1.stop = False
# MainGame.TANKE_P1.move()
print('按下s键,下移')
if event.key == pygame.K_SPACE:
print('发射子弹')
# 如果当前的子弹列表的大小小于等于5时,才可以创建子弹
if len(MainGame.myBulletList) <= 5:
# 创建我方坦克发射的子弹
myBullet = Bullet(MainGame.TANKE_P1)
MainGame.myBulletList.append(myBullet)
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_w or event.key == pygame.K_s or event.key == pygame.K_d:
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
MainGame.TANKE_P1.stop = True
# 左上角文字绘制的功能
def getTextSurface(self, text):
# 初始化字体模块
pygame.font.init()
# 选择合适的字体
font = pygame.font.SysFont('kaiti', 18)
# 使用对应的字符完成相关内容的绘制
textSurface = font.render(text, True, COLOR_RED)
return textSurface
# 坦克类
class Tanke(BsaeItem):
def __init__(self, left, top):
# 保存加载得图片
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()
# 分别指定坦克初始化的位置,分别距X,Y轴的位置
self.rect.left = left
self.rect.top = top
# 设置坦克的速度
self.speed = 5
# 设置坦克移动的开关,一开始为true,为静止状态
self.stop = True
# 设置存活标记
self.live = True
# 展示坦克(将坦克这个surface绘制到窗口中的blit())
def display(self):
# 1.重新设置坦克的图片
self.image = self.images[self.direction]
# 2.将坦克加入到窗口中
MainGame.window.blit(self.image, self.rect)
# 移动方法
def move(self):
# 判断坦克方向
if self.direction == 'L':
# 判断坦克在该方向上移动的条件
if self.rect.left > 0:
self.rect.left -= self.speed
if self.direction == 'R':
if self.rect.left + self.rect.height < SCREEN_WIDTH:
self.rect.left += self.speed
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= self.speed
if self.direction == 'D':
if self.rect.top + self.rect.height < SCREEN_HEIGHT:
self.rect.top += self.speed
# 射击方法
def shot(self):
return Bullet(self)
# 我方坦克
class myTanke(Tanke):
def __init__(self):
pass
# 敌方坦克
class diTanke(Tanke):
# 定义敌坦克初始化方法,传入左,上坐标,绘制坦克位置,出入速度
# 可参考我方坦克的初始化方法
def __init__(self, left, top, speed):
# 加载敌坦克图片集
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')
}
# 坦克方向,随机生成,导入random模块,调用随机生成坦克方向的方法
self.direction = self.randDirection()
# 根据方向获取坦克图片
self.image = self.images[self.direction]
# 获得区域
self.rect = self.image.get_rect()
# 对区域的left和top进行赋值
self.rect.left = left
self.rect.top = top
# 定义敌坦克的速度
self.speed = speed
# 定义坦克移动开关键
self.flag = True
# 新增加一个步数变量 step
self.step = 60
# 定义一个敌坦克是否存活的标记
self.live = True
# 定义随机生成坦克方向的方法
def randDirection(self):
num = random.randint(1, 4)
if num == 1:
return 'U'
if num == 2:
return 'L'
if num == 3:
return 'D'
if num == 4:
return 'R'
# 定义敌方坦克随机移动的方法,并在敌方坦克展示方法中调用展示
def randMove(self):
if self.step <= 0:
# 小于0,则修改方向,让步数复位
self.direction = self.randDirection()
self.step = 60
else:
self.move()
# 让步数递减,以达到改变方向的要求
self.step -= 1
# 重写父类中的shot方法,即定义敌方坦克随机产生子弹的方法
def shot(self):
num = random.randint(1, 100)
if num < 4:
return Bullet(self)
# 墙壁类
class Wall():
# 墙壁的位置也是通过top、和left确定
def __init__(self,left,top):
# 加载墙壁的图片
self.image = pygame.image.load('../img/steels.gif')
# 获取墙壁的区域
self.rect = self.image.get_rect()
# 设置left和top的值
self.rect.left = left
self.rect.top = top
# 是否存活
self.live = True
# 设置生命值
self.hp = 3
# 展示墙壁
def displayWall(self):
MainGame.window.blit(self.image,self.rect)
# 子弹类
class Bullet(BsaeItem):
# 坦克的方向决定子弹的方向,所以要传入一个tanke参数
def __init__(self, tanke):
# 加载子弹图片
self.image = pygame.image.load('../img/enemymissile.gif')
# 坦克的方向决定了子弹的方向
self.direction = tanke.direction
# 获取区域
self.rect = self.image.get_rect()
# 子弹的left和top与方向有关
if self.direction == 'U':
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top - self.rect.height
elif self.direction == 'D':
self.rect.left = tanke.rect.left + tanke.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top + tanke.rect.height
elif self.direction == 'L':
self.rect.left = tanke.rect.left - self.rect.width / 2 - self.rect.width / 2
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.width / 2
elif self.direction == 'R':
self.rect.left = tanke.rect.left + tanke.rect.width
self.rect.top = tanke.rect.top + tanke.rect.width / 2 - self.rect.width / 2
# 定义子弹的速度
self.speed = 6
# 定义子弹的存活状态
self.live = True
# 子弹移动
def bulletMove(self):
if self.direction == 'U':
if self.rect.top > 0:
self.rect.top -= 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
elif self.direction == 'D':
if self.rect.top + self.rect.height < 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
# 子弹展示
def displayBullet(self):
# 将子弹图片surface加载到窗口
MainGame.window.blit(self.image, self.rect)
# 我方子弹与敌坦克的碰撞
def myBullet_hit_ditanke(self):
# 循环遍历敌方坦克列表,判断是否与列表中的坦克发生碰撞
for diTanke in MainGame.diTankeList:
if pygame.sprite.collide_rect(diTanke, self):
# 修改敌坦克与我方子弹的状态
diTanke.live = False
self.live = False
# 创建爆炸对象,调用展示爆炸效果的方法
explode = Explode(diTanke)
# 将爆炸对象添加到爆炸列表中来
MainGame.explodeList.append(explode)
# 敌方子弹与我方坦克的碰撞
def diBullet_hit_myTanke(self):
if MainGame.TANKE_P1 and MainGame.TANKE_P1.live:
if pygame.sprite.collide_rect(MainGame.TANKE_P1, self):
# 产生爆炸对象
explode = Explode(MainGame.TANKE_P1)
# 将爆炸对象添加到爆炸列表中
MainGame.explodeList.append(explode)
# 修改敌方子弹与我方坦克的状态
self.live = False
MainGame.TANKE_P1.live = False
# 音效类
class music():
def __init__(self):
pass
# 音乐播放
def play(self):
pass
# 爆炸效果类
class Explode():
# 爆炸的位置由当前子弹打中的坦克位置决定,所以要把坦克作为参数传递进来
def __init__(self, tanke):
self.rect = tanke.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 display(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
if __name__ == '__main__':
MainGame().startGame()