1、源码来源:
nullhttps://github.com/wangxingyao/TankWar?tab=readme-ov-file
完整代码在文末
2、导入模块
import pygame # 导入pygame模块
import bulletClass # 导入自定义模块
3、设置坦克升级之后的图像
# 玩家1和玩家2的不同坦克等级的图像文件路径
tank_T1_0 = r"..\image\tank_T1_0.png"
tank_T1_1 = r"..\image\tank_T1_1.png"
tank_T1_2 = r"..\image\tank_T1_2.png"
tank_T2_0 = r"..\image\tank_T2_0.png"
tank_T2_1 = r"..\image\tank_T2_1.png"
tank_T2_2 = r"..\image\tank_T2_2.png"
4、定义MyTank类并初始化精灵
class MyTank(pygame.sprite.Sprite):
def __init__(self, playerNumber):
# 初始化精灵
pygame.sprite.Sprite.__init__(self)
5、设置玩家生命状态
# 玩家生命状态
self.life = True
6、 根据不同的玩家编号加载不同的坦克图像
# 根据玩家编号加载不同等级的坦克图像
if playerNumber == 1:
self.tank_L0_image = pygame.image.load(tank_T1_0).convert_alpha() # 0级坦克
#pygame.image.load(tank_T1_1):使用 Pygame 的 image.load() 方法加载指定路径(tank_T1_1)中的图像文件。
# 这个路径对应的是玩家1在1级时的坦克图像文件。
#.convert_alpha():将加载的图像转换为包含 alpha 通道的图像格式(RGBA)
# ,这允许图像支持透明背景,从而使渲染更高效且图像显示效果更好。
self.tank_L1_image = pygame.image.load(tank_T1_1).convert_alpha() # 1级坦克
self.tank_L2_image = pygame.image.load(tank_T1_2).convert_alpha() # 2级坦克
if playerNumber == 2:
self.tank_L0_image = pygame.image.load(tank_T2_0).convert_alpha() # 0级坦克
self.tank_L1_image = pygame.image.load(tank_T2_1).convert_alpha() # 1级坦克
self.tank_L2_image = pygame.image.load(tank_T2_2).convert_alpha() # 2级坦克
7、坦克等级初始化
# 坦克等级初始化为0级
#因此,self.level = 0 的主要作用是确保每次创建 MyTank 实例时,坦克的等级都从最基础的状态开始。
self.level = 0
在代码中,self.level = 0
的作用是初始化坦克的等级。具体而言:
-
坦克等级:
self.level
代表坦克的当前等级。在这个游戏逻辑中,坦克可以升级或降级,从而改变其能力(例如子弹的速度和强度)。等级0代表初始状态,较低的能力,随着等级增加,坦克的能力会增强。 -
初始化:在
MyTank
类的__init__
方法中,将self.level
初始化为0
,表示玩家的坦克从最低等级(0级)开始。之后,玩家可以通过游戏中的某些行为(例如获得道具)来升级坦克,增加其等级。
因此,self.level = 0
的主要作用是确保每次创建 MyTank
实例时,坦克的等级都从最基础的状态开始。
8、设置坦克的动画及矩形边界
#self.tank 是一个实例属性,用于存储当前坦克的图像。这个属性会在游戏中用于渲染坦克的外观。
'''
self.tank = self.tank_L0_image:
这部分代码将之前加载的0级坦克图像(存储在 self.tank_L0_image 中)赋值给 self.tank。
也就是说,坦克的外观现在被设置为0级时的图像。
'''
self.tank = self.tank_L0_image
# 运动中的两种不同图像,用于坦克的动画切换
'''
self.tank_R0 和 self.tank_R1:
这两个属性分别用于存储坦克在两种不同状态下的子图像(即坦克的不同帧或动画状态)。
self.tank.subsurface((0, 0), (48, 48)):
1、self.tank 是当前坦克的完整图像。
2、subsurface((0, 0), (48, 48)) 方法用于从 self.tank 图像中截取一个子图像。
3、(0, 0) 是子图像的起始位置(左上角的坐标)。(48, 48) 是子图像的宽度和高度。这里截取的是一个 48x48 像素的正方形区域。
self.tank_R0 因此存储了从 self.tank 的左上角 (0, 0) 开始的 48x48 像素区域。
self.tank.subsurface((48, 0), (48, 48)):
'''
self.tank_R0 = self.tank.subsurface((0, 0), (48, 48))
'''
同样地,这一行代码从 self.tank 图像的 (48, 0) 位置开始截取一个 48x48 像素的子图像。
self.tank_R1 因此存储了从 self.tank 的位置 (48, 0) 开始的 48x48 像素区域。
'''
self.tank_R1 = self.tank.subsurface((48, 0), (48, 48))
# 设置坦克的矩形边界
'''
self.tank_R0.get_rect():
self.tank_R0 是之前提取的坦克的一个子图像(即坦克在某种状态下的图像)。
get_rect() 是 Pygame 提供的方法,用于获取该图像的矩形区域(Rect 对象)。这个 Rect 对象包括图像的尺寸(宽度和高度)以及初始位置(默认位置是 (0, 0))。
self.rect:
self.rect 是 MyTank 类的一个实例属性,用于存储坦克的 Rect 对象。
通过 self.rect,可以方便地访问和修改坦克的位置、尺寸,以及进行碰撞检测等操作。
'''
self.rect = self.tank_R0.get_rect()
'''
self.rect = self.tank_R0.get_rect() 通过为坦克的图像 self.tank_R0 创建一个矩形对象
self.rect,为后续的碰撞检测、位置控制和渲染操作提供了基础。
这个矩形对象是 Pygame 中管理和操作精灵位置及碰撞的重要工具。
'''
9、根据玩家编号设置坦克的初始位置
#self.tank 是一个实例属性,用于存储当前坦克的图像。这个属性会在游戏中用于渲染坦克的外观。
'''
self.tank = self.tank_L0_image:
这部分代码将之前加载的0级坦克图像(存储在 self.tank_L0_image 中)赋值给 self.tank。
也就是说,坦克的外观现在被设置为0级时的图像。
'''
self.tank = self.tank_L0_image
# 运动中的两种不同图像,用于坦克的动画切换
'''
self.tank_R0 和 self.tank_R1:
这两个属性分别用于存储坦克在两种不同状态下的子图像(即坦克的不同帧或动画状态)。
self.tank.subsurface((0, 0), (48, 48)):
1、self.tank 是当前坦克的完整图像。
2、subsurface((0, 0), (48, 48)) 方法用于从 self.tank 图像中截取一个子图像。
3、(0, 0) 是子图像的起始位置(左上角的坐标)。(48, 48) 是子图像的宽度和高度。这里截取的是一个 48x48 像素的正方形区域。
self.tank_R0 因此存储了从 self.tank 的左上角 (0, 0) 开始的 48x48 像素区域。
self.tank.subsurface((48, 0), (48, 48)):
'''
self.tank_R0 = self.tank.subsurface((0, 0), (48, 48))
'''
同样地,这一行代码从 self.tank 图像的 (48, 0) 位置开始截取一个 48x48 像素的子图像。
self.tank_R1 因此存储了从 self.tank 的位置 (48, 0) 开始的 48x48 像素区域。
'''
self.tank_R1 = self.tank.subsurface((48, 0), (48, 48))
# 设置坦克的矩形边界
'''
self.tank_R0.get_rect():
self.tank_R0 是之前提取的坦克的一个子图像(即坦克在某种状态下的图像)。
get_rect() 是 Pygame 提供的方法,用于获取该图像的矩形区域(Rect 对象)。这个 Rect 对象包括图像的尺寸(宽度和高度)以及初始位置(默认位置是 (0, 0))。
self.rect:
self.rect 是 MyTank 类的一个实例属性,用于存储坦克的 Rect 对象。
通过 self.rect,可以方便地访问和修改坦克的位置、尺寸,以及进行碰撞检测等操作。
'''
self.rect = self.tank_R0.get_rect()
'''
self.rect = self.tank_R0.get_rect() 通过为坦克的图像 self.tank_R0 创建一个矩形对象
self.rect,为后续的碰撞检测、位置控制和渲染操作提供了基础。
这个矩形对象是 Pygame 中管理和操作精灵位置及碰撞的重要工具。
'''
10、设置子弹的初始化位置
#这段代码是 MyTank 类中的 shoot 方法,用于坦克发射子弹。它主要根据坦克的方向设置子弹的初始位置,并将子弹的状态激活。
def shoot(self):
# 发射子弹
#这行代码将子弹的 life 属性设置为 True,表示子弹处于激活状态,已经发射。
self.bullet.life = True # 激活子弹
self.bullet.changeImage(self.dir_x, self.dir_y) # 根据坦克方向改变子弹图像
'''
行代码根据坦克的当前方向 (dir_x 和 dir_y) 更新子弹的方向图像。
changeImage 方法用于调整子弹的图像,以使子弹朝向与坦克相同的方向发射。
'''
# 根据坦克当前方向设置子弹的初始位置
if self.dir_x == 0 and self.dir_y == -1: # 向上
#如果坦克朝上 (dir_x = 0, dir_y = -1),
self.bullet.rect.left = self.rect.left + 20
'''
.rect.left 表示矩形区域左边缘的 x 坐标,即矩形最左侧的水平位置。
#则子弹的 left 坐标设置为坦克左侧加 20 像素,使子弹居中。
'''
self.bullet.rect.bottom = self.rect.top + 1
'''
.rect.bottom 表示矩形区域底边缘的 y 坐标,即矩形最下方的垂直位置。
子弹的 bottom 坐标设置为坦克顶部的 top 坐标加 1 像素,确保子弹从坦克的顶部发射。
'''
elif self.dir_x == 0 and self.dir_y == 1: # 向下
# 如果坦克朝下 (dir_x = 0, dir_y = 1)
self.bullet.rect.left = self.rect.left + 20
# 则子弹的 left 坐标仍然设置为坦克左侧加 20 像素。
self.bullet.rect.top = self.rect.bottom - 1
# 子弹的 top 坐标设置为坦克底部的 bottom 坐标减 1 像素,使子弹从坦克底部发射。
elif self.dir_x == -1 and self.dir_y == 0: # 向左
# 如果坦克朝左(dir_x=-1, dir_y=0)
self.bullet.rect.right = self.rect.left - 1
# 则子弹的 right 坐标设置为坦克左侧的 left 坐标减 1 像素,使子弹从坦克左侧发射。
self.bullet.rect.top = self.rect.top + 20
# 子弹的 top 坐标设置为坦克顶部加 20 像素,使子弹居中。
elif self.dir_x == 1 and self.dir_y == 0: # 向右
# 如果坦克朝右 (dir_x = 1, dir_y = 0)
self.bullet.rect.left = self.rect.right + 1
# 则子弹的 left 坐标设置为坦克右侧的 right 坐标加 1 像素,使子弹从坦克右侧发射。
self.bullet.rect.top = self.rect.top + 20
# 子弹的 top 坐标设置为坦克顶部加 20 像素,使子弹居中。
11、设置坦克升级:使其更强;
# 根据坦克等级设置子弹的速度和强度
if self.level == 1:
# 如果坦克等级为1
self.bullet.speed = 16
# 子弹的速度设置为16像素/帧。
self.bullet.strong = False
# 子弹的强度设置为 False,意味着这颗子弹可能无法穿透较坚硬的障碍物或敌方坦克。
if self.level == 2:
# 如果坦克等级为2
self.bullet.speed = 16
# 子弹的速度仍然为16像素/帧。
self.bullet.strong = True
# 子弹的强度设置为 True,意味着子弹可能更强大,可以穿透某些障碍物或击毁较强的敌方坦克。
if self.level == 3:
# 如果坦克等级为3
self.bullet.speed = 48
# 子弹的速度大幅提高至48像素/帧,表明坦克在最高等级时发射的子弹速度极快。
self.bullet.strong = True
# 子弹的强度保持为 True,意味着它不仅速度快,而且具有更强的破坏力。
12、设置坦克降级:
def levelDown(self):
# 坦克降级
if self.level > 0:
# 如果坦克的等级大于0
self.level -= 1
# 则将等级降低1。等级最小为0,在这个条件下,降级会将等级减少到下一个等级。
if self.level == 0:
# 如果当前等级是0
self.tank = self.tank_L0_image
# 设置坦克的图像为等级0的图像 self.tank_L0_image
self.bullet.speed = 6
# 设置子弹的速度为6像素/帧(较低的速度,反映了较低等级的子弹效果)。
self.bullet.strong = False
# 将子弹的强度设置为 False,表示子弹没有穿透能力或威力较小。
if self.level == 1:
# 如果当前等级是1
self.tank = self.tank_L1_image
# 设置坦克的图像为等级1的图像 self.tank_L1_image。
if self.level == 2:
# 如果当前等级是2
self.tank = self.tank_L2_image
# 置坦克的图像为等级2的图像 self.tank_L2_image
13、判断坦克向上移动的碰撞检测
def moveUp(self, tankGroup, brickGroup, ironGroup):
'''
这是方法的定义。moveUp 是一个用于控制坦克向上移动的方法。方法接收三个参数:
tankGroup(其他坦克的组)、brickGroup(砖块的组)、ironGroup(铁块的组),
这些参数用于后续的碰撞检测。
'''
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
'''
这行代码让坦克向上移动。self.speed * 0 表示水平速度为 0,
self.speed * -1 表示垂直速度为负,即向上移动。
self.rect是坦克在屏幕上的位置和大小的矩形区域,
这里使用 move 方法将坦克向上移动 self.speed 个像素。
'''
self.tank_R0 = self.tank.subsurface((0, 0),(48, 48))
'''
这行代码更新坦克的图像为向上的图像(第一帧动画)。
self.tank.subsurface((0, 0),(48, 48)) 表示从坦克的整体图像中截取一部分区域来显示。
(0, 0) 是起点坐标,(48, 48) 是截取的区域大小。
'''
self.tank_R1 = self.tank.subsurface((48, 0),(48, 48))
'''
这行代码更新坦克的图像为向上的图像(第二帧动画)。
类似于上一行代码,它从坦克的整体图像中截取另一部分区域,用于实现简单的动画效果。
'''
self.dir_x, self.dir_y = 0, -1
'''
这行代码设置坦克的方向为“向上”。dir_x = 0 表示水平不动,dir_y = -1 表示垂直向上。
这两个变量用于后续操作(例如射击方向)的判断,表示当前坦克朝向的方向。
'''
if self.rect.top < 3:
#这行代码检查坦克的顶部是否已经接近屏幕的顶部(小于3个像素)
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
'''
.move 方法在游戏开发中常用于更新对象的位置,尤其是在处理对象的移动和碰撞检测时。
通过它,可以轻松地计算和调整对象的位置,并生成新的位置矩形,而不会影响原始位置数据。
'''
# 如果坦克已经到达上边界,这行代码将坦克的位置向下移动,避免超出边界。
return True
# 返回 True,表示发生了碰撞或越界。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群)中的任何一个对象发生了碰撞。
# 这部分代码继续检测坦克是否与 ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
# 如果坦克已经到达上边界,这行代码将坦克的位置向下移动,避免超出边界。
return True
# 返回 True,表示发生了碰撞或越界。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 这行代码检测坦克是否与 tankGroup(其他坦克)中的任何一个对象发生了碰撞。
# 如果检测到与其他坦克发生碰撞,坦克会被向下移动,并返回 True。
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
# 如果坦克与其他坦克发生碰撞,这行代码将坦克的位置向下移动,避免与其他坦克重叠。
return True
# 再次返回 True,表示发生了碰撞。
return False
# 如果没有发生碰撞(即没有与上边界、砖块、钢铁块或其他坦克碰撞),返回 False,表示坦克可以继续移动。
14、判断坦克向下移动的碰撞检测
这段代码定义了一个名为 moveDown 的方法,用于处理坦克对象向下移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveDown(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 48),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 48),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 48) 到 (48, 96) 和 (48, 48) 到 (96, 96) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = 0, 1
# self.dir_x 和 self.dir_y 表示坦克的移动方向。0, 1 表示坦克朝向下方。
if self.rect.bottom > 630 - 3:
# 如果坦克的底部超出了屏幕的边界(假设屏幕高度为 630 像素,3 像素是边界缓冲区)
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 并返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# pygame.sprite.spritecollide
# 方法用于检测坦克与 brickGroup(砖块组)或 ironGroup(铁块组)之间的碰撞。
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 并返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞。如果是
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 将坦克移动回去并返回 True。
return False
# 如果没有发生任何碰撞,则返回 False。
15、判断坦克向左移动的碰撞检测
'''
这段代码定义了一个名为 moveLeft 的方法,用于处理坦克对象向左移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveLeft(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 96),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 96),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 96) 到 (48, 48) 和 (48, 96) 到 (48, 48) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = -1, 0
# self.dir_x 和 self.dir_y 表示坦克的移动方向。-1, 0 表示坦克朝向左方。
if self.rect.left < 3:
# 这行代码检查坦克的 左边 是否已经接近屏幕的 左部(小于3个像素)
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * 1)
return True
# # 将坦克移动回去并返回 True。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群),ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回 True,表示发生了碰撞。
return False
# 如果没有发生任何碰撞,则返回 False。
16、判断坦克向右移动的碰撞检测
'''
这段代码定义了一个名为 moveRight 的方法,用于处理坦克对象向右移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveRight(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 144),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 144),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 144) 到 (48, 48) 和 (48,144) 到 (48, 48) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = 1, 0
# self.dir_x 和 self.dir_y 表示坦克的移动方向。1, 0 表示坦克朝向右方。
if self.rect.right > 630 - 3:
# 如果坦克的底部超出了屏幕的边界(假设屏幕高度为 630 像素,3 像素是边界缓冲区)
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回结果为True 表示发生了碰撞
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群),ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回结果为True,表示发生了碰撞
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
## 将其移动回去(self.speed * -1)
return True
# 返回结果为True,表示发生了碰撞
return False
# 如果没有发生任何碰撞,则返回 False。
完整代码:
import pygame # 导入pygame模块
import bulletClass # 导入自定义模块
# 玩家1和玩家2的不同坦克等级的图像文件路径
tank_T1_0 = r"..\image\tank_T1_0.png"
tank_T1_1 = r"..\image\tank_T1_1.png"
tank_T1_2 = r"..\image\tank_T1_2.png"
tank_T2_0 = r"..\image\tank_T2_0.png"
tank_T2_1 = r"..\image\tank_T2_1.png"
tank_T2_2 = r"..\image\tank_T2_2.png"
class MyTank(pygame.sprite.Sprite):
def __init__(self, playerNumber):
# 初始化精灵
pygame.sprite.Sprite.__init__(self)
# 玩家生命状态
self.life = True
# 根据玩家编号加载不同等级的坦克图像
if playerNumber == 1:
self.tank_L0_image = pygame.image.load(tank_T1_0).convert_alpha() # 0级坦克
#pygame.image.load(tank_T1_1):使用 Pygame 的 image.load() 方法加载指定路径(tank_T1_1)中的图像文件。
# 这个路径对应的是玩家1在1级时的坦克图像文件。
#.convert_alpha():将加载的图像转换为包含 alpha 通道的图像格式(RGBA)
# ,这允许图像支持透明背景,从而使渲染更高效且图像显示效果更好。
self.tank_L1_image = pygame.image.load(tank_T1_1).convert_alpha() # 1级坦克
self.tank_L2_image = pygame.image.load(tank_T1_2).convert_alpha() # 2级坦克
if playerNumber == 2:
self.tank_L0_image = pygame.image.load(tank_T2_0).convert_alpha() # 0级坦克
self.tank_L1_image = pygame.image.load(tank_T2_1).convert_alpha() # 1级坦克
self.tank_L2_image = pygame.image.load(tank_T2_2).convert_alpha() # 2级坦克
# 坦克等级初始化为0级
#因此,self.level = 0 的主要作用是确保每次创建 MyTank 实例时,坦克的等级都从最基础的状态开始。
self.level = 0
# 初始状态为0级坦克
#self.tank 是一个实例属性,用于存储当前坦克的图像。这个属性会在游戏中用于渲染坦克的外观。
'''
self.tank = self.tank_L0_image:
这部分代码将之前加载的0级坦克图像(存储在 self.tank_L0_image 中)赋值给 self.tank。
也就是说,坦克的外观现在被设置为0级时的图像。
'''
self.tank = self.tank_L0_image
# 运动中的两种不同图像,用于坦克的动画切换
'''
self.tank_R0 和 self.tank_R1:
这两个属性分别用于存储坦克在两种不同状态下的子图像(即坦克的不同帧或动画状态)。
self.tank.subsurface((0, 0), (48, 48)):
1、self.tank 是当前坦克的完整图像。
2、subsurface((0, 0), (48, 48)) 方法用于从 self.tank 图像中截取一个子图像。
3、(0, 0) 是子图像的起始位置(左上角的坐标)。(48, 48) 是子图像的宽度和高度。这里截取的是一个 48x48 像素的正方形区域。
self.tank_R0 因此存储了从 self.tank 的左上角 (0, 0) 开始的 48x48 像素区域。
self.tank.subsurface((48, 0), (48, 48)):
'''
self.tank_R0 = self.tank.subsurface((0, 0), (48, 48))
'''
同样地,这一行代码从 self.tank 图像的 (48, 0) 位置开始截取一个 48x48 像素的子图像。
self.tank_R1 因此存储了从 self.tank 的位置 (48, 0) 开始的 48x48 像素区域。
'''
self.tank_R1 = self.tank.subsurface((48, 0), (48, 48))
# 设置坦克的矩形边界
'''
self.tank_R0.get_rect():
self.tank_R0 是之前提取的坦克的一个子图像(即坦克在某种状态下的图像)。
get_rect() 是 Pygame 提供的方法,用于获取该图像的矩形区域(Rect 对象)。这个 Rect 对象包括图像的尺寸(宽度和高度)以及初始位置(默认位置是 (0, 0))。
self.rect:
self.rect 是 MyTank 类的一个实例属性,用于存储坦克的 Rect 对象。
通过 self.rect,可以方便地访问和修改坦克的位置、尺寸,以及进行碰撞检测等操作。
'''
self.rect = self.tank_R0.get_rect()
'''
self.rect = self.tank_R0.get_rect() 通过为坦克的图像 self.tank_R0 创建一个矩形对象
self.rect,为后续的碰撞检测、位置控制和渲染操作提供了基础。
这个矩形对象是 Pygame 中管理和操作精灵位置及碰撞的重要工具。
'''
# 根据玩家编号设置坦克的初始位置
'''
if playerNumber == 1: 和 if playerNumber == 2::
这两条判断语句用于区分不同玩家。在这段代码中,
playerNumber 参数决定了这是第1位玩家还是第2位玩家。
'''
if playerNumber == 1:
self.rect.left, self.rect.top = 3 + 24 * 8, 3 + 24 * 24
'''
这行代码在 playerNumber == 1 的情况下执行,设定第1位玩家的坦克位置。
self.rect.left 和 self.rect.top 分别是坦克矩形区域的左边缘和上边缘的坐标。
3 + 24 * 8 和 3 + 24 * 24 是计算出的初始坐标,基于网格或像素单位系统计算,确保坦克出现在特定的起始位置。
'''
if playerNumber == 2:
self.rect.left, self.rect.top = 3 + 24 * 16, 3 + 24 * 24
'''
这行代码在 playerNumber == 2 的情况下执行,设定第2位玩家的坦克位置。
与第1位玩家类似,这里的计算方式相同,只是 left 坐标增加了 24 * 8 的距离,将坦克放置在另一个初始位置。
'''
# 坦克速度、方向、生命值及子弹冷却状态
self.speed = 3 #这行代码设置坦克的初始速度为 3。这个值决定了坦克在游戏中每次移动时的位置变化量,即坦克移动的快慢。
self.dir_x, self.dir_y = 0, -1 # 坦克初始朝向(向上)
'''
这行代码设置坦克的初始方向为向上。
#dir_x 和 dir_y 分别表示坦克在水平方向和垂直方向上的移动方向。0, -1
表示坦克在水平方向上没有移动(dir_x = 0),而在垂直方向上向上移动(dir_y = -1)。
'''
self.life = 3 # 生命值为3
'''
这行代码为坦克设置初始生命值为 3。
生命值表示坦克能够承受的最大伤害次数,当生命值减至 0 时,坦克将被摧毁。
'''
self.bulletNotCooling = True # 子弹是否在冷却中
'''
这行代码设置子弹的初始冷却状态为 True,即子弹不在冷却中,坦克可以立即发射子弹。
冷却状态通常用于控制子弹的发射频率,防止坦克连续发射子弹而破坏游戏平衡。
'''
self.bullet = bulletClass.Bullet() # 创建一个子弹实例
'''
这行代码创建了一个 Bullet 类的实例,并将其赋值给 self.bullet。
这个实例用于管理坦克发射的子弹,包括子弹的属性(如速度、方向、强度)和行为(如移动、碰撞检测)。
'''
#这段代码是 MyTank 类中的 shoot 方法,用于坦克发射子弹。它主要根据坦克的方向设置子弹的初始位置,并将子弹的状态激活。
def shoot(self):
# 发射子弹
#这行代码将子弹的 life 属性设置为 True,表示子弹处于激活状态,已经发射。
self.bullet.life = True # 激活子弹
self.bullet.changeImage(self.dir_x, self.dir_y) # 根据坦克方向改变子弹图像
'''
行代码根据坦克的当前方向 (dir_x 和 dir_y) 更新子弹的方向图像。
changeImage 方法用于调整子弹的图像,以使子弹朝向与坦克相同的方向发射。
'''
# 根据坦克当前方向设置子弹的初始位置
if self.dir_x == 0 and self.dir_y == -1: # 向上
#如果坦克朝上 (dir_x = 0, dir_y = -1),
self.bullet.rect.left = self.rect.left + 20
'''
.rect.left 表示矩形区域左边缘的 x 坐标,即矩形最左侧的水平位置。
#则子弹的 left 坐标设置为坦克左侧加 20 像素,使子弹居中。
'''
self.bullet.rect.bottom = self.rect.top + 1
'''
.rect.bottom 表示矩形区域底边缘的 y 坐标,即矩形最下方的垂直位置。
子弹的 bottom 坐标设置为坦克顶部的 top 坐标加 1 像素,确保子弹从坦克的顶部发射。
'''
elif self.dir_x == 0 and self.dir_y == 1: # 向下
# 如果坦克朝下 (dir_x = 0, dir_y = 1)
self.bullet.rect.left = self.rect.left + 20
# 则子弹的 left 坐标仍然设置为坦克左侧加 20 像素。
self.bullet.rect.top = self.rect.bottom - 1
# 子弹的 top 坐标设置为坦克底部的 bottom 坐标减 1 像素,使子弹从坦克底部发射。
elif self.dir_x == -1 and self.dir_y == 0: # 向左
# 如果坦克朝左(dir_x=-1, dir_y=0)
self.bullet.rect.right = self.rect.left - 1
# 则子弹的 right 坐标设置为坦克左侧的 left 坐标减 1 像素,使子弹从坦克左侧发射。
self.bullet.rect.top = self.rect.top + 20
# 子弹的 top 坐标设置为坦克顶部加 20 像素,使子弹居中。
elif self.dir_x == 1 and self.dir_y == 0: # 向右
# 如果坦克朝右 (dir_x = 1, dir_y = 0)
self.bullet.rect.left = self.rect.right + 1
# 则子弹的 left 坐标设置为坦克右侧的 right 坐标加 1 像素,使子弹从坦克右侧发射。
self.bullet.rect.top = self.rect.top + 20
# 子弹的 top 坐标设置为坦克顶部加 20 像素,使子弹居中。
# 根据坦克等级设置子弹的速度和强度
if self.level == 1:
# 如果坦克等级为1
self.bullet.speed = 16
# 子弹的速度设置为16像素/帧。
self.bullet.strong = False
# 子弹的强度设置为 False,意味着这颗子弹可能无法穿透较坚硬的障碍物或敌方坦克。
if self.level == 2:
# 如果坦克等级为2
self.bullet.speed = 16
# 子弹的速度仍然为16像素/帧。
self.bullet.strong = True
# 子弹的强度设置为 True,意味着子弹可能更强大,可以穿透某些障碍物或击毁较强的敌方坦克。
if self.level == 3:
# 如果坦克等级为3
self.bullet.speed = 48
# 子弹的速度大幅提高至48像素/帧,表明坦克在最高等级时发射的子弹速度极快。
self.bullet.strong = True
# 子弹的强度保持为 True,意味着它不仅速度快,而且具有更强的破坏力。
# 增加坦克的等级,使其变得更强。
def levelUp(self):
# 坦克升级
if self.level < 2:
# 如果坦克的等级低于2
self.level += 1
# 则将等级提高1
if self.level == 0:
# 如果当前等级是0
self.tank = self.tank_L0_image
# 设置坦克的图像为等级0的图像 self.tank_L0_image。
if self.level == 1:
# 如果当前等级是1
self.tank = self.tank_L1_image
# 设置坦克的图像为等级1的图像 self.tank_L1_image。
if self.level == 2:
# 如果当前等级是2
self.tank = self.tank_L2_image
# 设置坦克的图像为等级2的图像 self.tank_L2_image
if self.level == 3:
# 如果等级等于3
self.tank = self.tank_L2_image
# 将坦克图像设置为等级2的图像 self.tank_L2_image。
def levelDown(self):
# 坦克降级
if self.level > 0:
# 如果坦克的等级大于0
self.level -= 1
# 则将等级降低1。等级最小为0,在这个条件下,降级会将等级减少到下一个等级。
if self.level == 0:
# 如果当前等级是0
self.tank = self.tank_L0_image
# 设置坦克的图像为等级0的图像 self.tank_L0_image
self.bullet.speed = 6
# 设置子弹的速度为6像素/帧(较低的速度,反映了较低等级的子弹效果)。
self.bullet.strong = False
# 将子弹的强度设置为 False,表示子弹没有穿透能力或威力较小。
if self.level == 1:
# 如果当前等级是1
self.tank = self.tank_L1_image
# 设置坦克的图像为等级1的图像 self.tank_L1_image。
if self.level == 2:
# 如果当前等级是2
self.tank = self.tank_L2_image
# 置坦克的图像为等级2的图像 self.tank_L2_image
def moveUp(self, tankGroup, brickGroup, ironGroup):
'''
这是方法的定义。moveUp 是一个用于控制坦克向上移动的方法。方法接收三个参数:
tankGroup(其他坦克的组)、brickGroup(砖块的组)、ironGroup(铁块的组),
这些参数用于后续的碰撞检测。
'''
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
'''
这行代码让坦克向上移动。self.speed * 0 表示水平速度为 0,
self.speed * -1 表示垂直速度为负,即向上移动。
self.rect是坦克在屏幕上的位置和大小的矩形区域,
这里使用 move 方法将坦克向上移动 self.speed 个像素。
'''
self.tank_R0 = self.tank.subsurface((0, 0),(48, 48))
'''
这行代码更新坦克的图像为向上的图像(第一帧动画)。
self.tank.subsurface((0, 0),(48, 48)) 表示从坦克的整体图像中截取一部分区域来显示。
(0, 0) 是起点坐标,(48, 48) 是截取的区域大小。
'''
self.tank_R1 = self.tank.subsurface((48, 0),(48, 48))
'''
这行代码更新坦克的图像为向上的图像(第二帧动画)。
类似于上一行代码,它从坦克的整体图像中截取另一部分区域,用于实现简单的动画效果。
'''
self.dir_x, self.dir_y = 0, -1
'''
这行代码设置坦克的方向为“向上”。dir_x = 0 表示水平不动,dir_y = -1 表示垂直向上。
这两个变量用于后续操作(例如射击方向)的判断,表示当前坦克朝向的方向。
'''
if self.rect.top < 3:
#这行代码检查坦克的顶部是否已经接近屏幕的顶部(小于3个像素)
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
'''
.move 方法在游戏开发中常用于更新对象的位置,尤其是在处理对象的移动和碰撞检测时。
通过它,可以轻松地计算和调整对象的位置,并生成新的位置矩形,而不会影响原始位置数据。
'''
# 如果坦克已经到达上边界,这行代码将坦克的位置向下移动,避免超出边界。
return True
# 返回 True,表示发生了碰撞或越界。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群)中的任何一个对象发生了碰撞。
# 这部分代码继续检测坦克是否与 ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
# 如果坦克已经到达上边界,这行代码将坦克的位置向下移动,避免超出边界。
return True
# 返回 True,表示发生了碰撞或越界。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 这行代码检测坦克是否与 tankGroup(其他坦克)中的任何一个对象发生了碰撞。
# 如果检测到与其他坦克发生碰撞,坦克会被向下移动,并返回 True。
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
# 如果坦克与其他坦克发生碰撞,这行代码将坦克的位置向下移动,避免与其他坦克重叠。
return True
# 再次返回 True,表示发生了碰撞。
return False
# 如果没有发生碰撞(即没有与上边界、砖块、钢铁块或其他坦克碰撞),返回 False,表示坦克可以继续移动。
'''
这段代码定义了一个名为 moveDown 的方法,用于处理坦克对象向下移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveDown(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * 0, self.speed * 1)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 48),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 48),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 48) 到 (48, 96) 和 (48, 48) 到 (96, 96) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = 0, 1
# self.dir_x 和 self.dir_y 表示坦克的移动方向。0, 1 表示坦克朝向下方。
if self.rect.bottom > 630 - 3:
# 如果坦克的底部超出了屏幕的边界(假设屏幕高度为 630 像素,3 像素是边界缓冲区)
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 并返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# pygame.sprite.spritecollide
# 方法用于检测坦克与 brickGroup(砖块组)或 ironGroup(铁块组)之间的碰撞。
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 并返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞。如果是
self.rect = self.rect.move(self.speed * 0, self.speed * -1)
# 将其移动回去(self.speed * -1)
return True
# 将坦克移动回去并返回 True。
return False
# 如果没有发生任何碰撞,则返回 False。
'''
这段代码定义了一个名为 moveLeft 的方法,用于处理坦克对象向左移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveLeft(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 96),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 96),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 96) 到 (48, 48) 和 (48, 96) 到 (48, 48) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = -1, 0
# self.dir_x 和 self.dir_y 表示坦克的移动方向。-1, 0 表示坦克朝向左方。
if self.rect.left < 3:
# 这行代码检查坦克的 左边 是否已经接近屏幕的 左部(小于3个像素)
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * 1)
return True
# # 将坦克移动回去并返回 True。
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群),ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回 True,表示发生了碰撞。
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回 True,表示发生了碰撞。
return False
# 如果没有发生任何碰撞,则返回 False。
'''
这段代码定义了一个名为 moveRight 的方法,用于处理坦克对象向右移动的逻辑,
同时检查是否与其他对象发生碰撞
'''
def moveRight(self, tankGroup, brickGroup, ironGroup):
self.rect = self.rect.move(self.speed * 1, self.speed * 0)
'''
这里 self.rect 是坦克对象的矩形边界框。
self.speed * 0 表示水平方向不移动。
self.speed * 1 表示垂直方向向下移动,self.speed 是坦克的速度。
.move(0, self.speed) 方法根据速度将坦克的位置向下移动。
'''
self.tank_R0 = self.tank.subsurface((0, 144),(48, 48))
self.tank_R1 = self.tank.subsurface((48, 144),(48, 48))
'''
self.tank 是坦克的当前图像,subsurface 方法从图像中截取指定区域
((0, 144) 到 (48, 48) 和 (48,144) 到 (48, 48) 的两个子图像)。
self.tank_R0 和 self.tank_R1 分别表示坦克在当前帧中的两个不同姿态,用于动画效果。
'''
self.dir_x, self.dir_y = 1, 0
# self.dir_x 和 self.dir_y 表示坦克的移动方向。1, 0 表示坦克朝向右方。
if self.rect.right > 630 - 3:
# 如果坦克的底部超出了屏幕的边界(假设屏幕高度为 630 像素,3 像素是边界缓冲区)
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回结果为True 表示发生了碰撞
if pygame.sprite.spritecollide(self, brickGroup, False, None) \
or pygame.sprite.spritecollide(self, ironGroup, False, None):
# 这行代码检测坦克是否与 brickGroup(砖块群),ironGroup(钢铁块群)中的任何一个对象发生了碰撞。
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
# 将其移动回去(self.speed * -1)
return True
# 返回结果为True,表示发生了碰撞
if pygame.sprite.spritecollide(self, tankGroup, False, None):
# 检查坦克是否与其他坦克(tankGroup)发生碰撞
self.rect = self.rect.move(self.speed * -1, self.speed * 0)
## 将其移动回去(self.speed * -1)
return True
# 返回结果为True,表示发生了碰撞
return False
# 如果没有发生任何碰撞,则返回 False。
如果注释看着乱自行删除