完善宠物系统

This commit is contained in:
2025-07-26 22:41:15 +08:00
parent 02a7e29e52
commit 048600e95d
135 changed files with 10204 additions and 5859 deletions

View File

@@ -53,15 +53,10 @@ extends CharacterBody2D
#- 亲密度(额外加属性)
#- 品质(白/绿/蓝/橙/红/紫)
#基本攻击方式:
#近战
#近战攻击伤害
#近战攻击速度
#远程
#远程攻击伤害
#远程攻击速度
#附录
#- 护甲公式示例:实际伤害 = 基础伤害 × (1 - 护甲值/(护甲值 + 100)),搭配"护甲穿透"可直接减少目标护甲值
#- 元素克制火属性攻击对冰属性敌人造成150%伤害同时被水属性克制仅造成80%伤害)
@@ -111,7 +106,7 @@ var current_armor: float = 100.0 # 当前护甲值
# 攻击属性
var attack_type: AttackType = AttackType.RANGED # 攻击类型
var attack_damage: float = 20.0 # 基础攻击伤害
var attack_range: float = 300.0 # 攻击距离
var attack_range: float = 400.0 # 攻击距离
var crit_rate: float = 0.1 # 暴击率0.0-1.0
var crit_damage: float = 1.5 # 暴击伤害倍数
var life_steal: float = 0.1 # 生命汲取0.0-1.0
@@ -152,7 +147,7 @@ enum RangedAttackMode {
PIERCING # 穿透攻击
}
# 内部状态变量(不需要导出)
var attack_speed: float = 1.0 # 当前攻击速度(根据攻击类型动态设置)
var gatling_firing: bool = false # 是否正在加特林射击
var gatling_current_bullet: int = 0 # 当前加特林子弹计数
@@ -219,13 +214,57 @@ var is_attacking: bool = false # 是否正在攻击
var is_berserker: bool = false # 是否处于狂暴状态
var is_stunned: bool = false # 是否被眩晕
var is_invulnerable: bool = false # 是否无敌
var is_being_knocked_back: bool = false # 是否正在被击退
var current_target: CharacterBody2D = null # 当前目标
var last_attacker: CharacterBody2D = null # 最后攻击者(用于击杀奖励)
var last_attack_time: float = 0.0 # 上次攻击时间
var last_regen_time: float = 0.0 # 上次恢复时间
var last_target_check_time: float = 0.0 # 上次目标检查时间
var knockback_velocity: Vector2 = Vector2.ZERO # 击退速度
# 受伤动画相关
var hurt_tween: Tween = null # 受伤动画缓动
var original_modulate: Color = Color.WHITE # 原始颜色
var last_hurt_time: float = 0.0 # 上次受伤时间(防止受伤动画过于频繁)
var hurt_animation_cooldown: float = 0.3 # 受伤动画冷却时间
# 攻击频率控制
var min_attack_interval: float = 0.5 # 最小攻击间隔(防止攻击过于频繁)
# 伤害反弹保护
var damage_reflect_depth: int = 0 # 伤害反弹递归深度
var max_reflect_depth: int = 3 # 最大反弹深度(防止无限递归)
# 性能保护
var performance_mode: bool = false # 性能模式(减少特效和计算)
var frame_skip_counter: int = 0 # 帧跳跃计数器
# 升级系统 - 基础属性列表(每次升级随机选择加点)
var base_upgrade_attributes: Array[String] = [
"max_health", # 最大生命值
"attack_damage", # 攻击伤害
"move_speed", # 移动速度
"max_shield", # 最大护盾值
"max_armor", # 最大护甲值
"crit_rate", # 暴击率
"health_regen", # 生命恢复
"attack_range" # 攻击距离
]
# 每次升级随机选择的属性数量
var attributes_per_level: int = 3
# 每5级额外属性奖励表
var level_milestone_bonuses: Dictionary = {
5: {"max_health": 20, "attack_damage": 5, "crit_rate": 0.02},
10: {"max_shield": 30, "armor_penetration": 5, "life_steal": 0.05},
15: {"max_armor": 25, "knockback_resist": 0.1, "dodge_rate": 0.03},
20: {"health_regen": 2, "move_speed": 15, "attack_range": 30},
25: {"max_health": 40, "attack_damage": 10, "enable_berserker_mode": true},
30: {"max_shield": 50, "shield_regen": 1, "enable_damage_reflect": true},
35: {"crit_damage": 0.3, "berserker_bonus": 0.2, "damage_reflect": 0.05},
40: {"max_armor": 40, "control_resist": 0.15, "enable_aid_system": true},
45: {"projectile_speed": 50, "pierce_count": 1, "enable_death_immunity": true},
50: {"max_health": 100, "attack_damage": 25, "enable_resurrection": true}
}
# 巡逻状态
var is_patrolling: bool = false # 是否正在巡逻
@@ -642,6 +681,10 @@ func _ready():
# 初始化生日
initialize_birthday()
# 保存原始颜色
if pet_image:
original_modulate = pet_image.modulate
# 延迟初始化UI显示确保所有节点都已准备好
call_deferred("update_ui")
@@ -702,35 +745,50 @@ func clamp_to_battle_area():
global_position.x = clamp(global_position.x, battle_area_min.x, battle_area_max.x)
global_position.y = clamp(global_position.y, battle_area_min.y, battle_area_max.y)
#宠物物理更新
#宠物物理更新(带性能保护)
func _physics_process(delta):
if not is_alive or is_dying:
return
# 性能保护每3帧执行一次非关键逻辑
frame_skip_counter += 1
var should_skip_frame = performance_mode and (frame_skip_counter % 3 != 0)
# 检测性能问题(如果帧时间过长,自动启用性能模式)
if delta > 0.025: # 帧时间超过25ms低于40FPS
if not performance_mode:
performance_mode = true
print("" + pet_name + " 启用性能模式(帧时间: " + str("%.3f" % delta) + "s")
# 巡逻宠物特殊处理
if is_patrolling:
handle_patrol(delta)
return
# 处理生命和护盾恢复
handle_regeneration(delta)
if not should_skip_frame:
handle_regeneration(delta)
# 更新年龄和亲密度
update_age_and_intimacy(delta)
# 更新年龄和亲密度(低优先级,可跳帧)
if not should_skip_frame:
update_age_and_intimacy(delta)
# 检查狂暴状态
check_berserker_mode()
if not should_skip_frame:
check_berserker_mode()
# 检查援助系统
check_aid_system()
# 检查援助系统(低优先级,可跳帧)
if not should_skip_frame:
check_aid_system()
# 如果被眩晕则不能行动
if is_stunned:
return
# 定期检查目标状态(每0.5秒检查一次
# 定期检查目标状态(性能模式下降低检查频率
var current_time = Time.get_ticks_msec() / 1000.0
if current_time - last_target_check_time >= 0.5:
var check_interval = 0.5 if not performance_mode else 1.0
if current_time - last_target_check_time >= check_interval:
check_target_validity()
last_target_check_time = current_time
@@ -791,15 +849,7 @@ func update_ai_state(delta):
#宠物移动
func handle_movement(delta):
# 处理击退效果
if is_being_knocked_back:
velocity = knockback_velocity
# 击退衰减
knockback_velocity = knockback_velocity.lerp(Vector2.ZERO, 5.0 * delta)
if knockback_velocity.length() < 10.0:
is_being_knocked_back = false
knockback_velocity = Vector2.ZERO
elif current_state == PetState.MOVING_TO_TARGET and current_target:
if current_state == PetState.MOVING_TO_TARGET and current_target:
var distance_to_target = global_position.distance_to(current_target.global_position)
var direction = (current_target.global_position - global_position).normalized()
@@ -832,7 +882,7 @@ func handle_movement(delta):
else:
velocity = Vector2.ZERO
#宠物攻击
#宠物攻击(带频率保护)
func handle_attack(delta):
if current_state == PetState.ATTACKING and current_target:
var current_time = Time.get_ticks_msec() / 1000.0 # 转换为秒
@@ -841,8 +891,9 @@ func handle_attack(delta):
if ranged_mode == RangedAttackMode.GATLING:
handle_gatling_attack(current_time, delta)
else:
# 普通攻击频率控制
if current_time - last_attack_time >= 1.0 / attack_speed:
# 普通攻击频率控制(确保最小攻击间隔)
var attack_interval = max(1.0 / attack_speed, min_attack_interval)
if current_time - last_attack_time >= attack_interval:
perform_attack(current_target)
last_attack_time = current_time
@@ -959,9 +1010,9 @@ func perform_melee_attack(target: CharacterBody2D):
var heal_amount = damage * life_steal
heal(heal_amount)
# 击退效果
if knockback_force > 0:
apply_knockback_to_target(target)
# 击退效果已禁用
# if knockback_force > 0:
# apply_knockback_to_target(target)
# 根据攻击模式发射子弹
func fire_projectile_by_mode(target: CharacterBody2D):
@@ -1090,15 +1141,29 @@ func create_and_fire_projectile(start_pos: Vector2, target_pos: Vector2, damage:
RangedAttackMode.PIERCING:
projectile.get_node("ProjectileSprite").modulate = Color.PURPLE
#宠物受到伤害
#宠物受到伤害(带死循环保护)
func take_damage(damage: float, armor_pen: float = 0.0, attacker_element: ElementType = ElementType.NONE, attacker: CharacterBody2D = null):
if not is_alive or is_invulnerable:
return
# 防止过于频繁的伤害处理(性能保护)
var current_time = Time.get_ticks_msec() / 1000.0
if current_time - last_attack_time < 0.05: # 50ms最小伤害间隔
return
# 增加伤害反弹递归深度
damage_reflect_depth += 1
# 递归深度保护(防止无限反弹)
if damage_reflect_depth > max_reflect_depth:
damage_reflect_depth = max(0, damage_reflect_depth - 1)
return
# 闪避检测
if randf() < dodge_rate:
if attacker and is_instance_valid(attacker):
add_battle_detail_to_panel("" + pet_name + " 闪避了 " + attacker.pet_name + " 的攻击!", Color.CYAN)
damage_reflect_depth = max(0, damage_reflect_depth - 1)
return
var actual_damage = damage
@@ -1123,8 +1188,11 @@ func take_damage(damage: float, armor_pen: float = 0.0, attacker_element: Elemen
if actual_damage > 0:
current_health -= actual_damage
# 添加受伤细节
if attacker and is_instance_valid(attacker):
# 播放受伤动画(带冷却保护)
play_hurt_animation()
# 添加受伤细节(性能模式下减少文本输出)
if not performance_mode and attacker and is_instance_valid(attacker):
var damage_text = "💔 " + pet_name + " 受到 " + str(int(actual_damage)) + " 点伤害"
if element_extra_damage > 0:
damage_text += " (元素克制 +" + str(int(element_extra_damage)) + ""
@@ -1135,15 +1203,19 @@ func take_damage(damage: float, armor_pen: float = 0.0, attacker_element: Elemen
last_attacker = attacker
# 反击机制:立即将攻击者设为目标(只有启用战斗时才反击)
# 添加反击冷却,防止过于频繁的目标切换
if combat_enabled and attacker and is_instance_valid(attacker) and attacker.is_alive:
if attacker.get_team() != pet_team: # 确保不攻击队友
current_target = attacker
current_state = PetState.MOVING_TO_TARGET
# 只有当前没有目标或当前目标已死亡时才切换目标
if not current_target or not is_instance_valid(current_target) or not current_target.is_alive:
current_target = attacker
current_state = PetState.MOVING_TO_TARGET
# 伤害反弹
if enable_damage_reflect and damage_reflect > 0.0 and attacker and is_instance_valid(attacker):
var reflect_damage = damage * damage_reflect
attacker.take_damage(reflect_damage, 0.0, element_type, self) # 反弹伤害也会触发反击
# 伤害反弹(带递归深度保护)
if enable_damage_reflect and damage_reflect > 0.0 and attacker and is_instance_valid(attacker) and damage_reflect_depth <= max_reflect_depth:
var reflect_damage = damage * damage_reflect * 0.5 # 反弹伤害减半,防止无限递归
# 延迟反弹,避免同帧内的递归调用
call_deferred("apply_reflect_damage", attacker, reflect_damage)
# 检查死亡
if current_health <= 0:
@@ -1159,9 +1231,17 @@ func take_damage(damage: float, armor_pen: float = 0.0, attacker_element: Elemen
if not is_dying: # 防止重复调用die()
call_deferred("die")
# 减少伤害反弹递归深度
damage_reflect_depth = max(0, damage_reflect_depth - 1)
# 更新UI
call_deferred("update_ui")
# 延迟应用反弹伤害(防止递归调用)
func apply_reflect_damage(target: CharacterBody2D, reflect_damage: float):
if target and is_instance_valid(target) and target.is_alive:
target.take_damage(reflect_damage, 0.0, element_type, self)
#宠物死亡
func die():
if is_dying: # 如果已经在死亡过程中,直接返回
@@ -1416,6 +1496,10 @@ func apply_quality_bonuses():
func get_team() -> String:
return pet_team
# 获取攻击类型(调试用)
func get_attack_type() -> AttackType:
return attack_type
# 处理生命和护盾恢复
func handle_regeneration(delta: float):
var current_time = Time.get_ticks_msec() / 1000.0
@@ -1516,7 +1600,7 @@ func gain_experience(amount: float):
while pet_experience >= max_experience and pet_level < 50:
level_up()
# 升级
# 升级(新的随机属性系统)
func level_up():
pet_experience -= max_experience
pet_level += 1
@@ -1524,25 +1608,197 @@ func level_up():
# 计算新的升级经验需求(指数增长)
max_experience = 100.0 * pow(1.2, pet_level - 1)
# 升级属性加成
var level_bonus = 1.1 # 每级10%属性加成
# 随机选择属性进行升级
var upgraded_attributes = apply_random_attribute_upgrade()
max_health *= level_bonus
current_health = max_health # 升级回满血
attack_damage *= level_bonus
max_shield *= level_bonus
current_shield = max_shield # 升级回满护盾
max_armor *= level_bonus
current_armor = max_armor # 升级回满护甲
# 检查是否有里程碑奖励每5级
var milestone_rewards = apply_milestone_bonus()
# 升级回血和护盾护甲
current_health = max_health
current_shield = max_shield
current_armor = max_armor
# 升级特效
show_level_up_effect()
# 添加升级细节
add_battle_detail_to_panel("🎉 " + pet_name + " 升级到 " + str(pet_level) + " 级!", Color.GOLD)
var upgrade_text = "🎉 " + pet_name + " 升级到 " + str(pet_level) + " 级!"
upgrade_text += "\n📈 随机提升:" + ", ".join(upgraded_attributes)
if milestone_rewards.size() > 0:
upgrade_text += "\n🏆 里程碑奖励:" + ", ".join(milestone_rewards)
add_battle_detail_to_panel(upgrade_text, Color.GOLD)
call_deferred("update_ui")
# 应用随机属性升级
func apply_random_attribute_upgrade() -> Array[String]:
var upgraded_attributes: Array[String] = []
var available_attributes = base_upgrade_attributes.duplicate()
# 随机选择几个属性进行升级
for i in range(min(attributes_per_level, available_attributes.size())):
var random_index = randi() % available_attributes.size()
var selected_attribute = available_attributes[random_index]
available_attributes.remove_at(random_index)
# 应用属性升级
var upgrade_applied = apply_single_attribute_upgrade(selected_attribute)
if upgrade_applied:
upgraded_attributes.append(upgrade_applied)
return upgraded_attributes
# 应用单个属性升级
func apply_single_attribute_upgrade(attribute_name: String) -> String:
match attribute_name:
"max_health":
var bonus = randf_range(8.0, 15.0) # 随机8-15点生命值
max_health += bonus
return "生命值 +" + str(int(bonus))
"attack_damage":
var bonus = randf_range(2.0, 5.0) # 随机2-5点攻击力
attack_damage += bonus
return "攻击力 +" + str(int(bonus))
"move_speed":
var bonus = randf_range(3.0, 8.0) # 随机3-8点移动速度
move_speed += bonus
return "移动速度 +" + str(int(bonus))
"max_shield":
var bonus = randf_range(5.0, 12.0) # 随机5-12点护盾值
max_shield += bonus
return "护盾值 +" + str(int(bonus))
"max_armor":
var bonus = randf_range(4.0, 10.0) # 随机4-10点护甲值
max_armor += bonus
return "护甲值 +" + str(int(bonus))
"crit_rate":
var bonus = randf_range(0.01, 0.03) # 随机1-3%暴击率
crit_rate = min(1.0, crit_rate + bonus) # 暴击率上限100%
return "暴击率 +" + str(int(bonus * 100)) + "%"
"health_regen":
var bonus = randf_range(0.3, 0.8) # 随机0.3-0.8点生命恢复
health_regen += bonus
return "生命恢复 +" + str("%.1f" % bonus)
"attack_range":
var bonus = randf_range(8.0, 20.0) # 随机8-20点攻击距离
attack_range += bonus
return "攻击距离 +" + str(int(bonus))
_:
return ""
# 应用里程碑奖励
func apply_milestone_bonus() -> Array[String]:
var milestone_rewards: Array[String] = []
if not level_milestone_bonuses.has(pet_level):
return milestone_rewards
var bonuses = level_milestone_bonuses[pet_level]
for bonus_key in bonuses.keys():
var bonus_value = bonuses[bonus_key]
var reward_text = apply_milestone_bonus_single(bonus_key, bonus_value)
if reward_text != "":
milestone_rewards.append(reward_text)
return milestone_rewards
# 应用单个里程碑奖励
func apply_milestone_bonus_single(bonus_key: String, bonus_value) -> String:
match bonus_key:
"max_health":
max_health += bonus_value
return "生命值 +" + str(bonus_value)
"attack_damage":
attack_damage += bonus_value
return "攻击力 +" + str(bonus_value)
"max_shield":
max_shield += bonus_value
return "护盾值 +" + str(bonus_value)
"max_armor":
max_armor += bonus_value
return "护甲值 +" + str(bonus_value)
"crit_rate":
crit_rate = min(1.0, crit_rate + bonus_value)
return "暴击率 +" + str(int(bonus_value * 100)) + "%"
"armor_penetration":
armor_penetration += bonus_value
return "护甲穿透 +" + str(bonus_value)
"life_steal":
life_steal = min(1.0, life_steal + bonus_value)
return "生命汲取 +" + str(int(bonus_value * 100)) + "%"
"knockback_resist":
knockback_resist = min(1.0, knockback_resist + bonus_value)
return "击退抗性 +" + str(int(bonus_value * 100)) + "%"
"dodge_rate":
dodge_rate = min(1.0, dodge_rate + bonus_value)
return "闪避率 +" + str(int(bonus_value * 100)) + "%"
"health_regen":
health_regen += bonus_value
return "生命恢复 +" + str(bonus_value)
"move_speed":
move_speed += bonus_value
return "移动速度 +" + str(bonus_value)
"attack_range":
attack_range += bonus_value
return "攻击距离 +" + str(bonus_value)
"shield_regen":
shield_regen += bonus_value
return "护盾恢复 +" + str(bonus_value)
"crit_damage":
crit_damage += bonus_value
return "暴击伤害 +" + str(int(bonus_value * 100)) + "%"
"berserker_bonus":
berserker_bonus += bonus_value
return "狂暴加成 +" + str(int(bonus_value * 100)) + "%"
"damage_reflect":
damage_reflect = min(1.0, damage_reflect + bonus_value)
return "伤害反弹 +" + str(int(bonus_value * 100)) + "%"
"control_resist":
control_resist = min(1.0, control_resist + bonus_value)
return "控制抗性 +" + str(int(bonus_value * 100)) + "%"
"projectile_speed":
projectile_speed += bonus_value
return "子弹速度 +" + str(bonus_value)
"pierce_count":
pierce_count += bonus_value
return "穿透数量 +" + str(bonus_value)
"enable_berserker_mode":
if bonus_value:
enable_berserker_mode = true
return "解锁狂暴模式"
else:
return ""
"enable_damage_reflect":
if bonus_value:
enable_damage_reflect = true
return "解锁伤害反弹"
else:
return ""
"enable_aid_system":
if bonus_value:
enable_aid_system = true
return "解锁援助召唤"
else:
return ""
"enable_death_immunity":
if bonus_value:
enable_death_immunity = true
death_immunity = true
return "解锁死亡免疫"
else:
return ""
"enable_resurrection":
if bonus_value:
enable_resurrection = true
return "解锁死亡重生"
else:
return ""
_:
return ""
# 显示升级特效
func show_level_up_effect():
if not pet_image:
@@ -1677,34 +1933,24 @@ func heal(amount: float):
current_health = min(max_health, current_health + amount)
call_deferred("update_ui")
# 对目标应用击退效果
# 击退效果已禁用
func apply_knockback_to_target(target: CharacterBody2D):
if not target or not is_instance_valid(target):
return
# 计算击退方向
var direction = (target.global_position - global_position).normalized()
# 计算击退力度(考虑目标的击退抗性)
var effective_knockback = knockback_force * (1.0 - target.knockback_resist)
if effective_knockback > 0:
target.apply_knockback(direction, effective_knockback)
add_battle_detail_to_panel(pet_name + " 击退了 " + target.pet_name)
# 击退功能暂时禁用
pass
# 击退时调
# 击退效果已禁
func apply_knockback(direction: Vector2, force: float):
if not is_alive:
return
# 击退功能暂时禁用
pass
# 将位置限制在战斗区域内
func clamp_position_to_battle_area(pos: Vector2) -> Vector2:
var battle_area_min = Vector2(50, 50)
var battle_area_max = Vector2(1350, 670)
# 设置击退状态
is_being_knocked_back = true
knockback_velocity = direction * force
# 击退时短暂失去目标(可选)
if current_target and randf() < 0.3: # 30%概率失去目标
current_target = null
current_state = PetState.IDLE
pos.x = clamp(pos.x, battle_area_min.x, battle_area_max.x)
pos.y = clamp(pos.y, battle_area_min.y, battle_area_max.y)
return pos
# 元素克制计算
func get_element_multiplier(attacker_element: ElementType, defender_element: ElementType) -> float:
@@ -1827,3 +2073,82 @@ func clamp_to_patrol_area():
# 限制位置
position.x = clamp(position.x, min_x, max_x)
position.y = clamp(position.y, min_y, max_y)
# 播放受伤动画(带冷却保护)
func play_hurt_animation():
if not pet_image:
return
# 检查受伤动画冷却时间
var current_time = Time.get_ticks_msec() / 1000.0
if current_time - last_hurt_time < hurt_animation_cooldown:
return # 冷却中,不播放动画
last_hurt_time = current_time
# 如果已经有受伤动画在播放,停止之前的
if hurt_tween:
hurt_tween.kill()
hurt_tween = null
# 性能模式下简化动画
if performance_mode:
# 简单的颜色变化无需Tween
pet_image.modulate = Color.RED
# 使用计时器恢复颜色(更轻量)
await get_tree().create_timer(0.1).timeout
if pet_image: # 确保宠物还存在
pet_image.modulate = original_modulate
return
# 创建受伤动画(闪红效果)
hurt_tween = create_tween()
# 立即变红
pet_image.modulate = Color.RED
# 0.2秒后恢复原色
hurt_tween.tween_property(pet_image, "modulate", original_modulate, 0.2)
# 动画结束后清理
hurt_tween.tween_callback(func():
hurt_tween = null
)
# 切换性能模式
func toggle_performance_mode():
performance_mode = !performance_mode
var mode_text = "性能模式" if performance_mode else "正常模式"
add_battle_detail_to_panel("" + pet_name + " 切换到 " + mode_text, Color.YELLOW)
print("" + pet_name + " 切换到 " + mode_text)
# 输出宠物性能状态
func debug_performance_status():
print("=== " + pet_name + " 性能状态调试 ===")
print("性能模式: " + str(performance_mode))
print("伤害反弹深度: " + str(damage_reflect_depth))
print("帧跳跃计数: " + str(frame_skip_counter))
print("上次受伤时间: " + str(last_hurt_time))
print("上次攻击时间: " + str(last_attack_time))
print("当前状态: " + str(current_state))
print("是否存活: " + str(is_alive))
print("是否正在死亡: " + str(is_dying))
print("============================")
# 重置性能状态(紧急恢复)
func reset_performance_state():
performance_mode = false
damage_reflect_depth = 0
frame_skip_counter = 0
# 清理可能卡住的动画
if hurt_tween:
hurt_tween.kill()
hurt_tween = null
# 恢复正常颜色
if pet_image:
pet_image.modulate = original_modulate
print("🔄 " + pet_name + " 性能状态已重置")
add_battle_detail_to_panel("🔄 " + pet_name + " 性能状态已重置", Color.GREEN)

View File

@@ -57,7 +57,7 @@ var current_attacker_name: String = "" # 当前进攻者用户名
func _ready():
# 加载宠物配置
visibility_changed.connect(_on_visibility_changed)
load_pet_configs()
# 连接返回农场按钮
@@ -69,7 +69,6 @@ func _ready():
battle_end_panel.visible = false
if pet_battle_details_panel:
pet_battle_details_panel.visible = false
# 加载宠物配置
func load_pet_configs():
@@ -115,10 +114,17 @@ func clear_battle_details():
if battle_details:
battle_details.text = ""
# 战斗结束检查计时器
var battle_check_timer: float = 0.0
var battle_check_interval: float = 0.5 # 每0.5秒检查一次,减少性能开销
func _process(delta):
# 只有启用自动对战时才检查战斗结束
# 只有启用自动对战时才检查战斗结束,并使用计时器减少检查频率
if auto_battle_enabled and battle_started and not battle_ended:
check_battle_end()
battle_check_timer += delta
if battle_check_timer >= battle_check_interval:
battle_check_timer = 0.0
check_battle_end()
# 获取队伍节点 - 供宠物调用
@@ -224,12 +230,6 @@ func end_battle(winner: String):
# 显示战斗结算面板
func show_battle_end_panel(winner: String):
var result_text = ""
var team1_survivors = 0
var team2_survivors = 0
var team1_total_damage = 0.0
var team2_total_damage = 0.0
var team1_pets_info: Array[String] = []
var team2_pets_info: Array[String] = []
# 统计存活宠物和详细信息 - 从宠物组中获取
var all_pets = get_tree().get_nodes_in_group("pets")
@@ -237,22 +237,6 @@ func show_battle_end_panel(winner: String):
if not is_instance_valid(pet):
continue
var status = "💀死亡"
if pet.is_alive:
status = "❤️存活(" + str(int(pet.current_health)) + ")"
if pet.pet_team == "team1":
team1_survivors += 1
elif pet.pet_team == "team2":
team2_survivors += 1
# 统计战力
if pet.pet_team == "team1":
team1_total_damage += pet.attack_damage
team1_pets_info.append(pet.pet_name + " " + status)
elif pet.pet_team == "team2":
team2_total_damage += pet.attack_damage
team2_pets_info.append(pet.pet_name + " " + status)
# 构建结算文本
result_text += "=== 战斗结算 ===\n\n"
@@ -416,39 +400,46 @@ func clear_all_pets():
# 清空对战细节
clear_battle_details()
# 先移除宠物组标签
var all_pets = get_tree().get_nodes_in_group("pets")
for pet in all_pets:
if is_instance_valid(pet):
# 检查是否是当前面板下的宠物
if pet.get_parent() == team1_node or pet.get_parent() == team2_node or pet.get_parent() == neutral_node:
pet.remove_from_group("pets")
pet.remove_from_group("team1")
pet.remove_from_group("team2")
pet.remove_from_group("neutral")
# 批量处理宠物清理,提高性能
var nodes_to_clear = [team1_node, team2_node, neutral_node]
# 清理现有宠物
for child in team1_node.get_children():
if is_instance_valid(child):
child.queue_free()
for child in team2_node.get_children():
if is_instance_valid(child):
child.queue_free()
for child in neutral_node.get_children():
if is_instance_valid(child):
child.queue_free()
for node in nodes_to_clear:
if not is_instance_valid(node):
continue
# 先移除组标签,再清理节点
for child in node.get_children():
if is_instance_valid(child):
# 停止宠物的所有行为,防止在清理过程中继续执行逻辑
if child.has_method("set_combat_enabled"):
child.set_combat_enabled(false)
# 移除所有组标签
child.remove_from_group("pets")
child.remove_from_group("team1")
child.remove_from_group("team2")
child.remove_from_group("neutral")
child.remove_from_group("aid_minions")
# 立即销毁,避免延迟
node.remove_child(child)
child.queue_free()
# 清空队伍数组
team1_pets.clear()
team2_pets.clear()
# 清理所有子弹
var all_projectiles = get_tree().get_nodes_in_group("projectiles")
for projectile in all_projectiles:
if is_instance_valid(projectile):
projectile.queue_free()
# 清理所有子弹和援助宠物
var groups_to_clear = ["projectiles", "aid_minions"]
for group_name in groups_to_clear:
var group_nodes = get_tree().get_nodes_in_group(group_name)
for node in group_nodes:
if is_instance_valid(node):
node.remove_from_group(group_name)
node.queue_free()
# 等待一帧确保清理完成
await get_tree().process_frame
# 处理偷菜对战结果
func handle_steal_battle_result(winner: String):
@@ -556,7 +547,9 @@ func update_battle_pet_data(pet_id: String, attacker_name: String, exp_gained: f
"new_max_experience": max_exp,
"new_intimacy": current_intimacy,
"level_ups": level_ups,
"level_bonus_multiplier": level_bonus_multiplier
"level_bonus_multiplier": level_bonus_multiplier,
"is_steal_battle": is_steal_battle,
"battle_winner": winner_team
}
# 发送数据到服务器

View File

@@ -1 +0,0 @@
uid://b4p4xk0pdf7yg