import { _decorator, Component, Node, Prefab, instantiate, Vec3, Vec2, Sprite, SpriteFrame, resources, RigidBody2D, CCFloat, CCInteger } from 'cc'; import { sp } from 'cc'; import { ConfigManager, EnemyConfig } from '../Core/ConfigManager'; import { EnemyComponent } from '../CombatSystem/EnemyComponent'; const { ccclass, property } = _decorator; /** * 敌人生成器示例脚本 * 展示如何使用ConfigManager来创建不同类型的敌人 */ @ccclass('EnemySpawnerExample') export class EnemySpawnerExample extends Component { @property({ type: Prefab, tooltip: '基础敌人预制体' }) public enemyPrefab: Prefab = null; @property({ type: Node, tooltip: '敌人容器节点' }) public enemyContainer: Node = null; @property({ type: CCFloat, tooltip: '生成间隔(秒)' }) public spawnInterval: number = 2.0; @property({ type: CCInteger, tooltip: '最大敌人数量' }) public maxEnemies: number = 10; private configManager: ConfigManager = null; private currentWave: number = 1; private currentEnemyCount: number = 0; private spawnTimer: number = 0; private isSpawning: boolean = false; start() { this.configManager = ConfigManager.getInstance(); // 延迟开始生成敌人,等待配置加载 this.scheduleOnce(() => { this.startSpawning(); }, 1.0); } update(deltaTime: number) { if (!this.configManager || !this.configManager.isConfigLoaded()) { return; } // 更新生成计时器 this.spawnTimer += deltaTime; if (this.spawnTimer >= this.spawnInterval && this.currentEnemyCount < this.maxEnemies) { this.spawnRandomEnemy(); this.spawnTimer = 0; } } // 开始生成敌人 startSpawning() { if (!this.configManager || !this.configManager.isConfigLoaded()) { return; } console.log('开始生成敌人'); this.isSpawning = true; this.schedule(this.spawnRandomEnemy, this.spawnInterval); } // 生成随机敌人 spawnRandomEnemy() { if (!this.isSpawning) return; const enemyConfig = this.configManager.getRandomEnemy(); if (!enemyConfig) { return; } this.spawnEnemyWithConfig(enemyConfig); } // 根据类型生成敌人 spawnEnemyByType(enemyType: string) { const enemyConfig = this.configManager.getEnemyById(enemyType); if (!enemyConfig) { return; } this.spawnEnemyWithConfig(enemyConfig); } // 根据稀有度生成敌人 spawnEnemyByRarity(rarity: string) { const enemyConfig = this.configManager.getRandomEnemy(rarity); if (!enemyConfig) { return; } this.spawnEnemyWithConfig(enemyConfig); } // 根据敌人配置生成敌人 private spawnEnemyWithConfig(enemyConfig: EnemyConfig) { if (!this.enemyPrefab) { return; } // 实例化敌人 const enemyNode = instantiate(this.enemyPrefab); if (!enemyNode) { return; } // 设置敌人名称 enemyNode.name = 'Enemy'; // 添加到场景中 this.node.addChild(enemyNode); // 设置随机位置 const spawnRadius = 300; const angle = Math.random() * Math.PI * 2; const distance = Math.random() * spawnRadius; const x = Math.cos(angle) * distance; const y = Math.sin(angle) * distance; enemyNode.position = new Vec3(x, y, 0); // 添加敌人组件 const enemyComponent = enemyNode.addComponent(EnemyComponent); enemyComponent.enemyConfig = enemyConfig; enemyComponent.spawner = this; console.log(`生成敌人: ${enemyConfig.name} (${enemyConfig.rarity})`); // 加载敌人动画 this.loadEnemyAnimation(enemyNode, enemyConfig); this.currentEnemyCount++; } // 加载敌人动画 private loadEnemyAnimation(enemyNode: Node, enemyConfig: EnemyConfig) { // 检查敌人配置中是否有Spine动画路径 const animations = enemyConfig.visualConfig?.animations; if (!animations || !animations.idle) { console.log(`敌人 ${enemyConfig.name} 没有Spine动画路径`); return; } // 构建Spine动画资源路径 const spineDataPath = animations.idle; // 加载Spine动画资源 resources.load(spineDataPath, sp.SkeletonData, (err, skeletonData) => { if (err) { console.warn(`加载敌人Spine动画失败: ${spineDataPath}`, err); return; } // 查找或创建Spine组件 let spineComponent = enemyNode.getComponent(sp.Skeleton); if (!spineComponent) { spineComponent = enemyNode.addComponent(sp.Skeleton); } // 设置Spine数据 spineComponent.skeletonData = skeletonData; // 播放默认动画 if (spineComponent.findAnimation('idle')) { spineComponent.setAnimation(0, 'idle', true); } console.log(`敌人 ${enemyConfig.name} Spine动画加载成功: ${spineDataPath}`); }); } // 设置敌人外观 private setupEnemyVisual(enemyNode: Node, enemyConfig: EnemyConfig) { // 查找Spine动画组件 const spineComponent = enemyNode.getComponent(sp.Skeleton); if (spineComponent) { // 如果有Spine组件,设置Spine动画 this.setupEnemySpineAnimation(spineComponent, enemyConfig); } else { // 如果没有Spine组件,使用Sprite组件作为后备 const spriteComponent = enemyNode.getComponent(Sprite); if (spriteComponent) { // 根据稀有度设置颜色 const rarityColors = { 'common': { r: 200, g: 200, b: 200, a: 255 }, // 灰色 'uncommon': { r: 255, g: 255, b: 0, a: 255 }, // 黄色 'rare': { r: 255, g: 100, b: 0, a: 255 }, // 橙色 'boss': { r: 255, g: 0, b: 0, a: 255 } // 红色 }; const color = rarityColors[enemyConfig.rarity] || rarityColors['common']; spriteComponent.color = spriteComponent.color.set(color.r, color.g, color.b, color.a); } } // 设置缩放 enemyNode.setScale(enemyConfig.visualConfig.scale, enemyConfig.visualConfig.scale, 1); } // 设置敌人Spine骨骼动画 private setupEnemySpineAnimation(spineComponent: sp.Skeleton, enemyConfig: EnemyConfig) { const spineDataPath = enemyConfig.visualConfig.spritePrefab; if (!spineDataPath) { console.warn(`敌人 ${enemyConfig.name} 没有Spine动画路径`); return; } // 加载Spine动画数据 resources.load(spineDataPath, sp.SkeletonData, (err, skeletonData) => { if (err) { console.warn(`加载敌人Spine动画失败: ${spineDataPath}`, err); return; } // 设置Spine数据 spineComponent.skeletonData = skeletonData; // 播放默认动画(如果有的话) const animations = enemyConfig.visualConfig.animations; if (animations && animations.idle) { spineComponent.setAnimation(0, animations.idle, true); } else if (animations && animations.walk) { spineComponent.setAnimation(0, animations.walk, true); } console.log(`敌人 ${enemyConfig.name} Spine动画加载成功: ${spineDataPath}`); }); } // 设置敌人物理 private setupEnemyPhysics(enemyNode: Node, enemyConfig: EnemyConfig) { const rigidBody = enemyNode.getComponent(RigidBody2D); if (rigidBody) { // 设置线性速度(向左移动) const speed = enemyConfig.stats.speed; rigidBody.linearVelocity = new Vec2(-speed, 0); } } // 敌人死亡回调 public onEnemyDeath(enemyNode: Node) { this.currentEnemyCount--; // 移除敌人节点 if (enemyNode && enemyNode.isValid) { enemyNode.destroy(); } } // 设置当前波次 public setCurrentWave(wave: number) { this.currentWave = wave; } // 获取当前波次 public getCurrentWave(): number { return this.currentWave; } // 获取当前敌人数量 public getCurrentEnemyCount(): number { return this.currentEnemyCount; } // 清除所有敌人 public clearAllEnemies() { if (this.enemyContainer) { this.enemyContainer.destroyAllChildren(); } this.currentEnemyCount = 0; } // 暂停生成 public pauseSpawning() { this.spawnInterval = Number.MAX_VALUE; } // 恢复生成 public resumeSpawning(interval: number = 2.0) { this.spawnInterval = interval; this.spawnTimer = 0; } }