【项目:坦克大战】

"""
v1.25新增功能:1.音效的处理
"""
import pygame,time,random
_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0)
COLOR_RED = pygame.Color(255, 0, 0)
version = 'v1.25'
class MainGame():#游戏主窗口window = NoneSCREEN_HEIGHT = 500SCREEN_WIDTH = 800#创建我方坦克TANK_P1 = None#存储所有敌方坦克EnemyTank_list = []#要创建的敌方坦克的数量EnemTank_count = 5#存储我方子弹的列表Bullet_list = []#存储敌方子弹的列表Enemy_bullet_list = []#爆炸效果列表Explode_list = []#墙壁列表Wall_list = []#开始游戏方法def startGame(self):_display.init()#创建窗口加载窗口(借鉴官方文档)MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH,MainGame.SCREEN_HEIGHT])self.creatMyTank()self.creatEnemyTank()self.creatWalls()#设置一下游戏标题_display.set_caption("坦克大战"+version)#让窗口持续刷新操作while True:#给窗口完成一个填充颜色MainGame.window.fill(COLOR_BLACK)#在循环中持续完成事件的获取self.getEvent()#将绘制文字得到的小画布,粘贴到窗口中MainGame.window.blit(self.getTextSurface("剩余敌方坦克%d辆"%len(MainGame.EnemyTank_list)),(5,5))#调用展示墙壁的方法self.blitWalls()if MainGame.TANK_P1 and MainGame.TANK_P1.live:# 将我方坦克加入到窗口中MainGame.TANK_P1.displayTank()else:del MainGame.TANK_P1MainGame.TANK_P1 = None#循环展示敌方坦克self.blitEnemyTank()#根据坦克的开关状态调用坦克的移动方法if MainGame.TANK_P1 and not MainGame.TANK_P1.stop:MainGame.TANK_P1.move()#调用碰撞墙壁的方法MainGame.TANK_P1.hitWalls()MainGame.TANK_P1.hitEnemyTank()#调用渲染子弹列表的一个方法self.blitBullet()#调用渲染敌方子弹列表的一个方法self.blitEnemyBullet()#调用展示爆炸效果的方法self.displayExplodes()time.sleep(0.02)#窗口的刷新_display.update()#创建我方坦克的方法def creatMyTank(self):# 创建我方坦克MainGame.TANK_P1 = MyTank(400, 300)#创建音乐对象music = Music('img/start.wav')#调用播放音乐方法music.play()#创建敌方坦克def creatEnemyTank(self):top = 100for i in range(MainGame.EnemTank_count):speed = random.randint(3,6)#每次都随机生成一个left值left = random.randint(1, 7)eTank = EnemyTank(left*100,top,speed)MainGame.EnemyTank_list.append(eTank)#创建墙壁的方法def creatWalls(self):for i in range(6):wall = Wall(130*i,240)MainGame.Wall_list.append(wall)def blitWalls(self):for wall in MainGame.Wall_list:if wall.live:wall.displayWall()else:MainGame.Wall_list.remove(wall)#将敌方坦克加入到窗口中def blitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if eTank.live:eTank.displayTank()# 坦克移动的方法eTank.randMove()#调用敌方坦克与墙壁的碰撞方法eTank.hitWalls()#敌方坦克是否撞到我方坦克eTank.hitMyTank()# 调用敌方坦克的射击eBullet = eTank.shot()# 如果子弹为None。不加入到列表if eBullet:# 将子弹存储敌方子弹列表MainGame.Enemy_bullet_list.append(eBullet)else:MainGame.EnemyTank_list.remove(eTank)#将我方子弹加入到窗口中def blitBullet(self):for bullet in MainGame.Bullet_list:#如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹if bullet.live:bullet.displayBullet()# 让子弹移动bullet.bulletMove()# 调用我方子弹与敌方坦克的碰撞方法bullet.hitEnemyTank()# 调用判断我方子弹是否碰撞到墙壁的方法bullet.hitWalls()else:MainGame.Bullet_list.remove(bullet)#将敌方子弹加入到窗口中def blitEnemyBullet(self):for eBullet in MainGame.Enemy_bullet_list:# 如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹if eBullet.live:eBullet.displayBullet()# 让子弹移动eBullet.bulletMove()#调用是否碰撞到墙壁的一个方法eBullet.hitWalls()if MainGame.TANK_P1 and MainGame.TANK_P1.live:eBullet.hitMyTank()else:MainGame.Enemy_bullet_list.remove(eBullet)#新增方法: 展示爆炸效果列表def displayExplodes(self):for explode in MainGame.Explode_list:if explode.live:explode.displayExplode()else:MainGame.Explode_list.remove(explode)#获取程序期间所有事件(鼠标事件,键盘事件)def getEvent(self):#1.获取所有事件eventList = pygame.event.get()#2.对事件进行判断处理(1、点击关闭按钮  2、按下键盘上的某个按键)for event in eventList:#判断event.type 是否QUIT,如果是退出的话,直接调用程序结束方法if event.type == pygame.QUIT:self.endGame()#判断事件类型是否为按键按下,如果是,继续判断按键是哪一个按键,来进行对应的处理if event.type == pygame.KEYDOWN:#点击ESC按键让我方坦克重生if event.key == pygame.K_ESCAPE and not MainGame.TANK_P1:#调用创建我方坦克的方法self.creatMyTank()if MainGame.TANK_P1 and MainGame.TANK_P1.live:# 具体是哪一个按键的处理if event.key == pygame.K_LEFT:print("坦克向左调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'L'MainGame.TANK_P1.stop = Falseelif event.key == pygame.K_RIGHT:print("坦克向右调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'R'MainGame.TANK_P1.stop = Falseelif event.key == pygame.K_UP:print("坦克向上调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'U'MainGame.TANK_P1.stop = Falseelif event.key == pygame.K_DOWN:print("坦克向下掉头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'D'MainGame.TANK_P1.stop = Falseelif event.key == pygame.K_SPACE:print("发射子弹")if len(MainGame.Bullet_list) < 3:# 产生一颗子弹m = Bullet(MainGame.TANK_P1)# 将子弹加入到子弹列表MainGame.Bullet_list.append(m)music = Music('img/fire.wav')music.play()else:print("子弹数量不足")print("当前屏幕中的子弹数量为:%d" % len(MainGame.Bullet_list))#结束游戏方法if event.type == pygame.KEYUP:#松开的如果是方向键,才更改移动开关状态if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:if MainGame.TANK_P1 and MainGame.TANK_P1.live:# 修改坦克的移动状态MainGame.TANK_P1.stop = True#左上角文字绘制的功能def getTextSurface(self,text):# 初始化字体模块pygame.font.init()#查看系统支持的所有字体# fontList = pygame.font.get_fonts()# print(fontList)# 选中一个合适的字体font = pygame.font.SysFont('kaiti',18)# 使用对应的字符完成相关内容的绘制textSurface = font.render(text,True,COLOR_RED)return textSurfacedef endGame(self):print("谢谢使用")#结束python解释器exit()
class BaseItem(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)
class Tank(BaseItem):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]#坦克所在的区域  Rect->self.rect = self.image.get_rect()#指定坦克初始化位置 分别距x,y轴的位置self.rect.left = leftself.rect.top = top#新增速度属性self.speed = 5#新增属性: 坦克的移动开关self.stop = True#新增属性  live 用来记录,坦克是否活着self.live = True#新增属性: 用来记录坦克移动之前的坐标(用于坐标还原时使用)self.oldLeft = self.rect.leftself.oldTop = self.rect.top#坦克的移动方法def move(self):#先记录移动之前的坐标self.oldLeft = self.rect.leftself.oldTop = self.rect.topif self.direction == 'L':if self.rect.left > 0:self.rect.left -= self.speedelif self.direction == 'R':if self.rect.left + self.rect.height < MainGame.SCREEN_WIDTH:self.rect.left += self.speedelif self.direction == 'U':if self.rect.top > 0:self.rect.top -= self.speedelif self.direction == 'D':if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT:self.rect.top += self.speeddef stay(self):self.rect.left = self.oldLeftself.rect.top = self.oldTop#新增碰撞墙壁的方法def hitWalls(self):for wall in MainGame.Wall_list:if pygame.sprite.collide_rect(wall,self):self.stay()#射击方法def shot(self):return Bullet(self)#展示坦克(将坦克这个surface绘制到窗口中  blit())def displayTank(self):#1.重新设置坦克的图片self.image = self.images[self.direction]#2.将坦克加入到窗口中MainGame.window.blit(self.image,self.rect)
class MyTank(Tank):def __init__(self,left,top):super(MyTank, self).__init__(left,top)#新增主动碰撞到敌方坦克的方法def hitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if pygame.sprite.collide_rect(eTank,self):self.stay()class EnemyTank(Tank):def __init__(self,left,top,speed):super(EnemyTank, self).__init__(left,top)# self.live = Trueself.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.randDirection()self.image = self.images[self.direction]# 坦克所在的区域  Rect->self.rect = self.image.get_rect()# 指定坦克初始化位置 分别距x,y轴的位置self.rect.left = leftself.rect.top = top# 新增速度属性self.speed = speedself.stop = True#新增步数属性,用来控制敌方坦克随机移动self.step = 30def randDirection(self):num = random.randint(1,4)if num == 1:return 'U'elif num == 2:return 'D'elif num == 3:return 'L'elif num == 4:return 'R'# def displayEnemtTank(self):#     super().displayTank()#随机移动def randMove(self):if self.step <= 0:self.direction = self.randDirection()self.step = 50else:self.move()self.step -= 1def shot(self):num = random.randint(1,1000)if num  <= 20:return Bullet(self)def hitMyTank(self):if MainGame.TANK_P1 and MainGame.TANK_P1.live:if pygame.sprite.collide_rect(self, MainGame.TANK_P1):# 让敌方坦克停下来  stay()self.stay()
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()if self.direction == 'U':self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2self.rect.top = tank.rect.top - self.rect.heightelif self.direction == 'D':self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2self.rect.top = tank.rect.top + tank.rect.heightelif self.direction == 'L':self.rect.left = tank.rect.left - self.rect.width / 2 - self.rect.width / 2self.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2elif self.direction == 'R':self.rect.left = tank.rect.left + tank.rect.widthself.rect.top = tank.rect.top + tank.rect.width / 2 - self.rect.width / 2#速度self.speed = 7#用来记录子弹是否活着self.live = True#子弹的移动方法def bulletMove(self):if self.direction == 'U':if self.rect.top > 0:self.rect.top -= self.speedelse:#修改状态值self.live = Falseelif self.direction == 'D':if self.rect.top < MainGame.SCREEN_HEIGHT - self.rect.height:self.rect.top += self.speedelse:# 修改状态值self.live = Falseelif self.direction == 'L':if self.rect.left > 0:self.rect.left -= self.speedelse:# 修改状态值self.live = Falseelif self.direction == 'R':if self.rect.left < MainGame.SCREEN_WIDTH - self.rect.width:self.rect.left += self.speedelse:# 修改状态值self.live = False#展示子弹的方法def displayBullet(self):MainGame.window.blit(self.image,self.rect)#新增我方子弹碰撞敌方坦克的方法def hitEnemyTank(self):for eTank in MainGame.EnemyTank_list:if pygame.sprite.collide_rect(eTank,self):#产生一个爆炸效果explode = Explode(eTank)#将爆炸效果加入到爆炸效果列表MainGame.Explode_list.append(explode)self.live = FalseeTank.live = False#新增敌方子弹与我方坦克的碰撞方法def hitMyTank(self):if pygame.sprite.collide_rect(self,MainGame.TANK_P1):# 产生爆炸效果,并加入到爆炸效果列表中explode = Explode(MainGame.TANK_P1)MainGame.Explode_list.append(explode)#修改子弹状态self.live = False#修改我方坦克状态MainGame.TANK_P1.live = False#新增子弹与墙壁的碰撞def hitWalls(self):for wall in MainGame.Wall_list:if pygame.sprite.collide_rect(wall,self):#修改子弹的live属性self.live = Falsewall.hp -= 1if wall.hp <= 0:wall.live = False
class Explode():def __init__(self,tank):self.rect = tank.rectself.step = 0self.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.image = self.images[self.step]self.live = True#展示爆炸效果def displayExplode(self):if self.step < len(self.images):MainGame.window.blit(self.image, self.rect)self.image = self.images[self.step]self.step += 1else:self.live = Falseself.step = 0
class Wall():def __init__(self,left,top):self.image = pygame.image.load('img/steels.gif')self.rect = self.image.get_rect()self.rect.left = leftself.rect.top = top#用来判断墙壁是否应该在窗口中展示self.live = True#用来记录墙壁的生命值self.hp = 3#展示墙壁的方法def displayWall(self):MainGame.window.blit(self.image,self.rect)
#我方坦克出生
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()
MainGame().startGame()


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部