damage_calculation_report.md 5.5 KB

伤害计算机制分析报告

问题描述

用户观察到游戏中存在伤害波动现象,例如同样的武器有时造成10伤害,有时造成5伤害,想要了解具体原因。

调查过程

1. 敌人防御机制检查

  • 结果: ✅ 已排除防御因素
  • 详情:
    • 所有敌人的防御值已设置为0
    • EnemyInstance.ts中的takeDamage方法直接扣除伤害,没有防御减伤逻辑
    • EnemyComponent.ts虽然有getDefense方法,但实际战斗中未被使用

2. 伤害计算流程分析

完整的伤害计算链路:

武器基础伤害 (weapons.json)
    ↓
WeaponBullet.calculateRuntimeStats()
    ↓ 应用升级加成
基础伤害 + (等级 - 1)
    ↓ 应用稀有度倍数
稀有度倍数 × 升级后伤害
    ↓ 应用技能加成
PersistentSkillManager.applyDamageBonus()
    ↓ 得到最终伤害
WeaponBullet.getFinalDamage()
    ↓
BulletHitEffect.processNormalDamage()
    ↓ 暴击判定
BulletHitEffect.calculateCriticalDamage()
    ↓ 应用到敌人
EnemyInstance.takeDamage()

关键代码位置:

  • 伤害计算: WeaponBullet.ts - calculateRuntimeStats()
  • 暴击判定: BulletHitEffect.ts - calculateCriticalDamage()
  • 伤害应用: EnemyInstance.ts - takeDamage()

3. 伤害波动的根本原因

✅ 主要原因:暴击机制

暴击系统详情

// BulletHitEffect.ts - calculateCriticalDamage()
private calculateCriticalDamage(baseDamage: number): { damage: number, isCritical: boolean } {
    const weaponBullet = this.getComponent('WeaponBullet') as any;
    if (!weaponBullet) {
        // 默认暴击率10%,暴击倍数2倍
        const critChance = 0.1;
        const isCritical = Math.random() < critChance;
        
        if (isCritical) {
            const critDamage = baseDamage * 2;
            return { damage: critDamage, isCritical: true };
        }
        return { damage: baseDamage, isCritical: false };
    }
    
    // 使用WeaponBullet的暴击配置
    const critChance = weaponBullet.getCritChance();
    const critDamage = weaponBullet.getFinalCritDamage();
    const isCritical = Math.random() < critChance;
    
    return isCritical ? 
        { damage: critDamage, isCritical: true } : 
        { damage: baseDamage, isCritical: false };
}

暴击机制特点

  • 默认暴击率: 10% (当没有WeaponBullet组件时)
  • 默认暴击倍数: 2倍
  • 随机性: 每次攻击都会进行Math.random() < critChance判定
  • 日志输出: 暴击时会在控制台输出详细信息

🔍 其他可能因素

  1. 技能系统动态加成

    • PersistentSkillManager.applyDamageBonus()可能提供动态伤害加成
    • 需要进一步调查技能效果是否有随机性
  2. 武器升级状态

    • 不同升级等级会影响基础伤害
    • 稀有度倍数会显著影响最终伤害

验证结果

模拟测试 (pea_shooter, 基础伤害10)

模拟100次攻击结果:
- 普通攻击: 92次, 伤害: 10
- 暴击攻击: 8次, 伤害: 20
- 实际暴击率: 8% (接近理论值10%)

武器配置确认

// pea_shooter配置
{
  "id": "pea_shooter",
  "stats": {
    "damage": 10
  },
  "rarity": "common",
  "upgradeConfig": {
    "levels": {
      "1": { "damage": 10, "cost": 100 },
      "2": { "damage": 11, "cost": 150 },
      "3": { "damage": 12, "cost": 200 }
    }
  }
}

结论

伤害波动的主要原因是暴击机制

  • 每次攻击有10%概率触发暴击
  • 暴击时伤害翻倍(或根据武器配置的暴击倍数)
  • 这完全解释了"10伤害变成5伤害"的现象(实际应该是10伤害变成20伤害)

用户观察到的"10伤害变成5伤害"可能的解释

  1. 可能是观察错误,实际是10伤害变成20伤害(暴击)
  2. 可能存在其他未发现的伤害减少机制
  3. 可能是UI显示与实际伤害不一致

解决方案建议

如果要消除伤害波动:

  1. 禁用暴击机制

    // 在BulletHitEffect.ts中修改
    private calculateCriticalDamage(baseDamage: number): { damage: number, isCritical: boolean } {
       return { damage: baseDamage, isCritical: false }; // 强制返回基础伤害
    }
    
  2. 设置固定暴击率为0

    const critChance = 0.0; // 将暴击率设为0
    
  3. 在UI中显示暴击状态

    • 添加暴击特效提示
    • 在伤害数字上标注"CRIT!"
    • 使用不同颜色显示暴击伤害

如果要保留暴击机制:

  1. 改善用户体验

    • 确保暴击特效明显可见
    • 在伤害数字上清楚标注暴击
    • 在武器说明中明确显示暴击率和暴击倍数
  2. 平衡性调整

    • 调整暴击率(当前10%可能过高)
    • 调整暴击倍数(当前2倍可能过高)
    • 根据武器稀有度设置不同的暴击属性

技术细节

相关文件

  • assets/scripts/CombatSystem/BulletEffects/BulletHitEffect.ts - 暴击计算
  • assets/scripts/CombatSystem/WeaponBullet.ts - 伤害计算
  • assets/scripts/EnemySystem/EnemyInstance.ts - 伤害应用
  • assets/resources/data/weapons.json - 武器配置
  • assets/resources/data/enemies.json - 敌人配置

关键方法

  • BulletHitEffect.calculateCriticalDamage() - 暴击判定
  • WeaponBullet.calculateRuntimeStats() - 伤害计算
  • WeaponBullet.getFinalDamage() - 获取最终伤害
  • EnemyInstance.takeDamage() - 应用伤害

调查完成时间: $(date) 调查结论: 伤害波动主要由暴击机制引起,敌人防御已确认不是原因。