前言
坦克大战是一款策略类的平面射击游戏,于 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 实现了坦克大战的基本功能,还有待完善,有兴趣的话,可以对游戏做进一步的完善和扩展。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]