| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- import { _decorator, Component, Node, Vec3, instantiate } from 'cc';
- import { SkillManager } from '../SkillSelection/SkillManager'; // 导入SkillManager(用于多重射击技能)
- import { WeaponBullet } from '../WeaponBullet'; // 正确导入WeaponBullet
- import { BulletCountConfig } from '../../Core/ConfigManager';
- const { ccclass, property } = _decorator;
- /**
- * 子弹数量控制器
- * 负责根据配置生成不同数量和模式的子弹
- */
- export interface BulletSpawnInfo {
- position: Vec3; // 发射位置
- direction: Vec3; // 发射方向
- delay: number; // 延迟时间
- index: number; // 子弹索引
- }
- @ccclass('BulletCount')
- export class BulletCount extends Component {
-
- /**
- * 根据配置计算所有子弹的生成信息
- * @param config 子弹数量配置
- * @param firePosition 发射位置
- * @param baseDirection 基础方向
- * @returns 子弹生成信息数组
- */
- public static calculateBulletSpawns(
- config: BulletCountConfig,
- firePosition: Vec3,
- baseDirection: Vec3
- ): BulletSpawnInfo[] {
- const spawns: BulletSpawnInfo[] = [];
-
- switch (config.type) {
- case 'single':
- spawns.push(...this.createSingleShot(config, firePosition, baseDirection));
- break;
- case 'spread':
- spawns.push(...this.createSpreadShot(config, firePosition, baseDirection));
- break;
- case 'burst':
- spawns.push(...this.createBurstShot(config, firePosition, baseDirection));
- break;
- }
-
- return spawns;
- }
-
- /**
- * 单发模式
- */
- private static createSingleShot(
- config: BulletCountConfig,
- firePosition: Vec3,
- baseDirection: Vec3
- ): BulletSpawnInfo[] {
- return [{
- position: firePosition.clone(),
- direction: baseDirection.clone().normalize(),
- delay: 0,
- index: 0
- }];
- }
-
- /**
- * 散射模式 - 同时发射多颗子弹,呈扇形分布
- */
- private static createSpreadShot(
- config: BulletCountConfig,
- firePosition: Vec3,
- baseDirection: Vec3
- ): BulletSpawnInfo[] {
- const spawns: BulletSpawnInfo[] = [];
- const bulletCount = config.amount;
- const spreadAngleRad = config.spreadAngle * Math.PI / 180;
-
- if (bulletCount === 1) {
- // 只有一颗子弹时,直接使用基础方向
- return this.createSingleShot(config, firePosition, baseDirection);
- }
-
- // 计算每颗子弹的角度偏移
- const angleStep = spreadAngleRad / (bulletCount - 1);
- const startAngle = -spreadAngleRad / 2;
-
- for (let i = 0; i < bulletCount; i++) {
- const angle = startAngle + angleStep * i;
- const direction = this.rotateVector(baseDirection, angle);
-
- spawns.push({
- position: firePosition.clone(),
- direction: direction.normalize(),
- delay: 0,
- index: i
- });
- }
-
- return spawns;
- }
-
- /**
- * 连发模式 - 按时间间隔依次发射子弹
- */
- private static createBurstShot(
- config: BulletCountConfig,
- firePosition: Vec3,
- baseDirection: Vec3
- ): BulletSpawnInfo[] {
- const spawns: BulletSpawnInfo[] = [];
- const burstCount = config.burstCount || config.amount;
-
- for (let i = 0; i < burstCount; i++) {
- spawns.push({
- position: firePosition.clone(),
- direction: baseDirection.clone().normalize(),
- delay: i * config.burstDelay,
- index: i
- });
- }
-
- return spawns;
- }
-
- /**
- * 旋转向量
- */
- private static rotateVector(vector: Vec3, angleRad: number): Vec3 {
- const cos = Math.cos(angleRad);
- const sin = Math.sin(angleRad);
-
- return new Vec3(
- vector.x * cos - vector.y * sin,
- vector.x * sin + vector.y * cos,
- vector.z
- );
- }
-
- /**
- * 创建散射位置偏移(可选功能,用于霰弹枪等)
- */
- public static createSpreadPositions(
- basePosition: Vec3,
- spreadRadius: number,
- count: number
- ): Vec3[] {
- const positions: Vec3[] = [];
-
- if (count === 1) {
- positions.push(basePosition.clone());
- return positions;
- }
-
- const angleStep = (Math.PI * 2) / count;
-
- for (let i = 0; i < count; i++) {
- const angle = angleStep * i;
- const offset = new Vec3(
- Math.cos(angle) * spreadRadius,
- Math.sin(angle) * spreadRadius,
- 0
- );
-
- positions.push(basePosition.clone().add(offset));
- }
-
- return positions;
- }
-
- /**
- * 验证配置有效性
- */
- public static validateConfig(config: BulletCountConfig): boolean {
- if (!config) return false;
-
- // 检查基本参数
- if (config.amount <= 0) return false;
- if (config.spreadAngle < 0 || config.spreadAngle > 360) return false;
- if (config.burstDelay < 0) return false;
-
- // 检查类型特定参数
- switch (config.type) {
- case 'spread':
- if (config.amount > 20) {
- console.warn('散射子弹数量过多,可能影响性能');
- return false;
- }
- break;
- case 'burst':
- if (config.burstCount <= 0) return false;
- if (config.burstDelay <= 0.01) {
- console.warn('连发间隔过短,可能影响性能');
- }
- break;
- }
-
- return true;
- }
- /**
- * 创建多发子弹
- */
- public static createBullets(initData: any, bulletPrefab: Node): Node[] {
- // 关卡备战或其他情况下可关闭生成
- if (!(window as any).WeaponBullet?.shootingEnabled) return [];
- // 检查游戏是否暂停,暂停时不创建子弹
- const gamePause = (window as any).GamePause?.getInstance?.();
- if (gamePause && !gamePause.isBulletFireEnabled()) {
- return [];
- }
- // 获取武器配置
- const config = initData.weaponConfig || (window as any).WeaponBullet?.getWeaponConfig?.(initData.weaponId);
- if (!config) {
- return [];
- }
-
- // === 应用多重射击技能 ===
- const modifiedConfig = BulletCount.applyMultiShotSkill(config);
-
- // === 计算基础发射方向 ===
- let direction: Vec3;
- if (initData.direction) {
- direction = initData.direction.clone();
- } else if (initData.autoTarget) {
- // 使用 EnemyController 单例获取最近敌人,避免频繁 find
- const enemyController = (window as any).EnemyController?.getInstance?.();
- if (enemyController) {
- const nearestEnemy = enemyController.getNearestEnemy(initData.firePosition);
- if (nearestEnemy) {
- direction = nearestEnemy.worldPosition.clone().subtract(initData.firePosition).normalize();
- }
- }
- // 如果没有敌人或计算失败,则不创建子弹
- if (!direction) {
- console.log('【BulletCount】自动瞄准未找到有效目标,取消创建子弹');
- return [];
- }
- } else {
- // 非自动瞄准时使用默认方向
- const angleRand = Math.random() * Math.PI * 2;
- direction = new Vec3(Math.cos(angleRand), Math.sin(angleRand), 0);
- }
-
- // 计算批量生成信息(保持原逻辑)
- const spawnInfos = BulletCount.calculateBulletSpawns(
- modifiedConfig.bulletConfig.count,
- initData.firePosition,
- direction
- );
-
- const bullets: Node[] = [];
-
- // 为每个生成信息创建子弹实例
- for (const spawnInfo of spawnInfos) {
- try {
- const bullet = instantiate(bulletPrefab);
- const weaponBullet = bullet.getComponent(WeaponBullet) || bullet.addComponent(WeaponBullet);
- weaponBullet.init({
- ...initData,
- firePosition: spawnInfo.position,
- direction: spawnInfo.direction,
- weaponConfig: modifiedConfig
- });
- bullets.push(bullet);
- } catch (error) {
- console.error(`[BulletCount] 子弹创建失败:`, error);
- }
- }
-
- return bullets;
- }
- /**
- * 应用多重射击技能效果
- * @param originalConfig 原始武器配置
- * @returns 应用技能后的武器配置
- */
- public static applyMultiShotSkill(originalConfig: any): any {
- // 获取SkillManager实例
- const skillManager = SkillManager.getInstance();
- if (!skillManager) {
- return originalConfig; // 如果没有技能管理器,返回原配置
- }
- // 获取多重射击技能等级
- const multiShotSkillLevel = skillManager.getSkillLevel('multi_shots');
- console.log(`[BulletCount] 多重射击技能等级: ${multiShotSkillLevel}`);
- if (multiShotSkillLevel <= 0) {
- console.log(`[BulletCount] 技能等级为0,返回原配置`);
- return originalConfig; // 技能等级为0,返回原配置
- }
- const bulletCountConfig = originalConfig.bulletConfig.count;
- // 计算多重射击几率
- const baseMultiShotChance = 0; // 基础几率为0
- const multiShotChance = SkillManager.calculateMultiShotChance(baseMultiShotChance, multiShotSkillLevel);
- console.log(`[BulletCount] 多重射击几率: ${multiShotChance}`);
- // 检查是否触发多重射击
- const shouldTriggerMultiShot = SkillManager.rollMultiShot(multiShotChance);
- console.log(`[BulletCount] 是否触发多重射击: ${shouldTriggerMultiShot}`);
- if (!shouldTriggerMultiShot) {
- return originalConfig; // 未触发多重射击,返回原配置
- }
- // 触发多重射击,计算子弹数量
- const baseBulletCount = 1;
- const multiShotBulletCount = SkillManager.calculateMultiShotBulletCount(baseBulletCount, multiShotSkillLevel);
- // 创建修改后的配置
- const modifiedConfig: any = JSON.parse(JSON.stringify(originalConfig)); // 深拷贝
- // 修改子弹配置为连射模式(同一方向连续发射)
- modifiedConfig.bulletConfig.count = {
- type: 'burst',
- amount: 2, // 每次连射发射1发子弹
- burstCount: multiShotBulletCount, // 连射次数
- burstDelay: 200 // 连射间隔200毫秒,可以根据需要调整
- };
- console.log(`多重射击触发!技能等级: ${multiShotSkillLevel}, 子弹数量: ${multiShotBulletCount}`);
- return modifiedConfig;
- }
- }
|