1、源码来源:
下面我将详细解释您提供的 EnemyTank
类代码。该类使用 Pygame 模块创建一个敌方坦克对象,涵盖了初始化、移动、射击以及与其他游戏对象(如砖块、铁块、玩家坦克)的碰撞检测等功能。
2、这个模块主要实现了一个敌方坦克类 (EnemyTank
),用于在游戏中生成并控制敌方坦克的行为。模块的主要作用包括以下几点:
-
敌方坦克的初始化:
- 根据不同的种类 (
kind
),加载相应的坦克图像资源。 - 随机选择坦克的种类、颜色(是否为红色)以及初始位置。
- 设置坦克的初始速度、生命值等属性。
- 根据不同的种类 (
-
敌方坦克的移动:
- 根据当前的方向和速度更新坦克的位置。
- 检测坦克是否碰撞到屏幕边界或其他物体(如砖块、铁块、其他坦克),并随机改变移动方向。
-
敌方坦克的射击:
- 控制坦克的射击行为,根据当前的方向发射子弹。
- 子弹的生成位置和方向与坦克的当前状态相关联。
-
碰撞检测:
- 检测坦克与游戏中其他元素(如砖块、铁块、其他坦克)的碰撞,并根据碰撞情况调整坦克的移动方向。
总体来说,这个模块为游戏中的敌方坦克提供了行为逻辑,包括初始化、移动、射击、碰撞检测等,确保敌方坦克在游戏中能够动态地表现出不同的行为。
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.png
和enemy_1_3.png
。 - 类型2:加载
enemy_2_0.png
和enemy_2_3.png
。 - 类型3:加载
enemy_3_1.png
和enemy_3_0.png
。 - 类型4:加载
enemy_4_0.png
和enemy_4_3.png
。
- 类型1:加载
-
self.enemy_3_0
和self.enemy_3_2
:无论类型如何,额外加载enemy_3_0.png
和enemy_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:
:如果isred
为True
,则使用红色坦克图像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
:当前坦克实例。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]))
:- 随机选择一个新的移动方向,避免卡在障碍物中。
注释已加入原代码中;
原代码:
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])) # 随机选择一个新的移动方向,避免卡在障碍物中。