前言
坦克大战是一款策略类的平面射击游戏,于 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 实现了坦克大战的基本功能,还有待完善,有兴趣的话,可以对游戏做进一步的完善和扩展。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]