正文
:
temp.rect = temp.rect.move((-temp.speed,
0
))
elif
temp.direction ==
"right"
:
temp.rect = temp.rect.move((temp.speed,
0
))
for
temp
in
cls.group_enemy:
if
temp.rect.x < BORDER_LEN
or
temp.rect.x > WIDTH - BORDER_LEN
or
temp.rect.y < BORDER_LEN
or
temp.rect.y > HEIGHT - BORDER_LEN:
cls.group_enemy.remove(temp)
print(
"子弹超出边界,移除子弹"
)
continue
if
temp.direction ==
"up"
:
temp.rect = temp.rect.move((
0
, -temp.speed))
elif
temp.direction ==
"down"
:
temp.rect = temp.rect.move((
0
, temp.speed))
elif
temp.direction ==
"left"
:
temp.rect = temp.rect.move((-temp.speed,
0
))
elif
temp.direction ==
"right"
:
temp.rect = temp.rect.move((temp.speed,
0
))
# 子弹碰砖墙(如果相碰,那么就移除当前子弹以及砖墙)
pygame.sprite.groupcollide(cls.group, Brick.group,
True
,
True
)
pygame.sprite.groupcollide(cls.group_enemy, Brick.group,
True
,
True
)
# 子弹碰铁墙(如果相碰,那么只移除子弹)
for
bullet
in
cls.group:
if
pygame.sprite.spritecollide(bullet, Iron.group,
False
,
None
):
cls.group.remove(bullet)
for
bullet
in
cls.group_enemy:
if
pygame.sprite.spritecollide(bullet, Iron.group,
False
,
None
):
cls.group_enemy.remove(bullet)
@classmethod
def
show
(cls, screen)
:
"""
显示子弹
"""
for
temp
in
cls.group:
screen.blit(temp.image, temp.rect)
for
temp
in
cls.group_enemy:
screen.blit(temp.image, temp.rect)
@classmethod
def
move_and_show
(cls, screen)
:
"""
移动、显示子弹
"""
cls.auto_move()
cls.show(screen)
class
PlayerTank
(pygame.sprite.Sprite)
:
"""
我方坦克类
"""
# 定义类属性,存储我方坦克(如果是单人模式就只有1个,如果是双人模式就有2个)
player_group = list()
# 定义精灵组,用来碰撞等判断
group = pygame.sprite.Group()
def
__init__
(self, player, top_left)
:
"""
实现初始化功能
"""
# 调用父类的初始化方法,这样才能够实现必要的初始化操作
super().__init__()
# 坦克的图片
image_path =
"resources/images/playerTank/tank_T1_0.png"
if
player ==
"player1"
else
"resources/images/playerTank/tank_T2_0.png"
self.tank_all_image = pygame.image.load(image_path).convert_alpha()
self.image = self.tank_all_image.subsurface((
0
,
0
), (
48
,
48
))
# 当使用碰撞判断方法时,pygame就需要知道当前要检测的物体的位置,所以这个rect属性一定要设置
self.rect = self.image.get_rect()
self.rect.topleft = top_left
# 记录初始位置,以便在被击中后能够重新在默认位置出现
self.origin_position = top_left
# 定义移动的步长
self.step_length =
8
# 坦克的默认方向
self.direction =
"up"
# 默认朝上
# 移动缓冲, 用于避免坦克连续移动过快导致不方便调整位置
self.move_cache_time =
4
self.move_cache_count =
0
# 坦克轮子转动效果
self.switch_count =
0
self.switch_time =
2
self.switch_image_index =
False
self.image_postion_index =
0
# 发射子弹的间隔
self.is_bullet_cooling =
False
# 如果是第一次发射子弹,则不在冷却时间内,可以正常发射
self.bullet_cooling_count =
0
self.bullet_cooling_time =
30
# 我方坦克生命次数
self.life_num =
3
# 标记此坦克是否显示
self.is_show_flag =
True
# 将当前对象添加到类属性中,这样就可以通过类对象访问到我方坦克
self.__class__.player_group.append(self)
# 或者self.player_group.append(self)也是可以的
# 添加到精灵组
self.group.add(self)
def
update_direction
(self)
:
"""
更新坦克的朝向
"""
if
self.direction ==
'up'
:
self.image = self.tank_all_image.subsurface((
0
,
0
), (
48
,
48
))
self.image_postion_index =
0
elif
self.direction ==
'down'
:
self.image = self.tank_all_image.subsurface((
0
,
48
), (
48
,
48
))
self.image_postion_index =
48
elif
self.direction ==
'left'
:
self.image = self.tank_all_image.subsurface((
0
,
96
), (
48
,
48
))
self.image_postion_index =
96
elif
self.direction ==
'right'
:
self.image = self.tank_all_image.subsurface((
0
,
144
), (
48
,
48
))
self.image_postion_index =
144
def
move
(self, direction, group_list)
:
"""
根据键盘调整坦克方向,然后移动
"""
# 如果要移动的方向与当前坦克的朝向不同,则先调整朝向
if
self.direction != direction:
self.direction = direction
self.update_direction()
return
# 移动缓冲
self.move_cache_count +=
1
if
self.move_cache_count < self.move_cache_time:
return
else
:
self.move_cache_count =
0
# 移动坦克
# 复制一份当前玩家坦克的坐标,如果碰到障碍物之后,可以进行恢复
rect_ori = self.rect
if
direction ==
"up"
:
self.rect = self.rect.move((
0
, -self.step_length))
elif
direction ==
"down"
:
self.rect = self.rect.move((
0
, self.step_length))
elif
direction ==
"left"
:
self.rect = self.rect.move((-self.step_length,
0
))
elif
direction ==
"right"
:
self.rect = self.rect.move((self.step_length,
0
))
# 检测碰撞"砖墙"、"铁墙"、"冰"、"河流"。"树"无需检查
for
group
in
group_list:
if
pygame.sprite.spritecollide(self, group,
False
,
None
):
self.rect = rect_ori
# 判断碰撞到边界
if
self.rect.top < BORDER_LEN:
self.rect.top = BORDER_LEN
elif
self.rect.bottom > HEIGHT - BORDER_LEN:
self.rect.bottom = HEIGHT - BORDER_LEN
elif
self.rect.left < BORDER_LEN:
self.rect.left = BORDER_LEN
elif
self.rect.right > WIDTH - BORDER_LEN:
self.rect.right = WIDTH - BORDER_LEN
# 为坦克轮动特效切换图片
self.switch_count +=
1
if
self.switch_count > self.switch_time:
self.switch_count =
0
self.switch_image_index =
not
self.switch_image_index
self.image = self.tank_all_image.subsurface((
48
* int(self.switch_image_index), self.image_postion_index), (
48
,
48
))
def
fire
(self)
:
"""
发射子弹
"""
if
not
self.is_bullet_cooling:
if
self.direction ==
"up"
:
position = (self.rect.centerx, self.rect.y)
elif
self.direction ==
"down"
:
position = (self.rect.centerx, self.rect.y +
48
)
elif
self.direction ==
"left"
:
position = (self.rect.x, self.rect.centery)
elif
self.direction ==
"right"
:
position = (self.rect.x +
48
, self.rect.centery)
Bullet(
"player"
, self.direction, position)
print(
"我方坦克发射子弹"
)
@classmethod
def
move_player_tank
(cls, is_dual_mode, group_list)
:
"""
控制我方坦克移动
"""
# 检查用户按键,从而控制坦克移动
key_pressed = pygame.key.get_pressed()
# 定义移动的步长
step_length =
8
# 复制一份当前玩家1的坐标,如果碰到障碍物之后,可以进行恢复
# rect_ori = cls.player_group[0].rect
# 玩家一, ASWD移动
if
key_pressed[pygame.K_w]:
cls.player_group[
0
].move(
"up"
, group_list)
elif
key_pressed[pygame.K_s]:
cls.player_group[
0
].move(
"down"
, group_list)
elif
key_pressed[pygame.K_a]:
cls.player_group[
0
].move(
"left"
, group_list)
elif
key_pressed[pygame.K_d]:
cls.player_group[
0
].move(
"right"
, group_list)
elif
key_pressed[pygame.K_SPACE]:
# 如果按下了空格键,那么就发射子弹
cls.player_group[
0
].fire()
# 检查玩家1是否碰撞到障碍物
# # 检测碰撞"砖墙"
# if pygame.sprite.spritecollide(cls.player_group[0], brick_group, False, None):
# print("玩家1碰到了砖墙", cls.player_group[0].rect)
# cls.player_group[0].rect = rect_ori
# 玩家二, ↑↓←→移动