老师,为什么我增加坦克不能穿墙的效果后坦克不能移动了,请问是哪里错了, 谢谢
import pygame,time,random
ScreenWidth=700
ScreenHeight=500
BG_COLOR=pygame.Color(0,0,0)
TEXT_COLOR=pygame.Color(255,255,255)
class BaseItem(pygame.sprite.Sprite):#定义一个基类
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class MainGame():#主类
window=None
my_tank=None
#存储地方坦克列表
#定义已生成敌方坦克数量
enemyTankList=[]
enemyTankCount=5
#存储我方子弹列表
myBulletList=[]
enemyBulletList=[]
explodeList=[]
#墙壁列表
wallList = []
def __init__(self):
pass
def StartGame(self):#开始游戏
#加载主窗口
pygame.display.init()
#设置窗口返回值,大小
MainGame.window=pygame.display.set_mode([ScreenWidth,ScreenHeight])
MainGame.my_tank=Tank(350,250)
#设置窗口标题
self.createMyTank()
self.createEnemyTank()
self.createWall()
pygame.display.set_caption('坦克大战')
while True:
time.sleep(0.02)
MainGame.window.fill(BG_COLOR)#填充背景色
#获取事件
self.GetEvent()
#绘制文字
MainGame.window.blit(self.getTextSurface('敌方坦克剩余数量%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.blitWall()#调用展示墙壁方法
self.blitEnemyTank()#循环遍历敌方坦克列表,展示敌方坦克
#调用移动方法,如果坦克开关开启,可以调用
self.blitMyBullet()# 调用子弹列表方法
self.blitEnemyBullet()# 调用敌方子弹列表
self.blitExplode()# 调用展示爆炸效果
if MainGame.my_tank and MainGame.my_tank.live:
if not MainGame.my_tank.stop:
'''MainGame.my_tank.move()
#调用碰撞墙壁的方法
MainGame.my_tank.hitWalls()'''
MainGame.my_tank.move()
# 检测我方坦克是否与墙壁发生碰撞
MainGame.my_tank.hitWall()
pygame.display.update()
def blitWall(self):
for wall in MainGame.wallList:
if wall.live:
wall.DisplayWall()
else:
MainGame.wallList.remove(wall)
def createWall(self):#初始化墙壁,加入列表
for i in range(6):
wall=Wall(130*i,220)
MainGame.wallList.append(wall)
def createMyTank(self):#创建己方坦克
MainGame.my_tank = Tank(350, 250)
#初始化敌方坦克,并加入列表
def createEnemyTank(self):
top=100
#循环生成敌方坦克
for i in range(MainGame.enemyTankCount):
left=random.randint(0,600)
speed=random.randint(1,4)
enemy=EnemyTank(left,top,speed)
MainGame.enemyTankList.append(enemy)
def blitExplode(self):
for explode in MainGame.explodeList:
if explode.live:
explode.displayExplode()
else:
MainGame.explodeList.remove(explode)
# 循环遍历敌方坦克列表,展示敌方坦克
def blitEnemyTank(self):
for enemyTank in MainGame.enemyTankList:
if enemyTank.live:
enemyTank.displayTank()
enemyTank.randMove()
enemyTank.hitWall()#敌方子弹是否碰撞墙壁
#调用敌方坦克射击方法
enemybullet = enemyTank.Shot()
#如果子弹为none,不加入列表
if enemybullet:
MainGame.enemyBulletList.append(enemybullet)
#子弹存储到敌方子弹列表
else:
MainGame.enemyTankList.remove(enemyTank)
#将子弹加入到窗口中
def blitMyBullet(self):
for mybullet in MainGame.myBulletList:
#如果子弹存在,否则移除
if mybullet.live:
mybullet.displayBullet()
mybullet.Move()
#调用我方子弹与敌方坦克的碰撞方法
mybullet.myBullet_hit_enemyTank()
#调用我方子弹碰撞墙壁
mybullet.hitWall()
else:
MainGame.myBulletList.remove(mybullet)
#将敌方子弹加入窗口中
def blitEnemyBullet(self):
for enemyBullet in MainGame.enemyBulletList:
#如果子弹存在,否则移除
if enemyBullet.live:
enemyBullet.displayBullet()
enemyBullet.Move()
enemyBullet.enemyBullet_hit_myTank()
enemyBullet.hitWall()#调用敌方子弹碰撞墙壁
if MainGame.my_tank and MainGame.my_tank.live:
enemyBullet.enemyBullet_hit_myTank()
else:
MainGame.enemyBulletList.remove(enemyBullet)
def EndGame(self):#结束游戏
print('谢谢使用,欢迎下次来玩')
exit()
#左上角加入文字
def getTextSurface(self,text):
pygame.font.init()#初始化字体
font=pygame.font.SysFont('kaiti',18)#字体格式
textSurface=font.render(text,True,TEXT_COLOR)
return textSurface
def GetEvent(self):
#获取事件
EventList=pygame.event.get()
#遍历事件
for event in EventList:
#判断按下的键是鼠标还是键盘
#如果是退出则关闭窗口
if event.type==pygame.QUIT:
self.EndGame()
#键盘
if event.type==pygame.KEYDOWN:
#判断上下左右
#松开键,坦克停止移动
#点击esc重生
if event.key==pygame.K_ESCAPE and not MainGame.my_tank:
#创建我方坦克方法
self.createMyTank()
if MainGame.my_tank and MainGame.my_tank.live:
if event.key==pygame.K_LEFT:
#切换方向
MainGame.my_tank.direction='L'
#MainGame.my_tank.move()
#坦克的开关是true
MainGame.my_tank.stop=False
print('按下左键,坦克向左')
elif event.key==pygame.K_RIGHT:
MainGame.my_tank.direction = 'R'
#MainGame.my_tank.move()
MainGame.my_tank.stop = False
print('按下右键,坦克向右')
elif event.key==pygame.K_UP:
MainGame.my_tank.direction = 'U'
# MainGame.my_tank.move()
MainGame.my_tank.stop = False
print('按下上键,向上移动')
elif event.key==pygame.K_DOWN:
MainGame.my_tank.direction = 'D'
#MainGame.my_tank.move()
MainGame.my_tank.stop = False
print('按下下键,向下移动')
elif event.key==pygame.K_SPACE:
print('射击')
if len(MainGame.myBulletList)<3:
#产生一颗子弹,发射,将子弹加入到子弹列表
m=bullet(MainGame.my_tank)
MainGame.myBulletList.append(m)
else:
print('子弹数量不足')
print('当前屏幕中子弹数量为:%d'%len(MainGame.myBulletList))
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:
# MainGame.my_tank.stop = True
if event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
if MainGame.my_tank and MainGame.my_tank.live:
MainGame.my_tank.stop = True
# 松开方向键,坦克停止移动,修改坦克的开关状态
class Tank(BaseItem):#坦克类 父类
def __init__(self,left,top):#距离左边,上边
#保存加载图片
self.images={
'U':pygame.image.load(r'D://pythoncharm2019/img/p1tankU.gif'),
'D':pygame.image.load(r'D://pythoncharm2019/img/p1tankD.gif'),
'L':pygame.image.load(r'D://pythoncharm2019/img/p1tankL.gif'),
'R':pygame.image.load(r'D://pythoncharm2019/img/p1tankR.gif')}
#方向
self.direction='U'
#根据图片的方向获取图片 surface
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 move(self):#移动
#记录移动之前坐标
self.oldLeft = self.rect.left
self.oldTop = self.rect.top
#判断坦克方向,进行移动
if self.direction=='L':
if self.rect.left>0:
self.rect.left-=self.speed
elif self.direction=='U':
if self.rect.top>0:
self.rect.top-=self.speed
elif self.direction=='D':
if self.rect.top+self.rect.height<ScreenHeight:
self.rect.top += self.speed
elif self.direction=='R':
if self.rect.left+self.rect.height<ScreenWidth:
self.rect.left += self.speed
def Shot(self):#射击
return bullet(self)
def stay(self):
self.rect.left = self.oldLeft
self.rect.top = self.oldTop
def hitWall(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 hitWalls(self):
for walls in MainGame.wallList:
if pygame.sprite.collide_rect(self,walls):
self.stay()'''
def displayTank(self):#展示
#获取展示对象
self.image=self.images[self.direction]
# 调用blit
MainGame.window.blit(self.image,self.rect)
class MyTank(Tank):#我方坦克
def __init__(self):
pass
class EnemyTank(Tank):#敌方坦克
def __init__(self,left,top,speed):
super(EnemyTank,self).__init__(left,top)
#加载图片
self.images={
'U': pygame.image.load(r'D://pythoncharm2019/img/enemy1U.gif'),
'D': pygame.image.load(r'D://pythoncharm2019/img/enemy1D.gif'),
'L': pygame.image.load(r'D://pythoncharm2019/img/enemy1L.gif'),
'R': pygame.image.load(r'D://pythoncharm2019/img/enemy1R.gif')}
#随机生成初始方向
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
#新增步数
self.step=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=60#步数复位
else:
self.move()
#让步数递减
self.step-=1
def Shot(self):
num=random.randint(1,1000)
if num<=15:
return bullet(self)
class bullet(BaseItem):#子弹类
def __init__(self,tank):
#加载图片
self.image=pygame.image.load(r'D://pythoncharm2019/img/enemymissile.gif')
#坦克的方向决定子弹方向
self.direction=tank.direction
#获取区域
self.rect=self.image.get_rect()
#子弹的left top与方向有关。
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-tank.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 Move(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 <= ScreenHeight - self.rect.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 < ScreenWidth - self.rect.width:
self.rect.left += self.speed
else:
self.live=False
def displayBullet(self):#子弹展示
#将图片surface加载窗口
MainGame.window.blit(self.image,self.rect)
#新增我方子弹碰撞敌方坦克的方法
def myBullet_hit_enemyTank(self):
for enemyTank in MainGame.enemyTankList:
if pygame.sprite.collide_rect(enemyTank,self):
#产生爆炸效果
#将爆炸效果加入爆炸效果列表
self.live = False
enemyTank.live = False
explode = Explode(enemyTank)
MainGame.explodeList.append(explode)
def enemyBullet_hit_myTank(self):
if pygame.sprite.collide_rect(self,MainGame.my_tank):
#爆炸效果并加入爆炸效果列表
exp=Explode(MainGame.my_tank)
MainGame.explodeList.append(exp)
#修改子弹状态
self.live=False
#我方坦克状态
MainGame.my_tank.live=False
def hitWall(self):
for wall in MainGame.wallList:
if pygame.sprite.collide_rect(wall,self):
#修改子弹live属性
self.live=False
wall.hp-=1
if wall.hp<=0:
wall.live=False
class Wall():#墙壁类
def __init__(self,left,top):#墙壁显示办法
self.image=pygame.image.load(r'D://pythoncharm2019/img/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):#墙壁展示
MainGame.window.blit(self.image,self.rect)
class Explode():#展示爆炸效果
def __init__(self,tank):
self.rect=tank.rect
self.images=[
pygame.image.load(r'D://pythoncharm2019/img/blast0.gif'),
pygame.image.load(r'D://pythoncharm2019/img/blast1.gif'),
pygame.image.load(r'D://pythoncharm2019/img/blast2.gif'),
pygame.image.load(r'D://pythoncharm2019/img/blast3.gif'),
pygame.image.load(r'D://pythoncharm2019/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):
pass
if __name__=='__main__':#双下划线
MainGame().StartGame()