SkillManager.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { _decorator, Component, Node } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * 技能数据接口
  5. */
  6. export interface SkillData {
  7. id: string;
  8. name: string;
  9. description: string;
  10. icon: string;
  11. maxLevel: number;
  12. currentLevel: number;
  13. effects: any;
  14. }
  15. /**
  16. * 技能效果事件
  17. */
  18. export interface SkillEffectEvent {
  19. skillId: string;
  20. skillLevel: number;
  21. effectType: string;
  22. value: number;
  23. }
  24. /**
  25. * 技能管理器 - 单例模式
  26. * 负责技能数据管理和效果计算
  27. */
  28. @ccclass('SkillManager')
  29. export class SkillManager extends Component {
  30. private static _instance: SkillManager | null = null;
  31. private _skills: Map<string, SkillData> = new Map();
  32. private _eventCallbacks: Map<string, Function[]> = new Map();
  33. public static getInstance(): SkillManager | null {
  34. return SkillManager._instance;
  35. }
  36. onLoad() {
  37. if (SkillManager._instance === null) {
  38. SkillManager._instance = this;
  39. } else {
  40. this.destroy();
  41. return;
  42. }
  43. }
  44. onDestroy() {
  45. if (SkillManager._instance === this) {
  46. SkillManager._instance = null;
  47. }
  48. }
  49. /**
  50. * 初始化技能数据
  51. */
  52. public initSkills(skillsData: SkillData[]) {
  53. this._skills.clear();
  54. skillsData.forEach(skill => {
  55. this._skills.set(skill.id, { ...skill });
  56. });
  57. }
  58. /**
  59. * 获取技能等级
  60. */
  61. public getSkillLevel(skillId: string): number {
  62. const skill = this._skills.get(skillId);
  63. return skill ? skill.currentLevel : 0;
  64. }
  65. /**
  66. * 设置技能等级
  67. */
  68. public setSkillLevel(skillId: string, level: number): void {
  69. const skill = this._skills.get(skillId);
  70. if (skill) {
  71. skill.currentLevel = Math.max(0, Math.min(skill.maxLevel, level));
  72. this.notifySkillChanged(skillId);
  73. }
  74. }
  75. /**
  76. * 升级技能
  77. */
  78. public upgradeSkill(skillId: string): boolean {
  79. const skill = this._skills.get(skillId);
  80. if (skill && skill.currentLevel < skill.maxLevel) {
  81. skill.currentLevel++;
  82. this.notifySkillChanged(skillId);
  83. return true;
  84. }
  85. return false;
  86. }
  87. // ==================== 技能效果计算方法 ====================
  88. /**
  89. * 便宜单位技能效果 - 计算降价后的价格
  90. */
  91. public static calculateCheaperUnitsPrice(originalPrice: number, skillLevel: number): number {
  92. if (skillLevel <= 0) return originalPrice;
  93. const reductionRate = skillLevel * 0.1;
  94. return originalPrice * (1 - reductionRate);
  95. }
  96. /**
  97. * 暴击几率技能效果 - 计算新的暴击率
  98. */
  99. public static calculateCritChance(baseCritChance: number, skillLevel: number): number {
  100. if (skillLevel <= 0) return baseCritChance;
  101. const bonusCritChance = skillLevel * 0.1;
  102. return Math.min(1.0, baseCritChance + bonusCritChance);
  103. }
  104. /**
  105. * 暴击伤害计算
  106. */
  107. public static calculateCritDamage(baseDamage: number, skillLevel: number): number {
  108. if (skillLevel <= 0) return baseDamage;
  109. const critMultiplier = 1 + (skillLevel * 0.1);
  110. return baseDamage * critMultiplier;
  111. }
  112. /**
  113. * 治疗技能效果 - 计算增加后的生命值
  114. */
  115. public static calculateHealBonus(baseHealth: number, skillLevel: number): number {
  116. if (skillLevel <= 0) return baseHealth;
  117. const healthBonus = skillLevel * 0.1;
  118. return Math.floor(baseHealth * (1 + healthBonus));
  119. }
  120. /**
  121. * 计算治疗技能的即时治疗量
  122. */
  123. public static calculateInstantHeal(maxHealth: number, skillLevel: number): number {
  124. if (skillLevel <= 0) return 0;
  125. return Math.floor(maxHealth * 0.1 * skillLevel);
  126. }
  127. /**
  128. * 获取治疗技能的最大血量加成
  129. */
  130. public static getHealSkillHealthBonus(skillLevel: number): number {
  131. if (skillLevel <= 0) return 0;
  132. return skillLevel * 0.1;
  133. }
  134. /**
  135. * 多重射击技能效果 - 计算多射几率
  136. */
  137. public static calculateMultiShotChance(baseMultiShotChance: number, skillLevel: number): number {
  138. if (skillLevel <= 0) return baseMultiShotChance;
  139. const bonusChance = skillLevel * 0.1;
  140. return Math.min(1.0, baseMultiShotChance + bonusChance);
  141. }
  142. /**
  143. * 多重射击子弹数量计算
  144. */
  145. public static calculateMultiShotBulletCount(baseBulletCount: number, skillLevel: number): number {
  146. if (skillLevel <= 0) return baseBulletCount;
  147. return baseBulletCount + Math.floor(skillLevel / 2);
  148. }
  149. /**
  150. * 能量猎手技能效果 - 计算能量值加成
  151. */
  152. public static calculateEnergyBonus(baseEnergy: number, skillLevel: number): number {
  153. if (skillLevel <= 0) return baseEnergy;
  154. const energyMultiplier = 1 + (skillLevel * 0.1);
  155. return baseEnergy * energyMultiplier;
  156. }
  157. /**
  158. * 球速提升技能效果 - 计算新的球速
  159. */
  160. public static calculateBallSpeed(baseBallSpeed: number, skillLevel: number): number {
  161. if (skillLevel <= 0) return baseBallSpeed;
  162. const speedMultiplier = 1 + (skillLevel * 0.1);
  163. return baseBallSpeed * speedMultiplier;
  164. }
  165. /**
  166. * 检查是否触发暴击
  167. */
  168. public static rollCriticalHit(critChance: number): boolean {
  169. return Math.random() < critChance;
  170. }
  171. /**
  172. * 检查是否触发多重射击
  173. */
  174. public static rollMultiShot(multiShotChance: number): boolean {
  175. return Math.random() < multiShotChance;
  176. }
  177. // ==================== 事件系统 ====================
  178. /**
  179. * 注册技能变化监听
  180. */
  181. public onSkillChanged(skillId: string, callback: (skillId: string, level: number) => void): void {
  182. if (!this._eventCallbacks.has(skillId)) {
  183. this._eventCallbacks.set(skillId, []);
  184. }
  185. this._eventCallbacks.get(skillId)!.push(callback);
  186. }
  187. /**
  188. * 移除技能变化监听
  189. */
  190. public offSkillChanged(skillId: string, callback: Function): void {
  191. const callbacks = this._eventCallbacks.get(skillId);
  192. if (callbacks) {
  193. const index = callbacks.indexOf(callback);
  194. if (index > -1) {
  195. callbacks.splice(index, 1);
  196. }
  197. }
  198. }
  199. /**
  200. * 通知技能变化
  201. */
  202. private notifySkillChanged(skillId: string): void {
  203. const callbacks = this._eventCallbacks.get(skillId);
  204. const skill = this._skills.get(skillId);
  205. if (callbacks && skill) {
  206. callbacks.forEach(callback => {
  207. callback(skillId, skill.currentLevel);
  208. });
  209. }
  210. }
  211. /**
  212. * 获取所有技能数据(用于保存)
  213. */
  214. public getAllSkillsData(): SkillData[] {
  215. return Array.from(this._skills.values());
  216. }
  217. }