python3坦克大战

# coding = utf-8
       import pygame, sys, time
       from pygame.locals import *
       from random import randint
       '''坦克大战主窗口'''
       class TankMain(object):
           width = 700
           height = 600
           wall_list = []
           my_tank = None
           home = None
           lives = 3
           # enemy_list = []     # 敌方坦克列表
           enemy_list = pygame.sprite.Group()  # 敌方坦克(精灵)族群
           my_tank_missile = []    # 我方子弹列表
           enemy_tank_missile = pygame.sprite.Group()  # 敌方子弹(精灵)族群
           explode_list = []       # 爆炸效果列表
           # 开始游戏
           def startGame(self):    # 开始游戏
               pygame.init()   # pygame模块初始化,加载系统资源
               # 设置一个窗口,第一个参数:(宽,高),第二个参数:窗口可变{0,RESIZABLE,FULLSCREEM,..},第三个参数:颜色位数{32,64,..}
               # screem是一个Surface表面对象
               screem = pygame.display.set_mode((TankMain.width, TankMain.height), 0, 32)
               # 给窗口设置标题
               pygame.display.set_caption("坦克大战")
               # 生成我方坦克,敌方坦克,障碍物等
               self.creat(screem)
               # 循环显示屏幕内容,形成动态效果
               while True:
                   screem.fill((0, 0, 0))    # 设置背景颜色 RGB (255,255,255):白色 (0,0,0):黑色
                   # 显示
                   self.show(screem)
                   # 事件处理
                   self.get_event(TankMain.my_tank, screem)  # 获取事件进行处理
                   time.sleep(0.05)    # 每次休息0.05秒跳到下一帧
                   pygame.display.update()     # 显示重置
           # 在屏幕上显示文字内容
           def write_text(self):
               font = pygame.font.SysFont('simhei', 13)  # 定义一个字体 参数: 字体 大小 粗细
               text_sf0 = font.render("我方坦克生命:%d"%TankMain.lives, True, (255, 0, 0))  # 根据字体创建一个文字的图像 参数:内容 抗锯齿 颜色 背景
               text_sf1 = font.render("敌方坦克数量:%d"%len(TankMain.enemy_list), True, (255, 0, 0))
   # 根据字体创建一个文字的图像 参数:内容 抗锯齿 颜色 背景
               text_sf2 = font.render("我方坦克屏幕子弹数量:%d"%len(TankMain.my_tank_missile), True,
   (255, 0, 0))  # 根据字体创建一个文字的图像 参数:内容 抗锯齿 颜色 背景
               return text_sf0, text_sf1, text_sf2
           # 生产,创建我方坦克,敌方坦克
           def creat(self, screem):
               # 生产墙列表
               for i in range(1, 14):
                   if i % 3 == 0:
                       TankMain.wall_list.append(GrassBarrier(screem, i * Barrier.width, TankMain.height - 400))
                       TankMain.wall_list.append(CobWallBarrier(screem, i * Barrier.width, 300))
                   elif i % 4 == 0:
                       pass
                   elif i % 5 == 0:
                       TankMain.wall_list.append(GrassBarrier(screem, i * Barrier.width, TankMain.height-400))
                       TankMain.wall_list.append(IronWallBarrier(screem, i * Barrier.width, 300))
                   elif i % 7 == 0:
                       TankMain.wall_list.append(CobWallBarrier(screem, i * Barrier.width, 300))
                   else:
                       TankMain.wall_list.append(IronWallBarrier(screem, i * Barrier.width, 300))
                       TankMain.wall_list.append(WaterBarrier(screem, i * Barrier.width, TankMain.height - 400))
                       TankMain.wall_list.append(GrassBarrier(screem, i * Barrier.width, i*Barrier.height))
                       TankMain.wall_list.append(WaterBarrier(screem, TankMain.width-i * Barrier.width, i * Barrier.height))
               # 生成我方坦克的家
               for i in range(0, 3):
                   if i == 1:
                       TankMain.home = HomeBarrier(screem, TankMain.width/2-HomeBarrier.width/2,
   TankMain.height-HomeBarrier.width)
                       TankMain.wall_list.append(CobWallBarrier(screem, (TankMain.width+(2*i-3)*HomeBarrier.width)/2,
   TankMain.height-HomeBarrier.width*2))
                   else:
                       TankMain.wall_list.append(CobWallBarrier(screem, (TankMain.width+(2*i-3)*HomeBarrier.width)/2,
   TankMain.height-HomeBarrier.width))
                       TankMain.wall_list.append(CobWallBarrier(screem, (TankMain.width+(2*i-3)*HomeBarrier.width)/2,
   TankMain.height-HomeBarrier.width*2))
               # 生产我方坦克
               TankMain.my_tank = MyTank(screem)
               # 生产敌方坦克
               for i in range(1, 6):
                   if i % 3 == 0:
                       TankMain.enemy_list.add(EnemyTankQ(screem))  # 在族群中添加3个普通坦克,就会有一个强坦克
                   TankMain.enemy_list.add(EnemyTank(screem))  # 在族群中添加一个精灵sprite(坦克)
           # 在屏幕上显示(矩形rect, sprite, image,等)
           def show(self, screem):
               # 显示文字
               for i, text in enumerate(self.write_text(), 0):
                   screem.blit(text, (0, 5 + (13 * i)))  # 在左上角显示文字 参数:源 位置(x,y)
               # 显示我方坦克的家
               if TankMain.home and TankMain.home.live:
                   TankMain.home.display()
                   TankMain.home.hit_other()
               else:
                   TankMain.home = None
                   TankMain.lives = 0
                   TankMain.my_tank = None
               # 显示敌方坦克
               for enemy_tank in TankMain.enemy_list:
                   if enemy_tank.live:
                       enemy_tank.display()
                       # enemy_tank.hit_ourself()
                       enemy_tank.random_move()
                       enemy_tank.random_fire()
                   else:
                       TankMain.enemy_list.remove(enemy_tank)
               # 显示我方坦克
               if TankMain.my_tank and TankMain.my_tank.live:
                   TankMain.my_tank.enemy_hit_mytank()
                   TankMain.my_tank.display()
                   TankMain.my_tank.move()
               elif TankMain.lives:
                   TankMain.my_tank = MyTank(screem)
                   TankMain.my_tank.live = True
                   TankMain.lives -= 1
               else:
                   TankMain.my_tank = None
                   pass
               # 显示我方炮弹
               for mm in TankMain.my_tank_missile:
                   if mm.live:
                       mm.display()
                       mm.hit_tank()  # 检测是否命中敌方坦克
                       mm.move()
                   else:
                       TankMain.my_tank_missile.remove(mm)
               # 显示敌方炮弹
               for em in TankMain.enemy_tank_missile:
                   if em.live:
                       em.display()
                       em.move()
                   else:
                       TankMain.enemy_tank_missile.remove(em)
               # 显示墙
               for wall in TankMain.wall_list:
                   if wall.live:
                       wall.display()
                       wall.hit_other()
                   else:
                       TankMain.wall_list.remove(wall)
               # 显示爆炸效果
               for explode in TankMain.explode_list:
                   if explode.live:
                       explode.display()
                   else:
                       TankMain.explode_list.remove(explode)
               # 显示胜利
               if not TankMain.enemy_list:
                   finall_text = pygame.font.SysFont('simhei', 50).render("YOU WIN", True, (255, 0, 0), (0, 255, 0))
                   screem.blit(finall_text, (TankMain.width / 2 - 70, TankMain.height / 2 - 25))
               # 显示失败
               if (TankMain.lives == 0 and not TankMain.my_tank) or not TankMain.home :
                   finall_text = pygame.font.SysFont('simhei', 50).render("YOU LOSE", True, (127, 127, 127), (255, 0, 0))
                   screem.blit(finall_text, (TankMain.width / 2 - 80, TankMain.height / 2 - 25))
           # 获取所有事件(敲击键盘,点击鼠标等)
           def get_event(self, my_tank, screem):
               for event in pygame.event.get():
                   if event.type == QUIT:  # 退出事件
                       self.stopGame()     # 退出
                   # if event.type == KEYDOWN and not my_tank and TankMain.lives and event.key == K_RETURN:
                   #     TankMain.lives -= 1
                   #     TankMain.my_tank = MyTank(screem)
                   if event.type == KEYDOWN and my_tank:       # 敲击键盘事件
                       if event.key == K_ESCAPE:   # 敲击键盘ESC
                           self.stopGame()     # 退出
                       if event.key == K_LEFT or event.key == K_a:     # 敲击键盘方向键向左
                           my_tank.direction = 'L'
                           my_tank.stop = False
                       if event.key == K_RIGHT or event.key == K_d:    # 敲击键盘方向键向右
                           my_tank.direction = 'R'
                           my_tank.stop = False
                       if event.key == K_UP or event.key == K_w:       # 敲击键盘方向键向上
                           my_tank.direction = 'U'
                           my_tank.stop = False
                       if event.key == K_DOWN or event.key == K_s:     # 敲击键盘方向键向下
                           my_tank.direction = 'D'
                           my_tank.stop = False
                       if  event.key == K_SPACE:
                           mm = my_tank.fire()
                           TankMain.my_tank_missile.append(mm)
                   if event.type == KEYUP and my_tank:
                       if event.key == K_LEFT or event.key == K_RIGHT or event.key == K_UP or event.key == K_DOWN \
                               or event.key == K_a or event.key == K_d or event.key == K_w or event.key == K_s:
                           my_tank.stop = True
                   if TankMain.my_tank and event.type == MOUSEBUTTONDOWN:  # 鼠标事件
                       mm = my_tank.fire()
                       TankMain.my_tank_missile.append(mm)
           # 关闭游戏
           def stopGame(self):  # 停止游戏
               sys.exit()
       
       # 坦克大战游戏中的基础父类
       class BaseIetm(pygame.sprite.Sprite):
           def __init__(self, screem):
               pygame.sprite.Sprite.__init__(self)
               self.screem = screem  # 坦克,炮弹,墙移动显示要用到的屏幕窗口
       
            # 把坦克显示在游戏窗口上
           def display(self):
               if self.live:
                   self.image = self.images[self.direction]
                   self.screem.blit(self.image, self.rect)
       
       # 坦克父类
       class Tank(BaseIetm):
           # 定义属性,所有坦克的宽高都是一样的
           width = 47
           height = 47
           def __init__(self, screem, left, top):
               super().__init__(screem)
               self.direction = 'D'    # 表示坦克方向,默认向下(U,D,L,R)
               self.speed = 5          # 坦克默认速度
               self.stop = False
               self.images = {}        # 表示坦克图片字典,key:方向,value:图片(surface)
               self.images['L'] = pygame.image.load("image/T_L.png")   # 我方坦克
               self.images['R'] = pygame.image.load("image/T_R.png")
               self.images['U'] = pygame.image.load("image/T_U.png")
               self.images['D'] = pygame.image.load("image/T_D.png")
               self.image = self.images[self.direction]    # 坦克的图片由坦克的方向决定
               self.rect = self.image.get_rect()   # 获得图片的边界
               self.rect.left = left       # 设置图片位置x
               self.rect.top = top         # 设置图片位置y
               self.live = True    # 决定坦克生死
               self.oldtop = self.rect.top
               self.oldleft = self.rect.left
       
           # 坦克碰到障碍物,停止前进
           def stay(self):
               self.rect.top = self.oldtop
               self.rect.left = self.oldleft
       
           # 坦克的移动
           def move(self):
               if not self.stop:
                   self.oldtop = self.rect.top
                   self.oldleft = self.rect.left
                   if self.direction == 'L':
                       if self.rect.left > 0:
                           self.rect.left -= self.speed
                       else:
                           self.rect.left = 0
                   elif self.direction == 'R':
                       if self.rect.right < TankMain.width:
                           self.rect.right += self.speed
                       else:
                           self.rect.right = TankMain.width
                   elif self.direction == 'U':
                       if self.rect.top > 0:
                          self.rect.top -= self.speed
                       else:
                           self.rect.top = 0
                   elif self.direction == 'D':
                       if self.rect.bottom < TankMain.height:
                            self.rect.bottom += self.speed
                       else:
                           self.rect.bottom = TankMain.height
       
           # 坦克开火,发射炮弹
           def fire(self):
               pass
       # 我方坦克
       class MyTank(Tank):
           def __init__(self, screem):
               super().__init__(screem, TankMain.width/2-MyTank.width/2, TankMain.height-150)  # 我方坦克初始化位置
               self.direction = 'U'        # 我方坦克默认朝上
               self.stop = True
       
           def enemy_hit_mytank(self):
               if TankMain.enemy_tank_missile:
                   em_list = pygame.sprite.spritecollide(self, TankMain.enemy_tank_missile, False)
                   for em in em_list:
                       em.live = False
                       self.live = False
                       explode = Explode(self.screem, self.rect)
                       TankMain.explode_list.append(explode)
               # if TankMain.enemy_list:
               #     tank_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, False)
               #     for tank in tank_list:
               #         tank.stop = True
               #         tank.stay()
       
           # 坦克开火,发射炮弹
           def fire(self):
               mm = MyMissile(self.screem, self)
               return mm
       # 敌方坦克
       class EnemyTank(Tank):
           def __init__(self, screem):
               super().__init__(screem, randint(0, TankMain.width), randint(0, TankMain.height-350))
               self.images['L'] = pygame.image.load("image/tan_l.png")     # 敌方坦克
               self.images['R'] = pygame.image.load("image/tan_r.png")
               self.images['U'] = pygame.image.load("image/tan_u.png")
               self.images['D'] = pygame.image.load("image/tan_d.png")
               self.speed = 4   # 敌方坦克速度
               self.step = 8    # 敌方坦克按照一个方向移动6步
               self.get_random_direction()
       
            # 获得一个随机方向
           def get_random_direction(self):
               r = randint(0, 4)
               if r == 0:
                   self.stop = True
               elif r == 1:
                   self.direction = 'L'
                   self.stop = False
               elif r == 2:
                   self.direction = 'R'
                   self.stop = False
               elif r == 3:
                   self.direction = 'U'
                   self.stop = False
               elif r == 4:
                   self.direction = 'D'
                   self.stop = False
       
           # 敌方坦克确定一个随机方向移动8步,然后再次改变方向移动
           def random_move(self):
               if self.live:
                   if self.step == 0:  # 如果已经移动了8步,则又随机获得一个方向
                       self.get_random_direction()
                       self.step = 8
                   else:
                       self.move()
                       self.step -= 1
           # 坦克开火,发射炮弹
           def random_fire(self):
               if randint(1, 100) > 95:
                   em = EnemyMissile(self.screem, self)
                   TankMain.enemy_tank_missile.add(em)
               else:
                   return
       
       # 敌方坦克
       class EnemyTankQ(EnemyTank):
           def __init__(self, screem):
               super().__init__(screem)
               self.images['L'] = pygame.image.load("image/tank_l.png")     # 敌方坦克
               self.images['R'] = pygame.image.load("image/tank_r.png")
               self.images['U'] = pygame.image.load("image/tank_u.png")
               self.images['D'] = pygame.image.load("image/tank_d.png")
       
       # 炮弹父类
       class Missile(BaseIetm):
           width = 12
           height = 12
           def __init__(self, screem, tank):
               super().__init__(screem)
               self.tank = tank
               self.direction = tank.direction  # 表示炮弹方向,由坦克方向决定
               self.speed = 12  # 炮弹默认速度
               self.images = {}    # 表示炮弹图片字典,key:方向,value:图片(surface)
               self.images['L'] = pygame.image.load("image/pao2.png")  # 我方炮弹
               self.images['R'] = pygame.image.load("image/pao2.png")
               self.images['U'] = pygame.image.load("image/pao2.png")
               self.images['D'] = pygame.image.load("image/pao2.png")
               self.image = self.images[self.direction]  # 炮弹的图片由炮弹的方向决定
               self.rect = self.image.get_rect()  # 获得炮弹的边界
               self.rect.left = tank.rect.left + (tank.width - self.width)/2  # 设置炮弹位置x
               self.rect.top = tank.rect.top + (tank.height - self.height)/2   # 设置炮弹位置y
               self.live = True  # 决定炮弹生死
       
           # 炮弹移动
           def move(self):
               if self.live:
                   if self.direction == 'L':
                       if self.rect.left > 0:
                           self.rect.left -= self.speed
                       else:
                           self.live = False
                   elif self.direction == 'R':
                       if self.rect.right < TankMain.width:
                           self.rect.right += self.speed
                       else:
                           self.live = False
                   elif self.direction == 'U':
                       if self.rect.top > 0:
                          self.rect.top -= self.speed
                       else:
                           self.live = False
                   elif self.direction == 'D':
                       if self.rect.bottom < TankMain.height:
                            self.rect.bottom += self.speed
                       else:
                           self.live = False
       
           # 炮弹击中坦克,第一种:我方炮弹击中敌方坦克,需要我方炮弹的边界和所有敌方坦克边界比对,看是否重叠,返回重叠位置
           # 第二种:敌方炮弹击中我方坦克,需要敌方炮弹和我方坦克位置比对,若重叠,返回位置
           def hit_tank(self):
               if TankMain.enemy_list:   # 我方炮弹击中敌方坦克
                   #  在与另一个精灵相交的组中查找精灵,检测是否碰撞 参数:本精灵 目标精灵组 是否删除组中所有碰撞的(Sprite)精灵
                   em_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, False)
                   for em in em_list:
                       self.live = False
                       em.live = False
                       explode = Explode(self.screem, em.rect)  # 产生一个爆炸对象
                       TankMain.explode_list.append(explode)
       # 我方炮弹
       class MyMissile(Missile):
           def __init__(self, screem, tank):
               super().__init__(screem, tank)
       # 敌方炮弹
       class EnemyMissile(Missile):
           def __init__(self, screem, tank):
               super().__init__(screem, tank)
               self.images['L'] = pygame.image.load("image/pao3.png")  # 我方炮弹
               self.images['R'] = pygame.image.load("image/pao3.png")
               self.images['U'] = pygame.image.load("image/pao3.png")
               self.images['D'] = pygame.image.load("image/pao3.png")
       
       # 爆炸类
       class Explode(BaseIetm):
           def __init__(self, screem, rect):
               super().__init__(screem)
               self.live = True
               self.images = [pygame.image.load("image/bao1.png"),
                               pygame.image.load("image/bao2.png"),
                               pygame.image.load("image/bao3.png"),
                               pygame.image.load("image/bao4.png"),
                               pygame.image.load("image/bao5.png"),
                               pygame.image.load("image/bao6.png")]
               self.step = 0
               self.image = self.images[self.step]     # 初始化第一张爆炸效果图
               self.rect = rect
       
           def display(self):
               if self.live:
                   if self.step == len(self.images) :  # 显示最后一张
                       self.live = False
                   else:
                       self.image = self.images[self.step]
                       self.screem.blit(self.image, self.rect)     # 爆炸位置由坦克的rect位置决定
                       self.step += 1
               else:
                   pass    # 删除该爆炸效果对象
       
       # 游戏中的静态障碍物(建筑,草,水等)
       class Barrier(BaseIetm):
           width = 47
           height = 47
           def __init__(self, screem, left, top):
               super().__init__(screem)
               # self.rect = Rect(left, top, width, height)  # 构建一个rect(一个物体在屏幕的位置及大小 )
               self.image = pygame.transform.scale(pygame.Surface((40, 40)), (40, 40))
               self.rect = self.image.get_rect()
               self.rect.left = left
               self.rect.top = top
               self.live = True
       
           def display(self):
               if self.live:
                   self.screem.blit(self.image, self.rect)
           # 碰撞检测
           def hit_other(self):
               pass
       # 障碍物--铁墙
       class IronWallBarrier(Barrier):
           def __init__(self, screem, left, top):
               super().__init__(screem, left, top)
               self.image = pygame.transform.scale(pygame.image.load("image/zhuan.gif"),
   (Barrier.width, Barrier.height))
       
           # 铁墙碰撞检测
           def hit_other(self):
               if TankMain.my_tank:
                   if pygame.sprite.collide_rect(self, TankMain.my_tank):
                       TankMain.my_tank.stop = True
                       TankMain.my_tank.stay()
               if TankMain.enemy_list:
                   et_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, False)
                   for et in et_list:
                       et.stop = True
                       et.stay()
               if TankMain.my_tank_missile:
                   mm_list = pygame.sprite.spritecollide(self, TankMain.my_tank_missile, False)
                   for mm in mm_list:
                       mm.live = False
               if TankMain.enemy_tank_missile:
                   em_list = pygame.sprite.spritecollide(self, TankMain.enemy_tank_missile, False)
                   for em in em_list:
                       em.live = False
       # 障碍物--土墙
       class CobWallBarrier(Barrier):
           def __init__(self, screem, left, top):
               super().__init__(screem, left, top)
               self.image = pygame.transform.scale(pygame.image.load("image/tu.gif"),
   (Barrier.width, Barrier.height))
       
           # 土墙碰撞检测
           def hit_other(self):
               if TankMain.my_tank:
                   if pygame.sprite.collide_rect(self, TankMain.my_tank):
                       TankMain.my_tank.stop = True
                       TankMain.my_tank.stay()
               if TankMain.enemy_list:
                   et_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, False)
                   for et in et_list:
                       et.stop = True
                       et.stay()
               if TankMain.my_tank_missile:
                   mm_list = pygame.sprite.spritecollide(self, TankMain.my_tank_missile, False)
                   for mm in mm_list:
                       mm.live = False
                       self.live = False
                       explode = Explode(self.screem, self.rect)
                       TankMain.explode_list.append(explode)
               if TankMain.enemy_tank_missile:
                   em_list = pygame.sprite.spritecollide(self, TankMain.enemy_tank_missile, False)
                   for em in em_list:
                       em.live = False
                       self.live = False
                       explode = Explode(self.screem, self.rect)
                       TankMain.explode_list.append(explode)
       # 障碍物--草
       class GrassBarrier(Barrier):
           def __init__(self, screem, left, top):
               super().__init__(screem, left, top)
               self.image = pygame.transform.scale(pygame.image.load("image/cao.gif"),
   (Barrier.width, Barrier.height))
       
           # 草碰撞检测
           def hit_other(self):
               pass
       # 障碍物--水
       class WaterBarrier(Barrier):
           def __init__(self, screem, left, top):
               super().__init__(screem, left, top)
               self.image = pygame.transform.scale(pygame.image.load("image/shui.gif"),
   (Barrier.width, Barrier.height))
       
           # 水碰撞检测
           def hit_other(self):
               pass
       # 我方坦克的家
       class HomeBarrier(Barrier):
           def __init__(self, screem, left, top):
               super().__init__(screem, left, top)
               self.image = pygame.transform.scale(pygame.image.load("image/home.gif"),
   (Barrier.width, Barrier.height))
       
           # 家碰撞检测
           def hit_other(self):
               if TankMain.my_tank:
                   if pygame.sprite.collide_rect(self, TankMain.my_tank):
                       TankMain.my_tank.stop = True
                       TankMain.my_tank.stay()
               if TankMain.enemy_list:
                   et_list = pygame.sprite.spritecollide(self, TankMain.enemy_list, False)
                   for et in et_list:
                       et.stop = True
                       et.stay()
               if TankMain.my_tank_missile:
                   mm_list = pygame.sprite.spritecollide(self, TankMain.my_tank_missile, False)
                   for mm in mm_list:
                       mm.live = False
                       self.live = False
                       explode = Explode(self.screem, self.rect)
                       TankMain.explode_list.append(explode)
               if TankMain.enemy_tank_missile:
                   em_list = pygame.sprite.spritecollide(self, TankMain.enemy_tank_missile, False)
                   for em in em_list:
                       em.live = False
                       self.live = False
                       explode = Explode(self.screem, self.rect)
                       TankMain.explode_list.append(explode)
       
       # 测试运行
       if __name__=='__main__':
           game = TankMain()
           game.startGame()

图片链接:http://www.aigei.com/view/63180.html#items 自己下
运行效果图:
python3坦克大战_第1张图片
主要用到pygame模块
官方文档:http://www.pygame.org/docs/

你可能感兴趣的:(python实战)