【Pygame小游戏(5)——敌方坦克_用于在游戏中生成并控制敌方坦克的行为】

 1、源码来源:

wangxingyao/TankWar: 小游戏坦克大战(python + pygame) (github.com)icon-default.png?t=N7T8https://github.com/wangxingyao/TankWar?tab=readme-ov-file

下面我将详细解释您提供的 EnemyTank 类代码。该类使用 Pygame 模块创建一个敌方坦克对象,涵盖了初始化、移动、射击以及与其他游戏对象(如砖块、铁块、玩家坦克)的碰撞检测等功能。


2、这个模块主要实现了一个敌方坦克类 (EnemyTank),用于在游戏中生成并控制敌方坦克的行为。模块的主要作用包括以下几点:

  1. 敌方坦克的初始化

    • 根据不同的种类 (kind),加载相应的坦克图像资源。
    • 随机选择坦克的种类、颜色(是否为红色)以及初始位置。
    • 设置坦克的初始速度、生命值等属性。
  2. 敌方坦克的移动

    • 根据当前的方向和速度更新坦克的位置。
    • 检测坦克是否碰撞到屏幕边界或其他物体(如砖块、铁块、其他坦克),并随机改变移动方向。
  3. 敌方坦克的射击

    • 控制坦克的射击行为,根据当前的方向发射子弹。
    • 子弹的生成位置和方向与坦克的当前状态相关联。
  4. 碰撞检测

    • 检测坦克与游戏中其他元素(如砖块、铁块、其他坦克)的碰撞,并根据碰撞情况调整坦克的移动方向。

总体来说,这个模块为游戏中的敌方坦克提供了行为逻辑,包括初始化、移动、射击、碰撞检测等,确保敌方坦克在游戏中能够动态地表现出不同的行为。


3、引入模块与自定义类——EnemyTank:

import pygame
import random
import bulletClass

class EnemyTank(pygame.sprite.Sprite):
  • import pygame:引入 Pygame 模块,用于开发游戏。

  • import random:引入 Python 的 random 模块,用于生成随机数,决定坦克的类型、颜色和移动方向等。

  • import bulletClass:引入自定义的 bulletClass 模块,假设其中定义了 Bullet 类,用于处理子弹的行为。

  • class EnemyTank(pygame.sprite.Sprite)::定义 EnemyTank 类,继承自 pygame.sprite.Sprite,使其具备精灵的基本属性和方法,便于在游戏中进行管理和渲染。

4. 构造函数 __init__

def __init__(self, x=None, kind=None, isred=None):
    pygame.sprite.Sprite.__init__(self)
    
    # 初始化闪烁效果相关属性
    self.flash = False
    self.times = 90
  • def __init__(self, x=None, kind=None, isred=None)::构造函数,接受三个可选参数:

    • x:坦克的初始横向位置索引。
    • kind:坦克的类型(1、2、3、4)。
    • isred:布尔值,决定坦克是否为红色。
  • pygame.sprite.Sprite.__init__(self):调用父类 pygame.sprite.Sprite 的构造函数,初始化精灵的基本属性。

  • self.flash = False:用于控制坦克的闪烁效果,初始值为 False

  • self.times = 90:计时器,用于控制闪烁效果的持续时间。

4.1 确定坦克类型

# 确定坦克类型
self.kind = kind
if not kind:
    self.kind = random.choice([1, 2, 3, 4])
  • self.kind = kind:将传入的 kind 参数赋值给实例变量 self.kind
  • if not kind::如果未指定 kind,则随机选择一个类型(1、2、3、4)赋值给 self.kind

4.2 加载坦克图像

# 根据类型加载不同的坦克图像
if self.kind == 1:
    self.enemy_x_0 = pygame.image.load(r"..\image\enemy_1_0.png").convert_alpha()
    self.enemy_x_3 = pygame.image.load(r"..\image\enemy_1_3.png").convert_alpha()
if self.kind == 2:
    self.enemy_x_0 = pygame.image.load(r"..\image\enemy_2_0.png").convert_alpha()
    self.enemy_x_3 = pygame.image.load(r"..\image\enemy_2_3.png").convert_alpha()
if self.kind == 3:
    self.enemy_x_0 = pygame.image.load(r"..\image\enemy_3_1.png").convert_alpha()
    self.enemy_x_3 = pygame.image.load(r"..\image\enemy_3_0.png").convert_alpha()
if self.kind == 4:
    self.enemy_x_0 = pygame.image.load(r"..\image\enemy_4_0.png").convert_alpha()
    self.enemy_x_3 = pygame.image.load(r"..\image\enemy_4_3.png").convert_alpha()
self.enemy_3_0 = pygame.image.load(r"..\image\enemy_3_0.png").convert_alpha()
self.enemy_3_2 = pygame.image.load(r"..\image\enemy_3_2.png").convert_alpha()
  • 根据 self.kind 的值,加载不同类型坦克的图像:

    • 类型1:加载 enemy_1_0.pngenemy_1_3.png
    • 类型2:加载 enemy_2_0.pngenemy_2_3.png
    • 类型3:加载 enemy_3_1.pngenemy_3_0.png
    • 类型4:加载 enemy_4_0.pngenemy_4_3.png
  • self.enemy_3_0self.enemy_3_2:无论类型如何,额外加载 enemy_3_0.pngenemy_3_2.png,可能用于动画或其他状态。

  • convert_alpha():优化图像以支持透明度,提高渲染效率。

4.3 确定坦克颜色

# 确定坦克颜色(红色或默认颜色)
self.isred = isred
if isred is None:  # 已修改为:if isred is None
    self.isred = random.choice((True, False, False, False, False))
if self.isred:
    self.tank = self.enemy_x_3
else:
    self.tank = self.enemy_x_0
  • self.isred = isred:将传入的 isred 参数赋值给实例变量 self.isred

  • if not None::这里有一个逻辑错误,not None 始终为 True,因此无论 isred 是否传入,都会随机选择颜色。

    • 已修正:应为 if isred is None:,以判断 isred 是否未传入。
  • self.isred = random.choice((True, False, False, False, False)):在修正后的逻辑下,若 isred 未指定,则有 20% 的概率选择 True(红色),80% 选择 False(默认颜色)。

  • if self.isred::如果 isredTrue,则使用红色坦克图像 self.enemy_x_3,否则使用默认图像 self.enemy_x_0

4.4 设置坦克初始位置

# 设置坦克初始横向位置
self.x = x
if not self.x:
    self.x = random.choice([1, 2, 3])
self.x -= 1

# 设置坦克的图像区域和位置
self.tank_R0 = self.tank.subsurface((0, 48), (48, 48))
self.tank_R1 = self.tank.subsurface((48, 48), (48, 48))
self.rect = self.tank_R0.get_rect()
self.rect.left, self.rect.top = 3 + self.x * 12 * 24, 3 + 0 * 24
  • self.x = x:将传入的 x 参数赋值给实例变量 self.x

  • if not self.x::如果 x 未指定,则随机选择 1、2、3 中的一个作为初始横向位置索引。

  • self.x -= 1:将 x 减 1,可能用于计算在游戏区域中的实际位置。

  • self.tank.subsurface((0, 48), (48, 48))self.tank.subsurface((48, 48), (48, 48))

    • 使用 subsurface 方法从坦克图像中截取特定区域,可能用于不同的动画帧或状态。
  • self.rect = self.tank_R0.get_rect():获取 tank_R0 图像的矩形区域,用于定位和碰撞检测。

  • self.rect.left, self.rect.top = 3 + self.x * 12 * 24, 3 + 0 * 24

    • 设置坦克的初始位置:
      • 横向位置3 + self.x * 12 * 24,根据 self.x 计算具体的横坐标。
      • 纵向位置3 + 0 * 24,固定在纵向起始位置(可能为顶部)。

4.5 初始化坦克属性

# 初始化坦克的速度、方向、生命值、子弹状态等
self.speed = 1
self.dir_x, self.dir_y = 0, 1
self.life = 1
self.bulletNotCooling = True
self.bullet = bulletClass.Bullet()
# 是否需要改变方向
self.dirChange = False

# 根据坦克类型调整速度和生命值
if self.kind == 2:
    self.speed = 3
if self.kind == 3:
    self.life = 3
  • self.speed = 1:设置坦克的移动速度,默认值为 1。

  • self.dir_x, self.dir_y = 0, 1:设置坦克的初始移动方向,(0,1) 表示向下移动。

  • self.life = 1:设置坦克的生命值,默认值为 1。

  • self.bulletNotCooling = True:子弹冷却状态标志,True 表示可以立即发射子弹。

  • self.bullet = bulletClass.Bullet():创建一个 Bullet 对象,用于管理坦克发射的子弹。

  • self.dirChange = False:是否需要改变方向的标志,初始值为 False

  • 根据 self.kind 调整属性

    • if self.kind == 2::如果坦克类型为 2,设置速度为 3。
    • if self.kind == 3::如果坦克类型为 3,设置生命值为 3。

5. 射击方法 shoot

def shoot(self):
    # 设置子弹为活动状态
    self.bullet.life = True
    # 根据坦克当前方向更换子弹图像
    self.bullet.changeImage(self.dir_x, self.dir_y)
    
    # 根据坦克方向设置子弹的初始位置
    if self.dir_x == 0 and self.dir_y == -1:
        self.bullet.rect.left = self.rect.left + 20
        self.bullet.rect.bottom = self.rect.top + 1
    elif self.dir_x == 0 and self.dir_y == 1:
        self.bullet.rect.left = self.rect.left + 20
        self.bullet.rect.top = self.rect.bottom - 1
    elif self.dir_x == -1 and self.dir_y == 0:
        self.bullet.rect.right = self.rect.left - 1
        self.bullet.rect.top = self.rect.top + 20
    elif self.dir_x == 1 and self.dir_y == 0:
        self.bullet.rect.left = self.rect.right + 1
        self.bullet.rect.top = self.rect.top + 20
  • self.bullet.life = True:将子弹的生命状态设为 True,表示子弹处于活动状态,可以移动和碰撞。

  • self.bullet.changeImage(self.dir_x, self.dir_y):根据坦克当前的移动方向,切换子弹的图像,使子弹方向与坦克一致。

  • 根据坦克的方向设置子弹的初始位置

    • 向上射击 (0, -1)
      • self.bullet.rect.left = self.rect.left + 20:子弹的左边缘与坦克左边缘偏移 20 像素对齐。
      • self.bullet.rect.bottom = self.rect.top + 1:子弹的底部与坦克的顶部对齐,并向上偏移 1 像素,防止重叠。
    • 向下射击 (0, 1)
      • self.bullet.rect.left = self.rect.left + 20:对子弹进行横向对齐。
      • self.bullet.rect.top = self.rect.bottom - 1:子弹的顶部与坦克的底部对齐,并向下偏移 1 像素。
    • 向左射击 (-1, 0)
      • self.bullet.rect.right = self.rect.left - 1:子弹的右边缘与坦克的左边缘对齐,并向左偏移 1 像素。
      • self.bullet.rect.top = self.rect.top + 20:子弹的顶部与坦克的顶部偏移 20 像素对齐。
    • 向右射击 (1, 0)
      • self.bullet.rect.left = self.rect.right + 1:子弹的左边缘与坦克的右边缘对齐,并向右偏移 1 像素。
      • self.bullet.rect.top = self.rect.top + 20:子弹的顶部与坦克的顶部偏移 20 像素对齐。

6. 移动方法 move

def move(self, tankGroup, brickGroup, ironGroup):
    # 根据当前方向和速度移动坦克
    self.rect = self.rect.move(self.speed * self.dir_x, self.speed * self.dir_y)
    
    # 根据坦克的方向更新图像区域
    if self.dir_x == 0 and self.dir_y == -1:
        self.tank_R0 = self.tank.subsurface((0, 0), (48, 48))
        self.tank_R1 = self.tank.subsurface((48, 0), (48, 48))
    elif self.dir_x == 0 and self.dir_y == 1:
        self.tank_R0 = self.tank.subsurface((0, 48), (48, 48))
        self.tank_R1 = self.tank.subsurface((48, 48), (48, 48))
    elif self.dir_x == -1 and self.dir_y == 0:
        self.tank_R0 = self.tank.subsurface((0, 96), (48, 48))
        self.tank_R1 = self.tank.subsurface((48, 96), (48, 48))
    elif self.dir_x == 1 and self.dir_y == 0:
        self.tank_R0 = self.tank.subsurface((0, 144), (48, 48))
        self.tank_R1 = self.tank.subsurface((48, 144), (48, 48))
    
    # 检查坦克是否超出边界,如果超出则调整位置并随机改变方向
    if self.rect.top < 3:
        self.rect = self.rect.move(self.speed * 0, self.speed * 1)
        self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))
    elif self.rect.bottom > 630 - 3:
        self.rect = self.rect.move(self.speed * 0, self.speed * -1)
        self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))
    elif self.rect.left < 3:
        self.rect = self.rect.move(self.speed * 1, self.speed * 0)
        self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))
    elif self.rect.right > 630 - 3:
        self.rect = self.rect.move(self.speed * -1, self.speed * 0)
        self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))
    
    # 检查与其他精灵组(砖块、铁块、玩家坦克)的碰撞
    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.dir_x, self.speed * -self.dir_y)
        # 随机改变坦克的移动方向
        self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))

6.1 移动坦克

  • self.rect = self.rect.move(self.speed * self.dir_x, self.speed * self.dir_y)
    • 根据当前的方向 (self.dir_x, self.dir_y) 和速度 (self.speed),更新坦克的位置。

6.2 更新坦克图像区域

  • 根据当前方向,使用 subsurface 方法从坦克图像中截取对应的区域,用于渲染不同方向的坦克图像。
    • 向上移动 (0, -1)
      • self.tank_R0 = self.tank.subsurface((0, 0), (48, 48))
      • self.tank_R1 = self.tank.subsurface((48, 0), (48, 48))
    • 向下移动 (0, 1)
      • self.tank_R0 = self.tank.subsurface((0, 48), (48, 48))
      • self.tank_R1 = self.tank.subsurface((48, 48), (48, 48))
    • 向左移动 (-1, 0)
      • self.tank_R0 = self.tank.subsurface((0, 96), (48, 48))
      • self.tank_R1 = self.tank.subsurface((48, 96), (48, 48))
    • 向右移动 (1, 0)
      • self.tank_R0 = self.tank.subsurface((0, 144), (48, 48))
      • self.tank_R1 = self.tank.subsurface((48, 144), (48, 48))

6.3 检查边界条件并调整方向

  • 检查坦克是否超出游戏区域的边界,如果超出则调整位置并随机改变移动方向:
    • 顶部边界
      • if self.rect.top < 3:
        • 将坦克向下移动 self.speed * 1,确保不超出边界。
        • 随机选择一个新的移动方向。
    • 底部边界
      • elif self.rect.bottom > 630 - 3:
        • 将坦克向上移动 self.speed * -1,确保不超出边界。
        • 随机选择一个新的移动方向。
    • 左侧边界
      • elif self.rect.left < 3:
        • 将坦克向右移动 self.speed * 1,确保不超出边界。
        • 随机选择一个新的移动方向。
    • 右侧边界
      • elif self.rect.right > 630 - 3:
        • 将坦克向左移动 self.speed * -1,确保不超出边界。
        • 随机选择一个新的移动方向。

6.4 检查与其他精灵组的碰撞

  • if pygame.sprite.spritecollide(self, brickGroup, False, None) or ...
    • 使用 pygame.sprite.spritecollide 方法检查当前坦克是否与 brickGroup(砖块组)、ironGroup(铁块组)、tankGroup(玩家坦克组)中的任何一个精灵发生碰撞。
    • 参数解释
      • self:当前坦克实例。
      • brickGroupironGrouptankGroup:待检测碰撞的精灵组。
      • False:不删除碰撞的精灵。
      • None:使用默认的碰撞检测回调函数。
  • 若发生碰撞
    • self.rect = self.rect.move(self.speed * -self.dir_x, self.speed * -self.dir_y)
      • 将坦克移动回原位置,避免穿透障碍物。
    • self.dir_x, self.dir_y = random.choice(([0, 1], [0, -1], [1, 0], [-1, 0]))
      • 随机选择一个新的移动方向,避免卡在障碍物中。

注释已加入原代码中;


原代码:


import pygame
#  引入 Pygame 模块,用于开发游戏。
import random
# 引入 Python 的 random 模块,用于生成随机数,决定坦克的类型、颜色和移动方向等。
import bulletClass
#   引入自定义的 bulletClass 模块,假设其中定义了 Bullet 类,用于处理子弹的行为。



class EnemyTank(pygame.sprite.Sprite):
    #   定义 EnemyTank 类,继承自 pygame.sprite.Sprite,
    #   使其具备精灵的基本属性和方法,便于在游戏中进行管理和渲染。
    def __init__(self, x = None, kind = None, isred = None):
        '''
        构造函数,接受三个可选参数:
        x:坦克的初始横向位置索引。
        kind:坦克的类型(1、2、3、4)。
        isred:布尔值,决定坦克是否为红色。
        '''
        pygame.sprite.Sprite.__init__(self)
        # 调用父类 pygame.sprite.Sprite 的构造函数,初始化精灵的基本属性。

        # 初始化闪烁效果相关属性
        self.flash = False
        # 用于控制坦克的闪烁效果,初始值为 False。
        self.times = 90
        # 计时器,用于控制闪烁效果的持续时间。
        
        # 确定坦克类型
        self.kind = kind    #   将传入的 kind 参数赋值给实例变量 self.kind。
        if not kind:
            self.kind = random.choice([1, 2, 3, 4])     # 如果未指定 kind,则随机选择一个类型(1、2、3、4)赋值给 self.kind。
            
        # 根据类型加载不同的坦克图像
        if self.kind == 1:   # 类型 1
            self.enemy_x_0 = pygame.image.load(r"..\image\enemy_1_0.png").convert_alpha()   # 加载 enemy_1_0.png
            self.enemy_x_3 = pygame.image.load(r"..\image\enemy_1_3.png").convert_alpha()   # 加载 enemy_1_3.png

        if self.kind == 2:   # 类型 2
            self.enemy_x_0 = pygame.image.load(r"..\image\enemy_2_0.png").convert_alpha()   # 加载 enemy_2_0.png
            self.enemy_x_3 = pygame.image.load(r"..\image\enemy_2_3.png").convert_alpha()   # 加载 enemy_2_3.png
        if self.kind == 3:   # 类型 3
            self.enemy_x_0 = pygame.image.load(r"..\image\enemy_3_1.png").convert_alpha()   # 加载 enemy_3_1.png
            self.enemy_x_3 = pygame.image.load(r"..\image\enemy_3_0.png").convert_alpha()   # 加载 enemy_3_0.png
        if self.kind == 4:   # 类型 4
            self.enemy_x_0 = pygame.image.load(r"..\image\enemy_4_0.png").convert_alpha()   # 加载 enemy_4_0.png
            self.enemy_x_3 = pygame.image.load(r"..\image\enemy_4_3.png").convert_alpha()   # 加载 enemy_4_3.png
        self.enemy_3_0 = pygame.image.load(r"..\image\enemy_3_0.png").convert_alpha()
        self.enemy_3_2 = pygame.image.load(r"..\image\enemy_3_2.png").convert_alpha()   # 无论类型如何,额外加载 enemy_3_0.png 和 enemy_3_2.png,可能用于动画或其他状态。
        
        
        # 确定坦克颜色(红色或默认颜色)
        self.isred = isred  # 将传入的 isred 参数赋值给实例变量 self.isred。

        if isred is None:   # 原代码:if not None:  此代码已修改为: if isred is None
            '''
        这里有一个逻辑错误,not None 始终为 True,因此无论 isred 是否传入,都会随机选择颜色。
        修正:应为 if isred is None:,以判断 isred 是否未传入。
            '''
            self.isred = random.choice((True, False, False, False, False))
            #  在修正后的逻辑下,若 isred 未指定,则有 20% 的概率选择 True(红色),80% 选择 False(默认颜色)。

        if self.isred:
            self.tank = self.enemy_x_3  # 如果 isred 为 True,则使用红色坦克图像 self.enemy_x_3
        else:
            self.tank = self.enemy_x_0  # 否则使用默认图像 self.enemy_x_0。
        # 设置坦克初始横向位置
        self.x = x   #  将传入的 x 参数赋值给实例变量 self.x。
        if not self.x:  # 如果 x 未指定,则随机选择 1、2、3 中的一个作为初始横向位置索引。
            self.x = random.choice([1, 2, 3])
        self.x -= 1   # 将 x 减 1,可能用于计算在游戏区域中的实际位置。
        
        # 设置坦克的图像区域和位置
        self.tank_R0 = self.tank.subsurface(( 0, 48), (48, 48))
        self.tank_R1 = self.tank.subsurface((48, 48), (48, 48))
        #   使用 subsurface 方法从坦克图像中截取特定区域,可能用于不同的动画帧或状态。
        self.rect = self.tank_R0.get_rect()   #  获取 tank_R0 图像的矩形区域,用于定位和碰撞检测。
        self.rect.left, self.rect.top = 3 + self.x * 12 * 24, 3 + 0 * 24
        '''
        设置坦克的初始位置:
        横向位置:3 + self.x * 12 * 24,根据 self.x 计算具体的横坐标。
        纵向位置:3 + 0 * 24,固定在纵向起始位置(可能为顶部)。
        '''

        # 初始化坦克的速度、方向、生命值、子弹状态等
        self.speed = 1  # 设置坦克的移动速度,默认值为 1。
        self.dir_x, self.dir_y = 0, 1   # 设置坦克的初始移动方向,(0,1) 表示向下移动。
        self.life = 1   # 设置坦克的生命值,默认值为 1。
        self.bulletNotCooling = True    # 子弹冷却状态标志,True 表示可以立即发射子弹。
        self.bullet = bulletClass.Bullet()  # 创建一个 Bullet 对象,用于管理坦克发射的子弹。
        # 是否需要改变方向
        self.dirChange = False  # 是否需要改变方向的标志,初始值为 False。

        # 根据坦克类型调整速度和生命值
        if self.kind == 2:
            self.speed = 3  # 如果坦克类型为 2,设置速度为 3。
        if self.kind == 3:
            self.life = 3   # 如果坦克类型为 3,设置生命值为 3。

    # 射击方法 shoot
    def shoot(self):
        # 设置子弹为活动状态
        self.bullet.life = True     # 将子弹的生命状态设为 True,表示子弹处于活动状态,可以移动和碰撞。
        self.bullet.changeImage(self.dir_x, self.dir_y)     # 根据坦克当前的移动方向,切换子弹的图像,使子弹方向与坦克一致。
        
        if self.dir_x == 0 and self.dir_y == -1:    # 向上射击 (0, -1)
            self.bullet.rect.left = self.rect.left + 20     # 子弹的左边缘与坦克左边缘偏移 20 像素对齐。
            self.bullet.rect.bottom = self.rect.top + 1     # 子弹的底部与坦克的顶部对齐,并向上偏移 1 像素,防止重叠。
        elif self.dir_x == 0 and self.dir_y == 1:   # 向下射击 (0, 1)
            self.bullet.rect.left = self.rect.left + 20     # 对子弹进行横向对齐。
            self.bullet.rect.top = self.rect.bottom - 1     # 子弹的顶部与坦克的底部对齐,并向下偏移 1 像素。
        elif self.dir_x == -1 and self.dir_y == 0:     # 向左射击 (-1, 0)
            self.bullet.rect.right = self.rect.left - 1     # 子弹的右边缘与坦克的左边缘对齐,并向左偏移 1 像素。
            self.bullet.rect.top = self.rect.top + 20       # 子弹的顶部与坦克的顶部偏移 20 像素对齐。
        elif self.dir_x == 1 and self.dir_y == 0:       # 向右射击 (1, 0)
            self.bullet.rect.left = self.rect.right + 1     # 子弹的左边缘与坦克的右边缘对齐,并向右偏移 1 像素。
            self.bullet.rect.top = self.rect.top + 20       # 子弹的顶部与坦克的顶部偏移 20 像素对齐。

    # 移动方法 move
    def move(self, tankGroup, brickGroup, ironGroup):
        self.rect = self.rect.move(self.speed * self.dir_x, self.speed * self.dir_y)
        #   根据当前的方向 (self.dir_x, self.dir_y) 和速度 (self.speed),更新坦克的位置。

        # 根据当前方向,使用 subsurface 方法从坦克图像中截取对应的区域,用于渲染不同方向的坦克图像。
        if self.dir_x == 0 and self.dir_y == -1:    # 向上移动 (0, -1)
            self.tank_R0 = self.tank.subsurface(( 0, 0),(48, 48))
            self.tank_R1 = self.tank.subsurface((48, 0),(48, 48))
        elif self.dir_x == 0 and self.dir_y == 1:   # 向下移动 (0, 1)
            self.tank_R0 = self.tank.subsurface(( 0, 48),(48, 48))
            self.tank_R1 = self.tank.subsurface((48, 48),(48, 48))
        elif self.dir_x == -1 and self.dir_y == 0:  # 向左移动 (-1, 0)
            self.tank_R0 = self.tank.subsurface(( 0, 96),(48, 48))
            self.tank_R1 = self.tank.subsurface((48, 96),(48, 48))
        elif self.dir_x == 1 and self.dir_y == 0:   # 向右移动 (1, 0)
            self.tank_R0 = self.tank.subsurface(( 0, 144),(48, 48))
            self.tank_R1 = self.tank.subsurface((48, 144),(48, 48))


        # 检查坦克是否超出边界,如果超出则调整位置并随机改变方向
        if self.rect.top < 3:   # 顶部边界
            self.rect = self.rect.move(self.speed * 0, self.speed * 1)  # 将坦克向下移动 self.speed * 1,确保不超出边界。
            self.dir_x, self.dir_y = random.choice(([0,1],[0,-1],[1,0],[-1,0]))     # 随机选择一个新的移动方向。
        elif self.rect.bottom > 630 - 3:    # 底部边界
            self.rect = self.rect.move(self.speed * 0, self.speed * -1)     # 将坦克向上移动 self.speed * -1,确保不超出边界。
            self.dir_x, self.dir_y = random.choice(([0,1],[0,-1],[1,0],[-1,0]))     # 随机选择一个新的移动方向。
        elif self.rect.left < 3:    # 左侧边界
            self.rect = self.rect.move(self.speed * 1, self.speed * 0)  # 将坦克向右移动 self.speed * 1,确保不超出边界。
            self.dir_x, self.dir_y = random.choice(([0,1],[0,-1],[1,0],[-1,0])) # 随机选择一个新的移动方向。
        elif self.rect.right > 630 - 3:     # 右侧边界
            self.rect = self.rect.move(self.speed * -1, self.speed * 0)     # 将坦克向左移动 self.speed * -1,确保不超出边界。
            self.dir_x, self.dir_y = random.choice(([0,1],[0,-1],[1,0],[-1,0]))     # 随机选择一个新的移动方向。
        # 检查与其他精灵组(砖块、铁块、玩家坦克)的碰撞
        if pygame.sprite.spritecollide(self, brickGroup, False, None) \
            or pygame.sprite.spritecollide(self, ironGroup, False, None) \
            or pygame.sprite.spritecollide(self, tankGroup, False, None):
            '''
            使用 pygame.sprite.spritecollide 方法检查当前坦克是否与 brickGroup(砖块组)、ironGroup(铁块组)、tankGroup(玩家坦克组)中的任何一个精灵发生碰撞。
            参数解释:
                self:当前坦克实例。
                brickGroup、ironGroup、tankGroup:待检测碰撞的精灵组。
                False:不删除碰撞的精灵。
                None:使用默认的碰撞检测回调函数。
            '''
            self.rect = self.rect.move(self.speed * -self.dir_x, self.speed * -self.dir_y)     # 将坦克移动回原位置,避免穿透障碍物。
            self.dir_x, self.dir_y = random.choice(([0,1],[0,-1],[1,0],[-1,0]))     # 随机选择一个新的移动方向,避免卡在障碍物中。

感兴趣点个赞!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值