如何利用pygame 开发坦克大战小游戏

一、首先我们当然要先认识一下pygame 中一些常用的模块的使用功能。

 因为这些都是我们在开发小游戏时,常用到的一些模块

二、我们要分析这个游戏有哪些类来组成,其中具体的方方法内容我们先不写

1.主类:主要包括游戏开始,游戏结束的功能

class MainGame():
      #初始化
      def ___init___(self):
         pass
      #开始游戏
      def startGame(self):
         pass
      #结束游戏
      def endGame(self):
         pass

2.坦克类:包括创建、显示、移动、射击功能

class Tanke():
     #初始化
     def __init__(self):
        pass
     #坦克展示的方法
     def displaytanke(self):
        pass
     #坦克射击的方法
     def shot(self):
        pass
     #坦克移动
     def move(self):
        pass

3.我方坦克类:我方坦克继承了坦克类,所以我们只需增加创建和与敌方坦克碰撞的方法即可

class Mytanke(Tanke):
    #初始化
    def __init__(self):
        pass
    #与敌方坦克碰撞
    def myhitenemytanke(self):
        pass

4.敌方坦克类:敌方坦克同样继承了坦克类,所以我们只需增加创建和与我方坦克碰撞的方法即可

class Enemytanke(Tanke):
    # 初始化
    def __init__(self):
        pass
    # 与我方坦克碰撞
    def hishitmytanke(self):
        pass

5.子弹类:包括创建、显示、移动、与坦克的碰撞、与墙壁的碰撞。

class Bullet():
    #初始化
    def __init__(self):
        pass
    #显示
    def displaybullet(self):
        pass
    #击中我方坦克
    def hitmytanke(self):
        pass
    #击中敌方坦克
    def hitenemytanke(self):
        pass
    #击中墙壁
    def hitwalls(self):
        pass

6.墙壁类:包括创建、显示。

class Walls():
    #初始化
    def __init__(self):
        pass
    #显示墙壁
    def displaywalls(self):
        pass

7.爆炸效果类:展示爆炸效果

class Explode():
    #初始化
    def __init__(self):
        pass
    #展示爆炸效果
    def displayexplode(self):
        pass

这个游戏的基本要素我们已经构建出来,接下来我们要做的就是将它们完善出来

三、显示游戏窗口

我们要玩游戏肯定得有一个游戏界面,也就是为这个游戏创建一个窗口。

import  pygame
#定义常量
SCREEN_WIDTH =1200
SCREEN_HEIGHT = 700
BG_COLOR = pygame.Color(0,0,0)

#主类
class MainGame():
    #游戏窗口
    window=None

    #初始化
    def __init__(self):
        pass
    #开始游戏
    def sartGame(self):
        #初始化窗口
        pygame.display.init()
        #创建窗口包括长宽、标题
        MainGame.window=pygame.display.set_mode([SCREEN_WIDTH ,SCREEN_HEIGHT])
        pygame.display.set_caption('坦克大战')
        #让窗口不断的刷新
        while True:
            #给窗口一个填充色
           MainGame.window.fill(BG_COLOR)
            #窗口刷新
           pygame.display.update()

这个过程我们就需要导入 pygame,因为显示都需要用到pygame.display这个模块。运行的时候我们只需调用MainGame().stargame()方法即可

四、添加事件监听:控制上、下、左、右四个方向键,实现针对不同的键改变坦克的方向和移动,点击关闭就能退出游戏。实现这个功能,我们主要利用 pygame.event这个模块来实现,在主类里新增一个事件监听方法

#结束游戏
    def endgame(self):
           exit()
    #事件监听
    def getEvent(self):
        #获取所有事件
        eventlist= pygame.event.get()
        #遍历事件
        for event in eventlist:
            if event.type == pygame.QUIT:
                self.endgame()
            elif event.type == pygame.K_UP:
                print('上')
            elif event.type == pygame.K_DOWN:
                print('下')
            elif event.type == pygame.K_RIGHT:
                print('右')
            elif event.type == pygame.K_LEFT:
                print('左')

五、加载我方坦克:加载坦克其实就是加载图片,首先我们要准备好四方向的坦克图片,利用pygame.image模块来实现,再利用pygame.rect来对图片的位置进行管理,图片位置的改变则是实现移动。我们先完善坦克类,然后再让我方坦克继承。

#坦克类
class  Tanke():
    #初始化
    def __init__(self,left,top):
        # 保存加载的图片
        self.images = {'U': pygame.image.load('img/U.png'),
                       'L': pygame.image.load('img/L.png'),
                       'R': pygame.image.load('img/R.png'),
                       'D': pygame.image.load('img/D.png')}
        #设置坦克方向
        self.direction ='U'
        #根据坦克方向来获取相应的坦克图片
        self.image =self.images[self.direction]
        #根据图片获取图片的位置
        self.rect=self.image.get_rect()
        # 设置区域的left和 top
        self.rect.left = left
        self.rect.top = top
    #展示坦克
    def displaytanke(self):
        #重新设置坦克的图片
        self.image=self.images[self.direction]
        #将坦克图片加载到窗口
        MainGame.window.blit(self.image,self.rect)

上面这个是坦克的创建方法,我们还需把它在主类中调用

def startGame(self):
    #创建我方坦克
    MainGame.TANK_P1 = Tank(400,300)
    while True:
      #将我方坦克加入到窗口中
      MainGame.TANK_P1.displayTank()

六、让坦克拥有移动和切换方向的功能

#移动
  def tankemove(self):
    #判断坦克的方向进行移动
    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<SCREEN_HEIGH:
        self.rect.top += self.speed
    elif self.direction == 'R':
      if self.rect.left+self.rect.height<SCREEN_WIDTH:
        self.rect.left += self.speed

这个方法,只能是按一下坦克,就动一下。为了能让坦克按住就能一直开,松开就会停,我们需要在坦克类属性里添加 self.stop =True ,通过按下方向键来修改self.stop的值并且对事件监听的方法进行修改

 def getEvent(self):
    #1.获取所有事件
    eventList = pygame.event.get()
    #2.遍历事件
    for event in eventList:  
      if event.type == pygame.QUIT:
        self.endGame()
      #判断事件类型是否为按键按下,如果是,继续判断按键是哪一个按键,来进行对应的处理
      if event.type == pygame.KEYDOWN:
        #具体是哪一个按键的处理
        if event.key ==pygame.K_LEFT:
          MainGame.tanke1.direction = 'L'
          MainGame.tanke1.stop =False
        elif event.key ==pygame.K_RIGHT:       
          MainGame.tanke1.direction = 'R'
          MainGame.tanke1.stop =False
        elif event.key ==pygame.K_UP:        
          MainGame.tanke1.direction = 'U'
          MainGame.tanke1.stop =False
        elif event.key ==pygame.K_DOWN:        
          MainGame.tanke1.direction = 'D'
          MainGame.tanke1.stop =False
        elif event.key ==pygame.K_SPACE:
          print("发射子弹")
     
      #松开的如果是方向键,才更改移动开关状态
     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:
          # 修改坦克的移动状态
           MainGame.tanke1.stop =True

七、加载敌方坦克:敌方坦克的方向是随机的,可以通过随机数生成

class EnemyTank(Tank):
  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')
   }
    self.direction =self.randDirection()
    self.image =self.images[self.direction]
    # 坦克所在的区域
    self.rect = self.image.get_rect()
    # 指定坦克初始化位置 分别距x,y轴的位置
    self.rect.left = left
    self.rect.top = top
    # 新增速度属性
    self.speed = speed
    self.stop = True

这里面我们还调用了一个未知的方法randDirection(),这个是我们随机生成方向的方法,所以我们必须要在敌方坦克类里面构建这个方法,然后才能被调用

def 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 randMove(self):
    if self.step <= 0:
      self.direction =self.randDirection()
      self.step = 50
    else:
      self.move()
      self.step -= 1

九、创建敌方坦克:敌方坦克的基本属性已经完成,但要创建多少辆,在界面哪里显示,我们还需要在主类里构建个方法。

#创建敌方坦克
  def creatEnemyTank(self):
    top = 100
    speed = random.randint(3,6)
    for i in range(MainGame.EnemTank_count):
      #每次都随机生成一个left值
      left = random.randint(1, 7)
      eTank =EnemyTank(left*100,top,speed)
    
    MainGame.EnemyTank_list.append(eTank)

把敌方坦克加入到窗口:坦克创建了,还需将它加载到窗口,再显示。

#将敌方坦克加入到窗口中
  def blitEnemyTank(self):
    for eTank in MainGame.EnemyTank_list:
      eTank.displayTank()
      #坦克移动的方法
      eTank.randMove()
  def startgame()
        .
        .
        .
       while True:
           self.blitEnemyTank()

十、完善子弹类:我方坦克发射子弹、敌方坦克随机发射子弹、实现子弹的移动、子弹与坦克的碰撞。

子弹的图片根据坦克的方向出现,然后移动子弹图片的位置。

class Bullet:
 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/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 = 7
    #用来记录子弹是否活着
    self.live = True
#展示子弹的方法
  def displayBullet(self):
  
    MainGame.window.blit(self.image,self.rect)

我方坦克发射子弹,就是按空格键产生子弹

#将我方子弹加入到窗口中
  def blitBullet(self):
    for bullet in MainGame.Bullet_list:
      #如果子弹还活着,绘制出来,否则,直接从
列表中移除该子弹
      if bullet.live:
        bullet.displayBullet()
        # 让子弹移动
        bullet.bulletMove()
      else:   
        MainGame.Bullet_list.remove(bullet)

并将子弹添加到一个子弹列表中,然后将子弹添加到窗口

      elif event.key ==pygame.K_SPACE:
          print("发射子弹")
          #产生一颗子弹
          m =Bullet(MainGame.TANK_P1)
          #将子弹加入到子弹列表
          MainGame.Bullet_list.append(m)
#将我方子弹加入到窗口中
  def blitBullet(self):
    for bullet in MainGame.Bullet_list:
      #如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
      if bullet.live:
        bullet.displayBullet()
        # 让子弹移动
        bullet.bulletMove()
      else:
           MainGame.Bullet_list.remove(bullet)

实现子弹的移动:在子弹类里创建子弹移动的方法

def bulletMove(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 <MainGame.SCREEN_HEIGHT - 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 <MainGame.SCREEN_WIDTH - self.rect.width:
        self.rect.left += self.speed
      else:
        # 修改状态值
        self.live = False

敌方坦克随机发射子弹:在敌方坦克类里构建一个射击方法,同样需要将子弹添加到敌方子弹列表中

def shot(self):
    num = random.randint(1,1000)
    if num  <= 20:
      return Bullet(self)
#将敌方坦克加入到窗口中
  def blitEnemyTank(self):
    for eTank in MainGame.EnemyTank_list:
      eTank.displayTank()
      #坦克移动的方法
      eTank.randMove()
      #调用敌方坦克的射击
      eBullet = eTank.shot()
      #如果子弹为None。不加入到列表
      if eBullet:
        # 将子弹存储敌方子弹列表    
        MainGame.Enemy_bullet_list.append(eBullet)

然后再将敌方发射的子弹添加到窗口

 #将敌方子弹加入到窗口中
  def blitEnemyBullet(self):
    for eBullet in MainGame.Enemy_bullet_list:
      # 如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
      if eBullet.live:
        eBullet.displayBullet()
        # 让子弹移动
        eBullet.bulletMove()
      else:
         MainGame.Enemy_bullet_list.remove(eBullet)

十一、我方子弹击中敌方坦克

在pygame中,使用pygame.sprite模块中的内置函数可以实现碰撞检测,而pygame.sprite.Spire是pygame精灵的的基类(在游戏开发中,通常把显示图像的对象叫做精灵Spire,精灵需要有两个属性,image要显示的图像,rect图像要显示在屏幕的位置),我们需要写一个自己的精灵类来继承pygame.sprite.Spire。然后让坦克类,子弹类都继承我们写的精灵类

class BaseItem(pygame.sprite.Sprite):
  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
class Tank(BaseItem):
class Bullet(BaseItem):

然后在子弹类中构建我方击中敌方坦克的方法,击中后则修改子弹和敌坦克的live属性的状态值

def hitEnemyTank(self):
    for eTank in MainGame.EnemyTank_list:
      if pygame.sprite.collide_rect(eTank,self):
        self.live = False
        eTank.live = False
#将我方子弹加入到窗口中
  def blitBullet(self):
    for bullet in MainGame.Bullet_list:
      #如果子弹还活着,绘制出来,否则,直接从列表中移除该子弹
      if bullet.live:
        bullet.displayBullet()
        # 让子弹移动
        bullet.bulletMove()
        # 调用我方子弹与敌方坦克的碰撞方法
        bullet.hitEnemyTank()
      else:
        MainGame.Bullet_list.remove(bullet)

十二、敌方坦克击中我方坦克:与我方击中敌方类似,同样在子弹类中构建击中我方坦克的方法

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

十三、添加爆炸效果:同样也是展示图片,先添加后展示

class Explode():
  def __init__(self,tank):
    self.rect = tank.rect
    self.step = 0
    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.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 += 1
    else:
      self.live = False
      self.step = 0

---------------------------------------------------------------------------------------------------------------------------------

基本上我们已经实现了的游戏功能,随机出现的坦克随机发射子弹,我方坦克能射击消灭敌方坦克,可以增加墙壁和一些相关的优化。自己多学一下也能解决,下面是整个游戏完整的代码

import pygame , time,random
from pygame.sprite import Sprite
#定义常量
SCREEN_WIDTH =1200
SCREEN_HEIGHT = 700
BG_COLOR = pygame.Color(0,0,0)
TEXT_COLOR = pygame.Color(255,0,0)
#创建精灵类
class BaseItem(Sprite):
    pass
#主类
class Maingame():
    window = None
    mytanke=None
    enemyCount=5
    enemyList =[]
    myBulletlist=[]
    enemybulletlist=[]
    expllist=[]
    wallslist=[]
    #初始化
    def __init__(self) -> None:
        pass
    #创建敌方坦克
    def createEnemytanke(self):
        top=100
        for i in range(Maingame.enemyCount):
            left =random.randint(0,1200)
            speed =random.randint(1,4)
            enemyTanke=enemytanke(left,top,speed)
            #添加列表
            Maingame.enemyList.append(enemyTanke)
    #加载敌方他坦克
    def displayenemytanke(self):
        for enemyTanke in Maingame.enemyList:
            if enemyTanke.live:
               enemyTanke.displayTanke()
               enemyTanke.randMove()
            #初始化敌方子弹
               enemybullet =enemyTanke.shot()
               enemyTanke.tankehitwalls()
               if Maingame.mytanke and Maingame.mytanke.live:
                     enemyTanke.enemytkhitmytabke()
               if enemybullet:
                  Maingame.enemybulletlist.append(enemybullet)
            else:
                Maingame.enemyList.remove(enemyTanke)
    #显示我方坦克子弹
    def displaymybullet(self):
        for myBullet in Maingame.myBulletlist:
            #判断子弹是否存活
            if myBullet.live:
                myBullet. displaybullet()
                myBullet.bulletmove()
                myBullet.hitenemytanke()
                myBullet.hitwalls()
            else:
                Maingame.myBulletlist.remove(myBullet)
    #显示敌方坦克子弹
    def displayenemybullet(self):
        for enemybullet in Maingame.enemybulletlist:
            if enemybullet.live:
                enemybullet.displaybullet()
                enemybullet.bulletmove()
                #调用敌方子弹与我方坦克碰撞方法
                enemybullet.hitmytanke()
                enemybullet.hitwalls()
            else:
                Maingame.enemybulletlist.remove(enemybullet)
    #展示爆炸效果
    def displayexpl(self):
        for expl in Maingame.expllist:
            if expl.live:
                expl.displayexplode()
            else:
                Maingame.expllist.remove(expl)
    #创建我方坦克
    def createmytanke(self):
        Maingame.mytanke =  mytanke(450, 600)
    #创建墙壁方法
    def createwall(self):
        top =SCREEN_HEIGHT/2
        for i in range(6):
            wall=Walls(i*230,top)
            Maingame.wallslist.append(wall)
    #展示墙壁的方法
    def displaywallslist(self):
        for wall in Maingame.wallslist:
            if wall.live:
                wall.displaywalls()
            else:
                Maingame.wallslist.remove(wall)

      #开始游戏
    def sartgame(self):
    #初始化窗口
       pygame.display.init()
    #设置窗口大小
       Maingame.window=pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])
    #设置窗口标题
       pygame.display.set_caption('坦克大战01')
    #初始化我方坦克
       self.createmytanke()
    #调用创建敌方坦克
       self.createEnemytanke()
    #调用创建 墙壁方法
       self.createwall()
       while True:
         time.sleep(0.02)
           #设置窗口填充色
         Maingame.window.fill(BG_COLOR)
           #添加文字信息
         textSurface=self.getTextSurface('敌方坦克剩余数量%d'%len(Maingame.enemyList))
           #添加主窗口显示文字信息
         Maingame.window.blit(textSurface,(10,5))
           #添加事件监听
         self.getEvent()
          #调用坦克的显示方法
         if Maingame.mytanke and Maingame.mytanke.live:
              Maingame.mytanke.displayTanke()
         else:
              del Maingame.mytanke
              Maingame.mytanke= None
           #调用坦克移动的方法
         if  Maingame.mytanke and Maingame.mytanke.live:
            if not Maingame.mytanke.stop:
                Maingame.mytanke.move()
                Maingame.mytanke.tankehitwalls()
                Maingame.mytanke.mytankehitenemytanke()
        #加载敌方坦克
         self.displayenemytanke()
        #加载我方子弹
         self.displaymybullet()
        #加载敌方子弹
         self.displayenemybullet()
         #加载爆炸效果
         self.displayexpl()
         #加载墙壁
         self.displaywallslist()


         pygame.display.update()
    #结束游戏
    def endgame(self):
        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:
               if not Maingame.mytanke:
                  if event.key == pygame.K_ESCAPE:
                      self.createmytanke()
               if Maingame.mytanke and Maingame.mytanke.live:
                 if event.key == pygame.K_LEFT:
                    Maingame.mytanke.direction='L'
                    #修改坦克的移动开关
                    Maingame.mytanke.stop =False
                 elif event.key == pygame.K_RIGHT:
                    Maingame.mytanke.direction = 'R'
                    # 修改坦克的移动开关
                    Maingame.mytanke.stop = False
                 elif event.key == pygame.K_UP:
                    Maingame.mytanke.direction = 'U'
                    # 修改坦克的移动开关
                    Maingame.mytanke.stop = False
                 elif event.key == pygame.K_DOWN:
                    Maingame.mytanke.direction = 'D'
                    # 修改坦克的移动开关
                    Maingame.mytanke.stop = False
                 elif event.key == pygame.K_SPACE:
                     if len(Maingame.myBulletlist) < 5:
                        myBullet=bullet(Maingame.mytanke)
                        Maingame.myBulletlist.append(myBullet)

            #判断键盘是否松开
            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.mytanke and Maingame.mytanke.live:
                       Maingame.mytanke.stop=True


#坦克类
class Tanke(BaseItem):
    #初始化
    def __init__(self,left,top) -> None:
        #保存加载的图片
        self.images ={'U':pygame.image.load('img/U.png'),
                      'L':pygame.image.load('img/L.png'),
                      'R':pygame.image.load('img/R.png'),
                      'D':pygame.image.load('img/D.png')}
        #设置坦克方向
        self.direction = 'L'
        #根据坦克方向,获取加载的图片
        self.image = self.images.get(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 displayTanke(self):
        self.image =self.images.get(self.direction)
        #调用blit方法展示
        Maingame.window.blit(self.image,self.rect)
    #移动
    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 == 'R':
             if self.rect.left + self.rect.height<SCREEN_WIDTH :
                  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<SCREEN_HEIGHT:
                 self.rect.top += self.speed
    #射击
    def shot(self):
        pass
    #设置坦克位置为移动之前的位置
    def stay(self):
        self.rect.left=self.oldleft
        self.rect.top =self.oldtop
    #碰撞墙壁
    def tankehitwalls(self):
        for walls in Maingame.wallslist:
            if pygame.sprite.collide_rect(self,walls):
                self.stay()


#我方坦克
class mytanke(Tanke):
    #初始化
    def __init__(self,left,top) -> None:
        super(mytanke, self).__init__(left,top)
    #碰撞敌方坦克
    def mytankehitenemytanke(self):
        for enemytanke in Maingame.enemyList:
          if pygame.sprite.collide_rect(self,enemytanke):
              self.stay()
#敌方坦克
class enemytanke(Tanke):
    #初始化
    def __init__(self,left,top,speed) -> None:
        #调用父类初始化方法
        super(enemytanke,self).__init__(left,top)
        #加载保存的图片
        self.images={'U':pygame.image.load('img/U.2.png'),
                     'D':pygame.image.load('img/D.2.png'),
                     'L':pygame.image.load('img/L.2.png'),
                     'R':pygame.image.load('img/R.2.png')
                     }
        #设置敌方坦克方向
        self.direction=self.randDirection()
        #根据方向获取图片
        self.image=self.images.get(self.direction)
        #获取矩形区域
        self.rect=self.image.get_rect()
        #设置left,top
        self.rect.left=left
        self.rect.top=top
        self.speed=speed
        #设置步数
        self.step=50
    #设置射击方法
    def shot(self):
        num =random.randint(0,100)
        if num <5:
            return bullet(self)
    #敌方坦克与我方碰撞
    def enemytkhitmytabke(self):

        if pygame.sprite.collide_rect(self,Maingame.mytanke):
            self.stay()



    #随机生成方向
    def 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 randMove(self):
        if self.step<=0:
            self.direction=self.randDirection()
            self.step=50
        else:
            self.move()
            self.step-=1

    #碰撞我方坦克
    def hitmytanke(self):
        pass
#子弹类
class bullet(BaseItem):
    #初始化
    def __init__(self,tank):
        #获取子弹图片
        self.image=pygame.image.load('img/bullet.png')
        #设置方向
        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 + 4*self.rect.height
        elif self.direction == 'L':
            self.rect.left = tank.rect.left - tank.rect.width / 2 + self.rect.width
            self.rect.top = tank.rect.top + 1.5*self.rect.height
        elif self.direction == 'R':
            self.rect.left = tank.rect.left + tank.rect.width / 2 + 2*self.rect.width
            self.rect.top = tank.rect.top + 1.5*self.rect.height
        #子弹速度
        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=='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
        elif self.direction=='R':
            if self.rect.left + self.rect.width < SCREEN_WIDTH:
                self.rect.left +=self.speed
            else:  # 碰到墙壁
                self.live = False
    #展示子弹
    def displaybullet(self):
        #将图片加载到窗口
        Maingame.window.blit(self.image,self.rect)
    #击中我方坦克
    def hitmytanke(self):
        if Maingame.mytanke and Maingame.mytanke.live:
            if pygame.sprite.collide_rect(self,Maingame.mytanke):
                expl = explode(Maingame.mytanke)
                Maingame.expllist.append(expl)
                self.live =False
                Maingame.mytanke.live =False

    #击中敌方坦克
    def hitenemytanke(self):
        #遍历敌方坦克列表
        for enemytanke in Maingame.enemyList:
           if  pygame.sprite.collide_rect(self,enemytanke):
               #修改子弹 和敌坦克状态
               enemytanke.live =False
               self.live=False
               #初始化爆炸出效果
               expl=explode(enemytanke)
               Maingame.expllist.append(expl)
    #击中墙壁
    def hitwalls(self):
        for walls in Maingame.wallslist:
            if pygame.sprite.collide_rect(self,walls):
                self.live=False
                walls.hp -=1
                if walls.hp <= 0:
                    walls.live=False

#墙壁类
class Walls():
    #初始化
    def __init__(self,left,top):
        #加载图片
        self.images=pygame.image.load('img/qb.png')
        #获取区域
        self.rect=self.images.get_rect()
        #设置left,top
        self.rect.left=left
        self.rect.top=top
        #存活状态
        self.live=True
        #生命值
        self.hp=6
    #展示墙壁
    def displaywalls(self):
        Maingame.window.blit(self.images,self.rect)

#爆炸效果类
class explode():
    #初始化
   def __init__(self,tanke):
       #爆炸位置
       self.rect=tanke.rect
       self.images=[
                    pygame.image.load('img/02.png'),
                    pygame.image.load('img/03.png'),
                    pygame.image.load('img/03.png'),
                    pygame.image.load('img/03.png'),
                    pygame.image.load('img/03.png'),
                    pygame.image.load('img/03.png')
                     ]
       self.step=0
       self.image=self.images[self.step]
      #生存状态
       self.live =True
    #展示爆炸效果
   def displayexplode(self):
       if self.step<len(self.images):
            self.imsge =self.images[self.step]
            self.step+=1
           #添加到主窗口
            Maingame.window.blit(self.image,self.rect)
       else:
            self.live=False
            self.step = 0

#主方法
if __name__ == '__main__':
#调用主类中startgame()
   Maingame().sartgame()

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值