【带你找回童年的快乐,Python实现坦克大战】

news2024/11/17 15:31:18

文章目录

    • 前言:
    • 第一步:安装Pygame库
    • 第二步:实现思路:
      • 场景实现:
      • 石头墙:
      • 钢墙:
      • 地面类(Grass)
      • 地图:
    • 第三步:坦克类的详细实现:
      • 坦克类(Tank)
      • 子弹类(Bullet)
      • 爆炸类(Explosion)
    • 坦克类详细代码以及实现:
    • 完整代码压缩包:
    • 最终成功展示:

在这里插入图片描述

前言:

坦克大战90版本是一款2D射击游戏,玩家扮演一辆坦克,通过操纵坦克进行战斗。游戏场景通常是由迷宫状的地图构成,在地图中有各种不同类型的障碍物,如墙壁、水域、草地等,这些障碍物会对玩家的行动和战斗产生影响。

玩家的目标是摧毁敌方坦克并保护自己的基地。游戏中会有敌方坦克和敌方基地,玩家需要躲避敌方坦克的攻击并利用自己的技巧和策略来摧毁敌方坦克和基地。同时,玩家还可以尝试收集道具,如增强装甲、提高射速等,以增加自己的战斗能力。

这款游戏具有简单直观的操作方式,通过方向键控制坦克移动,空格键发射子弹。游戏节奏紧凑,战斗刺激,让玩家体验到了紧张的战争氛围。此外,游戏还支持多人模式,玩家可以与朋友一起组队或对战,增加了游戏的趣味性和竞争性。

坦克大战90版本不仅在当时取得了巨大成功,在后来的几十年里也不断被翻新和改进,衍生出了更多精彩的版本和新的玩法。无论是当年的经典版还是现代的重制版,坦克大战都是一款具有吸引力和娱乐性的经典游戏,让玩家流连忘返。

第一步:安装Pygame库

确保你已经安装了Python:在安装Pygame之前,确保你已经安装了Python。你可以从官方网站下载Python的最新版本并进行安装。Pygame兼容Python 2.x和Python 3.x版本。

打开终端:在Windows操作系统中,你可以按下Win+R键,在运行窗口中输入"cmd"并按下回车键打开命令提示符。在macOS和Linux系统中,你可以打开终端应用程序。

使用pip安装Pygame:在终端中输入以下命令来使用pip包管理器安装Pygame库:

pip install pygame

如果你使用的是Python 3,则使用以下命令:

pip3 install pygame

等待安装完成:一旦执行了安装命令,pip将会自动下载和安装Pygame库及其依赖项。这个过程可能需要一些时间,取决于你的网络速度和系统环境。

验证安装:安装完成后,你可以通过在终端中输入以下命令来验证Pygame是否成功安装:

python -m pygame.examples.aliens

或者

python3 -m pygame.examples.aliens

如果一切顺利,你将会看到一个外星人射击游戏的窗口弹出。

在这里插入图片描述

第二步:实现思路:

场景实现:

游戏场景,场景的组成主要包括:石头墙、钢墙、地面、坦克、子弹地图。

石头墙:

石头墙是一种阻挡玩家和敌人行进路径的障碍物。可以使用矩形或图片来表示石头墙,并将其绘制在游戏界面的指定位置上。

# 石头墙
class Brick(pygame.sprite.Sprite):
    def __init__(self, position):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/scene/brick.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.topleft = position
        self.is_destroyed = False

    def destroy(self):
        self.is_destroyed = True

    def draw(self, surface):
        if not self.is_destroyed:
            surface.blit(self.image, self.rect)

position 参数:用于指定石头墙在游戏界面上的位置。
is_destroyed 属性:用于标记石头墙是否被摧毁。
destroy() 方法:用于将石头墙标记为被摧毁。
draw() 方法:用于将石头墙绘制在游戏界面上。

钢墙:

钢墙是一种更坚固的墙体,通常比石头墙更难被破坏。与石头墙类似,可以使用矩形或图片来表示钢墙,并将其绘制在游戏界面上。

# 钢墙
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

地面类(Grass)

草地是游戏中的一种地形,玩家可以在草地上自由行动。以下是一个简单的草地类定义:

import pygame

class Grass(pygame.sprite.Sprite):
    def __init__(self, x, y, width=32, height=32):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/grass.gif').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = x, y
        self.width, self.height = width, height
    
    def draw(self, surface):
        surface.blit(self.image, self.rect)

在这个示例中,我们定义了一个 Grass 类,用于表示游戏中的草地。x 和 y 参数用于指定草地的位置,width 和 height 参数用于指定草地的宽度和高度。

draw() 方法用于将草地绘制在游戏界面上。

地图:

地图:地图是一个整体的场景,它包含了所有的游戏元素,并定义了玩家和敌人的移动范围。地图可以通过一个矩阵或类似的数据结构来表示,其中不同的值代表不同的场景元素(如石头墙、钢墙、地板等)。根据地图的定义,可以将相应的场景元素绘制在游戏界面上。

# 地图
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)

第三步:坦克类的详细实现:

坦克类(Tank)

坦克是游戏中最主要的角色之一,玩家可以操控它来击败敌人。以下是一个简单的坦克类定义:

import pygame

class Tank(pygame.sprite.Sprite):
    def __init__(self, x, y, speed=5):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/tank/player1.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = x, y
        self.speed = speed
        self.direction = 'up'
        self.is_alive = True
    
    def move(self):
        if self.direction == 'up':
            self.rect.top -= self.speed
        elif self.direction == 'down':
            self.rect.top += self.speed
        elif self.direction == 'left':
            self.rect.left -= self.speed
        elif self.direction == 'right':
            self.rect.left += self.speed
    
    def draw(self, surface):
        surface.blit(self.image, self.rect)

在这个示例中,我们定义了一个 Tank 类,用于表示游戏中的坦克。x 和 y 参数用于指定坦克的初始位置,speed 参数用于指定坦克的移动速度。direction 属性表示坦克当前的朝向,is_alive 属性表示坦克是否存活。

move() 方法用于根据坦克的当前朝向,改变坦克的位置。draw() 方法用于将坦克绘制在游戏界面上。

子弹类(Bullet)

子弹是坦克和敌人所使用的武器。
子弹的主要属性包括:方向、速度、是否存活、是否为加强版等,代码实现如下:

# 子弹类
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

爆炸类(Explosion)

爆炸是游戏中的一种特效,当坦克被击中或者墙壁被摧毁时会产生爆炸效果。以下是一个简单的爆炸类定义:

import pygame

class Explosion(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/explosion.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.centerx, self.rect.centery = x, y
        self.frame = 0
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 50
    
    def update(self):
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.frame += 1
            if self.frame == 6:
                self.kill()
            else:
                self.last_update = now
    
    def draw(self, surface):
        surface.blit(self.image, self.rect, pygame.Rect(self.frame * 64, 0, 64, 64))

在这个示例中,我们定义了一个 Explosion 类,用于表示游戏中的爆炸效果。x 和 y 参数用于指定爆炸的位置。

update() 方法用于更新爆炸动画的帧数。draw() 方法用于将当前帧的爆炸效果绘制在游戏界面上。

坦克类详细代码以及实现:

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

# 我方坦克类
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))

完整代码压缩包:

由于代码内容过多就不一一展示放在文章当中了,如需完整项目请私信…

最终成功展示:

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1125235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国际刑事法院系统遭网络间谍攻击

导语&#xff1a;国际刑事法院&#xff08;ICC&#xff09;近日披露&#xff0c;其系统遭受了一次网络间谍攻击。这次攻击被认为是有目的的&#xff0c;旨在进行间谍活动。作为一个国际法庭&#xff0c;ICC的总部设在荷兰海牙&#xff0c;其职责是调查并追究犯下国际社会关注的…

微机原理与接口技术-第七章输入输出接口

文章目录 I/O接口概述I/O接口的典型结构基本功能 I/O端口的编址独立编址统一编址 输入输出指令I/O寻址方式I/O数据传输量I/O保护 16位DOS应用程序DOS平台的源程序框架DOS功能调用 无条件传送和查询传送无条件传送三态缓冲器锁存器接口电路 查询传送查询输入端口查询输出端口 中…

【Linux系统编程】命令模式2

目录 一&#xff0c;Linux下的初阶认识 1&#xff0c;管道 2&#xff0c;时间戳 二&#xff0c;Liunx系统命令操作 1&#xff0c;date时间指令 2&#xff0c;cal日历指令 3&#xff0c;which和find查找指令 3-1&#xff0c;which指令&#xff1a; 3-2&#xff0c;find…

c语言一维数组和二维指针

c语言一维数组和二维指针&#xff1a;测试目的&#xff0c;了解二维指针赋值。 #include <stdio.h> //c语言一维数组和二维指针 int main(int argc,char *argv[]) { int MyArray[2]; int *p1; int **p2; //int **p2&p1;//在声明变量时&#xff0c;可以这么赋值 …

如何保养维护实验室超声波清洗机

实验室是用于各个行业产品的研发以及检验的场所&#xff0c;所以对其中所使用的各种物品都有着极高的要求&#xff0c;因此只有品类齐全的实验室超声波清洗机能够满足实验室对于清洁以及其他方面的一些需求&#xff0c;但是要想实验室超声波清洗机设备的性能能够始终如一&#…

后 Cookie 时代如何实现精准的用户运营与管理?

Cookie 时代的营销&#xff1a;用隐私换取个性化服务方式帮助他们找到回家的路。而在数字世界中&#xff0c;网站运营者可以通过这些“碎饼干屑 &#xff08;Cookie&#xff09;”追踪用户行为。 用户隐私和个性化服务之间的平衡一直是一个备受争议的话题。随着技术的发展&…

二叉排序树(BST)

二叉排序树 基本介绍 二叉排序树创建和遍历 class Node:"""创建 Node 节点"""value: int 0left Noneright Nonedef __init__(self, value: int):self.value valuedef add(self, node):"""添加节点node 表示要添加的节点&quo…

Your password has expired. To log in you must change it using a client that

早上打开本地mysql链接报错了&#xff0c;提示密码过期 PS:是密码过期&#xff0c;不是密码错误 开始 先看下mysql安装位置 windowsD 打开运行窗口 输入 services.msc 打开服务界面 找到mysql 查看安装路径 windowsD 打开运行窗口 cmd 进入mysql bin 目录 1、cd 你的目…

React 中 keys 的作用是什么?

目录 前言&#xff1a;React 中的 Keys 的重要性 为什么 Keys 重要&#xff1f; 详解&#xff1a;key 属性的基本概念 用法&#xff1a;key 属性的示例 解析&#xff1a;key 属性的优势和局限性 优势&#xff1a; 局限性&#xff1a; key 属性的最佳实践 稳定的唯一标…

ZYNQ linux调试LCD7789

一,硬件管脚 1,参数解释和实物 LVGL是一个开源的图形库,主要用于MCU上屏幕UI的部署,功能完善,封装合理,可裁切性强,也可以实现Linux上fbx的部署。LVGL官网LVGL - Light and Versatile Embedded Graphics Library 每根线的作用

[Linux 基础] make、Makefile自动化构建代码工具

文章目录 1、make与Makefile是什么2、为什么要有make与Makefile3、怎么实现一个Makefile文件3.1 如何编写Makefile文件3.1.1 依赖关系3.1.2 依赖方法 3.2 如何清理项目3.2.1 如何编写3.2.2 clean详解 3.3 make的使用3.4 原理3.4.1 查看文件修改时间 1、make与Makefile是什么 m…

0基础学习VR全景平台篇第110篇:源图像导入和镜头预设 - PTGui Pro教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 本节教程&#xff0c;我们讲述拼接软件 PTGui Pro 操作的第一步&#xff1a;导入源图像和预设镜头&画幅参数。 我们此次课堂有两个重点&#xff1a; 第一点是 培养摄影后期…

拼团小程序制作技巧大揭秘:零基础也能轻松掌握

随着拼团模式的日益流行&#xff0c;越来越多的商家和消费者开始关注拼团小程序的制作。对于没有技术背景的普通人来说&#xff0c;制作一个拼团小程序似乎是一项艰巨的任务。但实际上&#xff0c;选择一个简单易用的第三方平台或工具&#xff0c;可以轻松完成拼团小程序的制作…

024-第三代软件开发-TabView

第三代软件开发-TabView 文章目录 第三代软件开发-TabView项目介绍TabView官方示例 项目实际使用 关键字&#xff1a; Qt、 Qml、 TabView、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Langu…

开发趋势 Java Lambda 表达式 第一篇

开发趋势 Java Lambda 表达式 一&#xff0c;介绍 Java Lambda 表达式是自 Java 8以后引入的一种新的编程特性&#xff0c;它使得 Java 也能使用函数式编程的部分特性。Lambda 表达式提供了一种清晰且简洁的方式来代表一个方法接口&#xff08;single method interface&#x…

【Unity3D日常开发】Unity3D的Color Space(颜色空间)【全解析】

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 Edit→Player Settings→Other Settings→Rendering→Color Sp…

app拉新渠道整合 一手地推、网推拉新平台整理

1.聚量推客 聚量推客自己本身是服务商&#xff0c;自己直营的平台&#xff0c;相对来说数据更好&#xff0c;我们也拿到了平台首码&#xff1a;000000 填这个就行&#xff0c;属于官方渠道 2.蓝猫推客 蓝猫推客我认为是比较又潜力的平台&#xff0c;经过几天测试数据和结算都…

【23级红细胞招新模拟训练(部分题解 不包含最后三题】

前言 提前说明 &#xff1a; 本人是蒟蒻 题解基本没考虑过优化 只求通过 写这篇题解仅仅是分享一下我的做法 使用的语言&#xff1a;cpp 6-1 题目 请编写函数&#xff0c;对三个整数按升序排序。 函数原型 void IntSortAsc3(int *x, int *y, int *z); 说明&#xff1a;参数 …

【鸿蒙软件开发】文本输入(TextInput/TextArea)

文章目录 前言一、输入框1.1 创建输入框单行输入框多行输入框单行和多行输入框的区别 1.2 设置输入框的类型有哪些类型基本输入模式&#xff08;默认类型&#xff09;密码输入模式 1.3 自定义样式设置无输入时的提示文本设置输入框当前的文本内容。添加backgroundColor改变输入…

基于减法平均优化的BP神经网络(分类应用) - 附代码

基于减法平均优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于减法平均优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.减法平均优化BP神经网络3.1 BP神经网络参数设置3.2 减法平均算法应用 4.测试结果…