用 Python 写个坦克大战

    技术2022-07-10  135

    文 | 野客

    来源:Python 技术「ID: pythonall」

    坦克大战是一款策略类的平面射击游戏,于 1985 年由 Namco 游戏公司发布,尽管时至今日已经有了很多衍生类的游戏,但这款游戏仍然受到了相当一部分人的欢迎,本文我们看一下如何使用 Python 来实现这款游戏,游戏实现主要用到的 Python 库为 pygame。

    简介

    坦克大战的组成主要包括:场景、坦克、子弹、食物、大本营,其本质就是一个塔防类的游戏,游戏目标为:守住大本营并且消灭敌方坦克,通常支持单双人模式,下面我们来看一下具体实现。

    实现

    首先,我们来实现游戏场景,场景的组成主要包括:石头墙、钢墙、冰、河流、树、地图,我们暂时做两个关卡,代码实现如下:

    # 石头墙 class Brick(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   self.brick = pygame.image.load('images/scene/brick.png')   self.rect = self.brick.get_rect()   self.being = False # 钢墙 class Iron(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   self.iron = pygame.image.load('images/scene/iron.png')   self.rect = self.iron.get_rect()   self.being = False # 冰 class Ice(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   self.ice = pygame.image.load('images/scene/ice.png')   self.rect = self.ice.get_rect()   self.being = False # 河流 class River(pygame.sprite.Sprite):  def __init__(self, kind=None):   pygame.sprite.Sprite.__init__(self)   if kind is None:    self.kind = random.randint(0, 1)   self.rivers = ['images/scene/river1.png', 'images/scene/river2.png']   self.river = pygame.image.load(self.rivers[self.kind])   self.rect = self.river.get_rect()   self.being = False # 树 class Tree(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   self.tree = pygame.image.load('images/scene/tree.png')   self.rect = self.tree.get_rect()   self.being = False # 地图 class Map():  def __init__(self, stage):   self.brickGroup = pygame.sprite.Group()   self.ironGroup  = pygame.sprite.Group()   self.iceGroup = pygame.sprite.Group()   self.riverGroup = pygame.sprite.Group()   self.treeGroup = pygame.sprite.Group()   if stage == 1:    self.stage1()   elif stage == 2:    self.stage2()  # 关卡一  def stage1(self):   for x in [2, 3, 6, 7, 18, 19, 22, 23]:    for y in [2, 3, 4, 5, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21, 22, 23]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [10, 11, 14, 15]:    for y in [2, 3, 4, 5, 6, 7, 8, 11, 12, 15, 16, 17, 18, 19, 20]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [4, 5, 6, 7, 18, 19, 20, 21]:    for y in [13, 14]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [12, 13]:    for y in [16, 17]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x, y in [(11, 23), (12, 23), (13, 23), (14, 23), (11, 24), (14, 24), (11, 25), (14, 25)]:    self.brick = Brick()    self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24    self.brick.being = True    self.brickGroup.add(self.brick)   for x, y in [(0, 14), (1, 14), (12, 6), (13, 6), (12, 7), (13, 7), (24, 14), (25, 14)]:    self.iron = Iron()    self.iron.rect.left, self.iron.rect.top = 3 + x * 24, 3 + y * 24    self.iron.being = True    self.ironGroup.add(self.iron)  # 关卡二  def stage2(self):   for x in [2, 3, 6, 7, 18, 19, 22, 23]:    for y in [2, 3, 4, 5, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21, 22, 23]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [10, 11, 14, 15]:    for y in [2, 3, 4, 5, 6, 7, 8, 11, 12, 15, 16, 17, 18, 19, 20]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [4, 5, 6, 7, 18, 19, 20, 21]:    for y in [13, 14]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x in [12, 13]:    for y in [16, 17]:     self.brick = Brick()     self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24     self.brick.being = True     self.brickGroup.add(self.brick)   for x, y in [(11, 23), (12, 23), (13, 23), (14, 23), (11, 24), (14, 24), (11, 25), (14, 25)]:    self.brick = Brick()    self.brick.rect.left, self.brick.rect.top = 3 + x * 24, 3 + y * 24    self.brick.being = True    self.brickGroup.add(self.brick)   for x, y in [(0, 14), (1, 14), (12, 6), (13, 6), (12, 7), (13, 7), (24, 14), (25, 14)]:    self.iron = Iron()    self.iron.rect.left, self.iron.rect.top = 3 + x * 24, 3 + y * 24    self.iron.being = True    self.ironGroup.add(self.iron)  def protect_home(self):   for x, y in [(11, 23), (12, 23), (13, 23), (14, 23), (11, 24), (14, 24), (11, 25), (14, 25)]:    self.iron = Iron()    self.iron.rect.left, self.iron.rect.top = 3 + x * 24, 3 + y * 24    self.iron.being = True    self.ironGroup.add(self.iron)

    我们接着看大本营的实现,大本营的实现相对比较简单,其本质就是一个标识物,代码实现如下:

    class Home(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   self.homes = ['images/home/home1.png', 'images/home/home2.png', 'images/home/home_destroyed.png']   self.home = pygame.image.load(self.homes[0])   self.rect = self.home.get_rect()   self.rect.left, self.rect.top = (3 + 12 * 24, 3 + 24 * 24)   self.alive = True  # 大本营置为摧毁状态  def set_dead(self):   self.home = pygame.image.load(self.homes[-1])   self.alive = False

    再接着看食物的实现,食物主要用来提升坦克能力,如:坦克升级、增加生命等,代码实现如下:

    # 食物类 class Food(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   # 消灭当前所有敌人   self.food_boom = 'images/food/food_boom.png'   # 当前所有敌人静止一段时间   self.food_clock = 'images/food/food_clock.png'   # 使得坦克子弹可碎钢板   self.food_gun = 'images/food/food_gun.png'   # 使得大本营的墙变为钢板   self.food_iron = 'images/food/food_gun.png'   # 坦克获得一段时间的保护罩   self.food_protect = 'images/food/food_protect.png'   # 坦克升级   self.food_star = 'images/food/food_star.png'   # 坦克生命 + 1   self.food_tank = 'images/food/food_tank.png'   # 所有食物   self.foods = [self.food_boom, self.food_clock, self.food_gun, self.food_iron, self.food_protect, self.food_star, self.food_tank]   self.kind = None   self.food = None   self.rect = None   # 是否存在   self.being = False   # 存在时间   self.time = 1000  # 生成食物  def generate(self):   self.kind = random.randint(0, 6)   self.food = pygame.image.load(self.foods[self.kind]).convert_alpha()   self.rect = self.food.get_rect()   self.rect.left, self.rect.top = random.randint(100, 500), random.randint(100, 500)   self.being = True

    再接着看坦克的实现,坦克包括我方坦克和敌方坦克,我方坦克由玩家自己控制移动、射击等操作,敌方坦克实现自动移动、射击等操作,代码实现如下:

    # 我方坦克类 class myTank(pygame.sprite.Sprite):  def __init__(self, player):   pygame.sprite.Sprite.__init__(self)   # 玩家编号(1/2)   self.player = player   # 不同玩家用不同的坦克(不同等级对应不同的图)   if player == 1:    self.tanks = ['images/myTank/tank_T1_0.png', 'images/myTank/tank_T1_1.png', 'images/myTank/tank_T1_2.png']   elif player == 2:    self.tanks = ['images/myTank/tank_T2_0.png', 'images/myTank/tank_T2_1.png', 'images/myTank/tank_T2_2.png']   else:    raise ValueError('myTank class -> player value error.')   # 坦克等级(初始0)   self.level = 0   # 载入(两个tank是为了轮子特效)   self.tank = pygame.image.load(self.tanks[self.level]).convert_alpha()   self.tank_0 = self.tank.subsurface((0, 0), (48, 48))   self.tank_1 = self.tank.subsurface((48, 0), (48, 48))   self.rect = self.tank_0.get_rect()   # 保护罩   self.protected_mask = pygame.image.load('images/others/protect.png').convert_alpha()   self.protected_mask1 = self.protected_mask.subsurface((0, 0), (48, 48))   self.protected_mask2 = self.protected_mask.subsurface((48, 0), (48, 48))   # 坦克方向   self.direction_x, self.direction_y = 0, -1   # 不同玩家的出生位置不同   if player == 1:    self.rect.left, self.rect.top = 3 + 24 * 8, 3 + 24 * 24   elif player == 2:    self.rect.left, self.rect.top = 3 + 24 * 16, 3 + 24 * 24   else:    raise ValueError('myTank class -> player value error.')   # 坦克速度   self.speed = 3   # 是否存活   self.being = True   # 有几条命   self.life = 3   # 是否处于保护状态   self.protected = False   # 子弹   self.bullet = Bullet()  # 射击  def shoot(self):   self.bullet.being = True   self.bullet.turn(self.direction_x, self.direction_y)   if self.direction_x == 0 and self.direction_y == -1:    self.bullet.rect.left = self.rect.left + 20    self.bullet.rect.bottom = self.rect.top - 1   elif self.direction_x == 0 and self.direction_y == 1:    self.bullet.rect.left = self.rect.left + 20    self.bullet.rect.top = self.rect.bottom + 1   elif self.direction_x == -1 and self.direction_y == 0:    self.bullet.rect.right = self.rect.left - 1    self.bullet.rect.top = self.rect.top + 20   elif self.direction_x == 1 and self.direction_y == 0:    self.bullet.rect.left = self.rect.right + 1    self.bullet.rect.top = self.rect.top + 20   else:    raise ValueError('myTank class -> direction value error.')   if self.level == 0:    self.bullet.speed = 8    self.bullet.stronger = False   elif self.level == 1:    self.bullet.speed = 12    self.bullet.stronger = False   elif self.level == 2:    self.bullet.speed = 12    self.bullet.stronger = True   elif self.level == 3:    self.bullet.speed = 16    self.bullet.stronger = True   else:    raise ValueError('myTank class -> level value error.')  # 等级提升  def up_level(self):   if self.level < 3:    self.level += 1   try:    self.tank = pygame.image.load(self.tanks[self.level]).convert_alpha()   except:    self.tank = pygame.image.load(self.tanks[-1]).convert_alpha()  # 等级降低  def down_level(self):   if self.level > 0:    self.level -= 1   self.tank = pygame.image.load(self.tanks[self.level]).convert_alpha()  # 向上  def move_up(self, tankGroup, brickGroup, ironGroup, myhome):   self.direction_x, self.direction_y = 0, -1   # 先移动后判断   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   self.tank_0 = self.tank.subsurface((0, 0), (48, 48))   self.tank_1 = self.tank.subsurface((48, 0), (48, 48))   # 是否可以移动   is_move = True   # 地图顶端   if self.rect.top < 3:    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞石头/钢墙   if pygame.sprite.spritecollide(self, brickGroup, False, None) or \    pygame.sprite.spritecollide(self, ironGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞其他坦克   if pygame.sprite.spritecollide(self, tankGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 大本营   if pygame.sprite.collide_rect(self, myhome):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   return is_move  # 向下  def move_down(self, tankGroup, brickGroup, ironGroup, myhome):   self.direction_x, self.direction_y = 0, 1   # 先移动后判断   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   self.tank_0 = self.tank.subsurface((0, 48), (48, 48))   self.tank_1 = self.tank.subsurface((48, 48), (48, 48))   # 是否可以移动   is_move = True   # 地图底端   if self.rect.bottom > 630 - 3:    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞石头/钢墙   if pygame.sprite.spritecollide(self, brickGroup, False, None) or \    pygame.sprite.spritecollide(self, ironGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞其他坦克   if pygame.sprite.spritecollide(self, tankGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 大本营   if pygame.sprite.collide_rect(self, myhome):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   return is_move  # 向左  def move_left(self, tankGroup, brickGroup, ironGroup, myhome):   self.direction_x, self.direction_y = -1, 0   # 先移动后判断   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   self.tank_0 = self.tank.subsurface((0, 96), (48, 48))   self.tank_1 = self.tank.subsurface((48, 96), (48, 48))   # 是否可以移动   is_move = True   # 地图左端   if self.rect.left < 3:    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞石头/钢墙   if pygame.sprite.spritecollide(self, brickGroup, False, None) or \    pygame.sprite.spritecollide(self, ironGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞其他坦克   if pygame.sprite.spritecollide(self, tankGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False     # 大本营   if pygame.sprite.collide_rect(self, myhome):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   return is_move  # 向右  def move_right(self, tankGroup, brickGroup, ironGroup, myhome):   self.direction_x, self.direction_y = 1, 0   # 先移动后判断   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   self.tank_0 = self.tank.subsurface((0, 144), (48, 48))   self.tank_1 = self.tank.subsurface((48, 144), (48, 48))   # 是否可以移动   is_move = True   # 地图右端   if self.rect.right > 630 - 3:    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞石头/钢墙   if pygame.sprite.spritecollide(self, brickGroup, False, None) or \    pygame.sprite.spritecollide(self, ironGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 撞其他坦克   if pygame.sprite.spritecollide(self, tankGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   # 大本营   if pygame.sprite.collide_rect(self, myhome):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    is_move = False   return is_move  # 死后重置  def reset(self):   self.level = 0   self.protected = False   self.tank = pygame.image.load(self.tanks[self.level]).convert_alpha()   self.tank_0 = self.tank.subsurface((0, 0), (48, 48))   self.tank_1 = self.tank.subsurface((48, 0), (48, 48))   self.rect = self.tank_0.get_rect()   self.direction_x, self.direction_y = 0, -1   if self.player == 1:    self.rect.left, self.rect.top = 3 + 24 * 8, 3 + 24 * 24   elif self.player == 2:    self.rect.left, self.rect.top = 3 + 24 * 16, 3 + 24 * 24   else:    raise ValueError('myTank class -> player value error.')   self.speed = 3 # 敌方坦克类 class enemyTank(pygame.sprite.Sprite):  def __init__(self, x=None, kind=None, is_red=None):   pygame.sprite.Sprite.__init__(self)   # 用于给刚生成的坦克播放出生特效   self.born = True   self.times = 90   # 坦克的种类编号   if kind is None:    self.kind = random.randint(0, 3)   else:    self.kind = kind   # 所有坦克   self.tanks1 = ['images/enemyTank/enemy_1_0.png', 'images/enemyTank/enemy_1_1.png', 'images/enemyTank/enemy_1_2.png', 'images/enemyTank/enemy_1_3.png']   self.tanks2 = ['images/enemyTank/enemy_2_0.png', 'images/enemyTank/enemy_2_1.png', 'images/enemyTank/enemy_2_2.png', 'images/enemyTank/enemy_2_3.png']   self.tanks3 = ['images/enemyTank/enemy_3_0.png', 'images/enemyTank/enemy_3_1.png', 'images/enemyTank/enemy_3_2.png', 'images/enemyTank/enemy_3_3.png']   self.tanks4 = ['images/enemyTank/enemy_4_0.png', 'images/enemyTank/enemy_4_1.png', 'images/enemyTank/enemy_4_2.png', 'images/enemyTank/enemy_4_3.png']   self.tanks = [self.tanks1, self.tanks2, self.tanks3, self.tanks4]   # 是否携带食物(红色的坦克携带食物)   if is_red is None:    self.is_red = random.choice((True, False, False, False, False))   else:    self.is_red = is_red   # 同一种类的坦克具有不同的颜色, 红色的坦克比同类坦克多一点血量   if self.is_red:    self.color = 3   else:    self.color = random.randint(0, 2)   # 血量   self.blood = self.color   # 载入(两个tank是为了轮子特效)   self.tank = pygame.image.load(self.tanks[self.kind][self.color]).convert_alpha()   self.tank_0 = self.tank.subsurface((0, 48), (48, 48))   self.tank_1 = self.tank.subsurface((48, 48), (48, 48))   self.rect = self.tank_0.get_rect()   # 坦克位置   if x is None:    self.x = random.randint(0, 2)   else:    self.x = x   self.rect.left, self.rect.top = 3 + self.x * 12 * 24, 3   # 坦克是否可以行动   self.can_move = True   # 坦克速度   self.speed = max(3 - self.kind, 1)   # 方向   self.direction_x, self.direction_y = 0, 1   # 是否存活   self.being = True   # 子弹   self.bullet = Bullet()  # 射击  def shoot(self):   self.bullet.being = True   self.bullet.turn(self.direction_x, self.direction_y)   if self.direction_x == 0 and self.direction_y == -1:    self.bullet.rect.left = self.rect.left + 20    self.bullet.rect.bottom = self.rect.top - 1   elif self.direction_x == 0 and self.direction_y == 1:    self.bullet.rect.left = self.rect.left + 20    self.bullet.rect.top = self.rect.bottom + 1   elif self.direction_x == -1 and self.direction_y == 0:    self.bullet.rect.right = self.rect.left - 1    self.bullet.rect.top = self.rect.top + 20   elif self.direction_x == 1 and self.direction_y == 0:    self.bullet.rect.left = self.rect.right + 1    self.bullet.rect.top = self.rect.top + 20   else:    raise ValueError('enemyTank class -> direction value error.')  # 随机移动  def move(self, tankGroup, brickGroup, ironGroup, myhome):   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   is_move = True   if self.direction_x == 0 and self.direction_y == -1:    self.tank_0 = self.tank.subsurface((0, 0), (48, 48))    self.tank_1 = self.tank.subsurface((48, 0), (48, 48))    if self.rect.top < 3:     self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)     self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))     is_move = False   elif self.direction_x == 0 and self.direction_y == 1:    self.tank_0 = self.tank.subsurface((0, 48), (48, 48))    self.tank_1 = self.tank.subsurface((48, 48), (48, 48))    if self.rect.bottom > 630 - 3:     self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)     self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))     is_move = False   elif self.direction_x == -1 and self.direction_y == 0:    self.tank_0 = self.tank.subsurface((0, 96), (48, 48))    self.tank_1 = self.tank.subsurface((48, 96), (48, 48))    if self.rect.left < 3:     self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)     self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))     is_move = False   elif self.direction_x == 1 and self.direction_y == 0:    self.tank_0 = self.tank.subsurface((0, 144), (48, 48))    self.tank_1 = self.tank.subsurface((48, 144), (48, 48))    if self.rect.right > 630 - 3:     self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)     self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))     is_move = False   else:    raise ValueError('enemyTank class -> direction value error.')   if pygame.sprite.spritecollide(self, brickGroup, False, None) \    or pygame.sprite.spritecollide(self, ironGroup, False, None) \    or pygame.sprite.spritecollide(self, tankGroup, False, None):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))    is_move = False   if pygame.sprite.collide_rect(self, myhome):    self.rect = self.rect.move(self.speed*-self.direction_x, self.speed*-self.direction_y)    self.direction_x, self.direction_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))    is_move = False   return is_move  # 重新载入坦克  def reload(self):   self.tank = pygame.image.load(self.tanks[self.kind][self.color]).convert_alpha()   self.tank_0 = self.tank.subsurface((0, 48), (48, 48))   self.tank_1 = self.tank.subsurface((48, 48), (48, 48))

    再接着看子弹的实现,子弹的主要属性包括:方向、速度、是否存活、是否为加强版等,代码实现如下:

    # 子弹类 class Bullet(pygame.sprite.Sprite):  def __init__(self):   pygame.sprite.Sprite.__init__(self)   # 子弹四个方向(上下左右)   self.bullets = ['images/bullet/bullet_up.png', 'images/bullet/bullet_down.png', 'images/bullet/bullet_left.png', 'images/bullet/bullet_right.png']   # 子弹方向(默认向上)   self.direction_x, self.direction_y = 0, -1   self.bullet = pygame.image.load(self.bullets[0])   self.rect = self.bullet.get_rect()   # 在坦克类中再赋实际值   self.rect.left, self.rect.right = 0, 0   # 速度   self.speed = 6   # 是否存活   self.being = False   # 是否为加强版子弹(可碎钢板)   self.stronger = False  # 改变子弹方向  def turn(self, direction_x, direction_y):   self.direction_x, self.direction_y = direction_x, direction_y   if self.direction_x == 0 and self.direction_y == -1:    self.bullet = pygame.image.load(self.bullets[0])   elif self.direction_x == 0 and self.direction_y == 1:    self.bullet = pygame.image.load(self.bullets[1])   elif self.direction_x == -1 and self.direction_y == 0:    self.bullet = pygame.image.load(self.bullets[2])   elif self.direction_x == 1 and self.direction_y == 0:    self.bullet = pygame.image.load(self.bullets[3])   else:    raise ValueError('Bullet class -> direction value error.')  # 移动  def move(self):   self.rect = self.rect.move(self.speed*self.direction_x, self.speed*self.direction_y)   # 到地图边缘后消失   if (self.rect.top < 3) or (self.rect.bottom > 630 - 3) or (self.rect.left < 3) or (self.rect.right > 630 - 3):    self.being = False

    最后,我们看一下程序的主要初始化代码,如下所示:

    # 初始化 pygame.init() pygame.mixer.init() screen = pygame.display.set_mode((630, 630)) pygame.display.set_caption("TANK") # 加载图片 bg_img = pygame.image.load("images/others/background.png") # 加载音效 add_sound = pygame.mixer.Sound("audios/add.wav") add_sound.set_volume(1) bang_sound = pygame.mixer.Sound("audios/bang.wav") bang_sound.set_volume(1) blast_sound = pygame.mixer.Sound("audios/blast.wav") blast_sound.set_volume(1) fire_sound = pygame.mixer.Sound("audios/fire.wav") fire_sound.set_volume(1) Gunfire_sound = pygame.mixer.Sound("audios/Gunfire.wav") Gunfire_sound.set_volume(1) hit_sound = pygame.mixer.Sound("audios/hit.wav") hit_sound.set_volume(1) start_sound = pygame.mixer.Sound("audios/start.wav") start_sound.set_volume(1) # 开始界面 num_player = show_start_interface(screen, 630, 630) # 播放游戏开始的音乐 start_sound.play() # 关卡 stage = 0 num_stage = 2 # 游戏是否结束 is_gameover = False # 时钟 clock = pygame.time.Clock()

    看一下实现效果:

    再说一下玩家一、二的操作键,玩家一、二移动键分别为:WASD、←→↑↓,玩家一、二射击键分别为:J、0。

    总结

    本文我们使用 Python 实现了坦克大战的基本功能,还有待完善,有兴趣的话,可以对游戏做进一步的完善和扩展。

    PS:公号内回复「Python」即可进入Python 新手学习交流群,一起100天计划!

    老规矩,兄弟们还记得么,右下角的 “在看” 点一下,如果感觉文章内容不错的话,记得分享朋友圈让更多的人知道!

    【代码获取方式】

    识别文末二维码,回复:200628

    Processed: 0.011, SQL: 9