file-type

探索Monsters OFX:Nuke中的革命性插件

RAR文件

下载需积分: 9 | 18.88MB | 更新于2025-03-17 | 46 浏览量 | 3 评论 | 5 下载量 举报 收藏
download 立即下载
根据提供的文件信息,可以看出所讨论的是名为“Monsters OFX”的Nuke插件,该插件属于OFX(OpenFX)插件集合之一。下面将详细介绍与这个主题相关的关键知识点。 ### OFX插件概述 OFX(OpenFX)是一个开放标准的插件框架,用于视觉特效、图像处理和视频编辑软件。它是由OpenFX协会定义的,旨在允许插件开发者创建与支持OFX的应用程序兼容的插件。OFX插件广泛用于电影和电视后期制作中,具有跨平台、开源且易于集成的特性。 ### Nuke插件的作用 Nuke是由The Foundry公司开发的一套功能强大的视觉特效软件,广泛应用于电影、电视和游戏行业的后期制作。它支持OFX、Python脚本、Gizmos等多种插件形式,可以极大扩展其内置功能,为艺术家提供创建复杂视觉效果的能力。 ### Monsters OFX插件特点 标题中的“Monsters OFX”表明我们正在讨论一种Nuke专用的OFX插件。尽管没有提供具体细节,但可以推断这种插件很可能提供了一些专门处理视觉效果的功能,如3D模型、动画、粒子系统、颜色校正等高级功能。由于插件的具体功能未在描述中提及,我们无法提供更具体的说明,但可以确定的是,它是一个用于Nuke软件的特定视觉效果工具。 ### OFX插件的使用场景 OFX插件在后期制作中被广泛应用,其使用场景包括但不限于: - **图像处理**:进行颜色校正、图像修复、风格化等操作。 - **合成**:通过各种合成技术将多个图层和元素整合在一起,创建复杂的视觉效果。 - **动态效果**:包括动态模糊、粒子效果、运动跟踪等动态元素的创建与控制。 - **3D视觉效果**:为2D图像添加3D元素,例如插入3D模型、环境映射等。 - **生成效果**:创建程序化生成的纹理、图案和形状。 ### OFX插件的开发与应用 OFX插件的开发通常需要使用C++或C语言,并且需要遵循OFX规范来编写。为了确保插件能够在不同的软件和操作系统上正常工作,开发者需要在多个平台进行测试。开发者社区中也有许多开源项目,允许艺术家和开发者合作开发和改进插件。 OFX插件在后期制作领域中的应用非常广泛,使得软件如Nuke能够通过不断扩增的插件库适应不断变化的市场需求。从色彩校正到复杂效果生成,OFX插件为艺术家提供了强大的工具集,以创造出前所未有的视觉效果。 ### 标签"ofx"的含义 标签“ofx”用于标识那些符合OFX标准的插件、应用程序或相关内容。在本例中,它表明“Monsters OFX”是一个符合OpenFX标准的插件,因此它能够被Nuke等软件所识别和使用。 ### 压缩包子文件的文件名称列表 提到的“Monsters OFX”位于压缩包子文件的文件名称列表中,这暗示了插件可能被打包成一个压缩包以便传输和安装。文件压缩是常见的软件分发方式,尤其是对于体积较大的插件或软件来说。解压缩文件通常需要使用如WinRAR、7-Zip等压缩工具。 总结来说,“Monsters OFX”是一个专门为Nuke设计的OFX插件,提供了一定范围的视觉特效或图像处理功能。由于缺乏具体的描述和功能列表,我们无法了解插件的全部细节,但可以确认它是一个能够在后期制作软件中扩展视觉特效和图像处理能力的工具。

相关推荐

filetype

// SkillManager.ts import { _decorator, Component, Node, Prefab, Vec3, v3, instantiate, Tween, tween, find } from 'cc'; const { ccclass, property } = _decorator; import { GameManager } from './GameManager'; // 导入GameManager import { MonsterController } from './MonsterController'; // 导入MonsterController @ccclass('SkillManager') export class SkillManager extends Component { @property({type: [Prefab]}) private skillsPrefabs: Prefab[] = []; // 技能特效节点预制体数组 // 添加对GameManager的引用 @property({type: Node}) private gameManagerNode: Node; // 挂载GameManager的节点 @property({type: Prefab}) private hengSaoQianJunEffectPrefab: Prefab; //横扫千军特效 @property({type: Prefab}) private duJieShuEffectPrefab: Prefab; //渡劫术特效 private gameManager: GameManager | null = null; // 存储当前激活的技能实例 private activeWanJianJueSkills: Node[] = []; //存储万剑诀实例 private activeDuJieShuSkills: Node[] = []; // 存储渡劫术实例 // 英雄节点引用 private heroNode: Node | null = null; // 万剑诀生成计时器 private wanJianJueSpawnTimer: number = 0; private wanJianJueSpawnCount: number = 0; // 已生成数量 // 万剑诀攻击范围(像素) private readonly WAN_JIAN_JUE_ATTACK_RANGE: number = 20; // 设置公共方法公共变量 public wanJianJueTotalCount: number = 20; // 普通状态:20把剑 public wanJianJueSpawnInterval: number = 0.1; // 普通状态:0.1秒间隔 public duJieShuDamage: number = 5; // 普通状态:5点伤害 // 设置万剑诀强化状态 public setEnhancedWanJian(enhanced: boolean) { if (enhanced) { this.wanJianJueTotalCount = 40; this.wanJianJueSpawnInterval = 0.05; } else { this.wanJianJueTotalCount = 20; this.wanJianJueSpawnInterval = 0.1; } } // 设置渡劫术强化状态 public setEnhancedDuJie(enhanced: boolean) { this.duJieShuDamage = enhanced ? 10 : 5; } protected onLoad(): void { // 获取GameManager组件 if (this.gameManagerNode) { this.gameManager = this.gameManagerNode.getComponent(GameManager); // 获取英雄节点 this.heroNode = this.gameManager.HeroNode; } } // 每帧更新 update(deltaTime: number) { // 更新万剑诀生成计时器 if (this.wanJianJueSpawnCount > 0 && this.wanJianJueSpawnCount < this.wanJianJueTotalCount) { this.wanJianJueSpawnTimer += deltaTime; // 检查是否达到生成间隔 if (this.wanJianJueSpawnTimer >= this.wanJianJueSpawnInterval) { this.wanJianJueSpawnTimer = 0; this.createWanJianJueInstance(); } } } //按键启动万剑诀 public buttenWanJianJue(){ // 获取最近的怪兽 let nearestMonster = this.getNearestMonsterForSkill(); if (nearestMonster) { // 重置生成参数 this.wanJianJueSpawnCount = 0; this.wanJianJueSpawnTimer = 0; // 立即生成第一个实例 this.createWanJianJueInstance(); } else { console.warn("没有找到有效的怪兽作为万剑诀落点"); } } /** * 获取最近的怪兽节点 * @returns 最近的怪兽节点或null */ private getNearestMonsterForSkill(): Node | null { if (!this.gameManager) { console.warn("GameManager未设置"); return null; } return this.gameManager.getNearestAliveMonster(); } /** * 创建单个万剑诀实例 */ private createWanJianJueInstance(): void { // 1. 找到万剑诀预制体 const wanJianJuePrefab = this.skillsPrefabs.find(prefab => prefab.name === "WanJianJue"); if (!wanJianJuePrefab) { console.error("万剑诀预制体未找到!"); return; } // 确保英雄节点有效 if (!this.heroNode || !this.heroNode.isValid) { console.warn("英雄节点无效,无法创建万剑诀实例"); return; } // 创建实例 const instance = instantiate(wanJianJuePrefab); // 获取英雄位置 const heroPos = this.heroNode.position.clone(); // 位置生成参数 const minX = heroPos.x - 350 + 470*0.6; const maxX = heroPos.x + 350 + 470*0.6; const minY = -350 - 185*0.6; const maxY = -50 -185*0.6; const minDistance = 30; // 距离英雄的最小距离 let position: Vec3; let attempts = 0; const maxAttempts = 10; // 最大尝试次数 // 尝试找到一个满足条件的位置 do { attempts++; // 在指定范围内生成随机位置 const randomX = Math.random() * (maxX - minX) + minX; const randomY = Math.random() * (maxY - minY) + minY; position = v3(randomX, randomY, heroPos.z); // 检查是否满足距离要求 const distanceToHero = Vec3.distance(position, heroPos); // 如果满足距离要求或达到最大尝试次数 if (distanceToHero >= minDistance || attempts >= maxAttempts) { break; } } while (true); // 设置位置 instance.setPosition(position); // 添加到场景 this.heroNode.parent.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); // 增加生成计数 this.wanJianJueSpawnCount++; // 0.5秒后检测伤害(基于该实例位置结合万剑诀单例的动画换算) this.scheduleOnce(() => { this.detectWanJianJueDamageForInstance(new Vec3(position.x-282,position.y+90,0)); // 0.3秒后删除该实例(总共0.8秒) this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeWanJianJueSkills.indexOf(instance); if (index !== -1) { this.activeWanJianJueSkills.splice(index, 1); } } }, 0.25); }, 0.5); } /** * 为单个万剑诀实例检测伤害 * @param position 实例位置 */ private detectWanJianJueDamageForInstance(position: Vec3): void { if (!this.gameManager) { console.warn("GameManager未设置,无法检测技能伤害"); return; } // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 计算距离(基于怪兽尺寸半径) const distance = Vec3.distance(monster.position, position); const monsterRadius = controller.MonsterSize; // 获取怪兽尺寸半径 // 计算总攻击范围 = 怪物半径 + 30像素攻击范围 const totalRange = monsterRadius + this.WAN_JIAN_JUE_ATTACK_RANGE; // 如果距离小于等于怪兽尺寸半径,造成伤害 if (distance <= totalRange) { // 对怪物造成伤害 controller.takeDamage(60); } } } /** * 清空所有激活的技能实例 */ private clearActiveSkills(): void { for (const skill of this.activeWanJianJueSkills) { if (skill.isValid) { skill.destroy(); } } this.activeWanJianJueSkills = []; } /** * 启动横扫千军技能 */ public buttenHengSaoQianJun() { // 在英雄位置创建横扫千军特效 this.startHengSaoQianJun(); } /** * 创建横扫千军技能 */ private startHengSaoQianJun(): void { // 1. 找到横扫千军预制体 const hengSaoQianJunPrefab = this.skillsPrefabs.find(prefab => prefab.name === "HengSaoQianJun1"); if (!hengSaoQianJunPrefab) { console.error("横扫千军预制体未找到!"); return; } // 确保英雄节点有效 if (!this.heroNode || !this.heroNode.isValid) { console.warn("英雄节点无效,无法创建横扫千军特效"); return; } // 创建实例 const instance = instantiate(hengSaoQianJunPrefab); // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 设置偏移量 - 根据英雄朝向调整X方向 const offsetX = isHeroFacingLeft ? 364 : -364; const offset = new Vec3(offsetX, 25, 0); // 计算最终位置 const heroPos = this.heroNode.position.clone(); const position = new Vec3( heroPos.x + offset.x, heroPos.y + offset.y, heroPos.z + offset.z ); instance.setPosition(position); // 调整技能朝向 - 与英雄朝向一致 const currentScale = instance.scale; if (isHeroFacingLeft) { // 英雄朝左,技能朝左(Scale.x为正) instance.setScale(new Vec3(Math.abs(currentScale.x), currentScale.y, currentScale.z)); } else { // 英雄朝右,技能朝右(Scale.x为负) instance.setScale(new Vec3(-Math.abs(currentScale.x), currentScale.y, currentScale.z)); } // 添加到场景 this.node.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); // 添加伤害检测 this.scheduleOnce(() => { this.detectHengSaoDamage(position); }, 0.7); // 0.7秒后检测伤害 // 1.7秒后删除技能实例 this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeWanJianJueSkills.indexOf(instance); if (index !== -1) { this.activeWanJianJueSkills.splice(index, 1); } } }, 1.6667); } /** * 检测横扫千军伤害 * @param position 技能位置 */ private detectHengSaoDamage(position: Vec3): void { if (!this.gameManager) { console.warn("GameManager未设置,无法检测技能伤害"); return; } // +++ 添加屏幕震动效果 +++ // 在巨剑砸到地面的瞬间触发震动 this.gameManager.triggerScreenShake(20, 0.9); // 使用更强的震动效果 // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 获取英雄位置 const heroPos = this.heroNode.position.clone(); // 定义伤害区域参数 const damageLength = 400; // 伤害区域长度(像素) const damageWidth = 200; // 伤害区域宽度(像素) const damageAmount = 80; // 伤害值80点 // 计算伤害区域边界 let minX: number, maxX: number; let minY: number, maxY: number; if (isHeroFacingLeft) { // 英雄朝左,伤害区域向左延伸 minX = heroPos.x - damageLength; maxX = heroPos.x; } else { // 英雄朝右,伤害区域向右延伸 minX = heroPos.x; maxX = heroPos.x + damageLength; } // Y轴范围(以英雄位置为中心) minY = heroPos.y - damageWidth / 2; maxY = heroPos.y + damageWidth / 2; // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 获取怪物位置 const monsterPos = monster.position; // 检查怪物是否在伤害区域内 const inXRange = monsterPos.x >= minX && monsterPos.x <= maxX; const inYRange = monsterPos.y >= minY && monsterPos.y <= maxY; if (inXRange && inYRange) { // 对怪物造成伤害 controller.takeDamage(damageAmount); } } } // 按键启动渡劫术 public buttonDuJieShu() { // 过滤出在350像素范围内的怪兽 const monstersInRange = this.getMonstersInRange(350); if (monstersInRange.length > 0) { this.startDuJieShu(monstersInRange); } else { console.warn("没有在350像素范围内的存活怪兽作为渡劫术目标"); } } /** * 获取距离英雄350像素范围内的存活怪兽 * @returns 范围内的存活怪兽节点数组 */ private getMonstersInRange(range: number): Node[] { if (!this.gameManager || !this.heroNode) { console.warn("GameManager或英雄节点未设置"); return []; } const monsters = this.gameManager.getAllMonsters(); const monstersInRange: Node[] = []; for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 计算距离 const distance = Vec3.distance(monster.position, this.heroNode.position); // 如果距离在指定范围内 if (distance <= range) { monstersInRange.push(monster); } } return monstersInRange; } /** * 启动渡劫术技能 * @param targetMonsters 目标怪物节点数组 */ private startDuJieShu(targetMonsters: Node[]): void { // 1. 找到渡劫术预制体 const duJieShuPrefab = this.skillsPrefabs.find(prefab => prefab.name === "DuJieShu-1"); if (!duJieShuPrefab) { console.error("渡劫术预制体未找到!"); return; } // 2. 为每个怪物创建渡劫术实例 for (const monster of targetMonsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 创建渡劫术实例 const instance = instantiate(duJieShuPrefab); // 设置位置为怪物位置 instance.setPosition(monster.position.clone()); // 添加到场景 this.heroNode.parent.addChild(instance); // 添加到激活技能列表 this.activeDuJieShuSkills.push(instance); // 3. 立即对目标怪物造成伤害 this.applyDuJieShuDamage(monster); // 4. 0.4667秒后删除技能实例 this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeDuJieShuSkills.indexOf(instance); if (index !== -1) { this.activeDuJieShuSkills.splice(index, 1); } } }, 0.4667); } } /** * 应用渡劫术伤害 * @param targetMonster 目标怪物节点 */ private applyDuJieShuDamage(targetMonster: Node): void { if (!targetMonster || !targetMonster.isValid) return; const controller = targetMonster.getComponent(MonsterController); if (!controller || controller.isDie) return; // 直接对怪物造成伤害 controller.takeDamage(this.duJieShuDamage); console.log(`渡劫术对 ${targetMonster.name} 造成${this.duJieShuDamage}伤害!`); } // 组件销毁时清理资源 protected onDestroy(): void { this.clearActiveSkills(); } }现在的重启游戏代码不完整,初始状态时英雄的位置是(0,-200,0),战斗背景的位置是(0,442.5,0);SkillManager.ts里面没有resetSkills();这个重启方法。

filetype

// SkillManager.ts import { _decorator, Component, Node, Prefab, Vec3, v3, instantiate, Tween, tween, find } from ‘cc’; const { ccclass, property } = _decorator; import { GameManager } from ‘./GameManager’; // 导入GameManager import { MonsterController } from ‘./MonsterController’; // 导入MonsterController @ccclass(‘SkillManager’) export class SkillManager extends Component { @property({type: [Prefab]}) private skillsPrefabs: Prefab[] = []; // 技能特效节点预制体数组 // 添加对GameManager的引用 @property({type: Node}) private gameManagerNode: Node; // 挂载GameManager的节点 private gameManager: GameManager | null = null; // 存储当前激活的技能实例 private activeWanJianJueSkills: Node[] = []; //存储万剑诀实例 private activeDuJieShuSkills: Node[] = []; // 存储渡劫术实例 // 英雄节点引用 private heroNode: Node | null = null; // 万剑诀生成计时器 private wanJianJueSpawnTimer: number = 0; private wanJianJueSpawnInterval: number = 0.2; // 0.2秒生成间隔 private wanJianJueSpawnCount: number = 0; // 已生成数量 private wanJianJueTotalCount: number = 10; // 总生成数量 // 万剑诀攻击范围(像素) private readonly WAN_JIAN_JUE_ATTACK_RANGE: number = 30; protected onLoad(): void { // 获取GameManager组件 if (this.gameManagerNode) { this.gameManager = this.gameManagerNode.getComponent(GameManager); // 获取英雄节点 this.heroNode = this.gameManager.HeroNode; } } // 每帧更新 update(deltaTime: number) { // 更新万剑诀生成计时器 if (this.wanJianJueSpawnCount > 0 && this.wanJianJueSpawnCount < this.wanJianJueTotalCount) { this.wanJianJueSpawnTimer += deltaTime; // 检查是否达到生成间隔 if (this.wanJianJueSpawnTimer >= this.wanJianJueSpawnInterval) { this.wanJianJueSpawnTimer = 0; this.createWanJianJueInstance(); } } } //按键启动万剑诀 public buttenWanJianJue(){ // 获取最近的怪兽 let nearestMonster = this.getNearestMonsterForSkill(); if (nearestMonster) { // 重置生成参数 this.wanJianJueSpawnCount = 0; this.wanJianJueSpawnTimer = 0; // 立即生成第一个实例 this.createWanJianJueInstance(); } else { console.warn(“没有找到有效的怪兽作为万剑诀落点”); } } /** * 获取最近的怪兽节点 * @returns 最近的怪兽节点或null / private getNearestMonsterForSkill(): Node | null { if (!this.gameManager) { console.warn(“GameManager未设置”); return null; } return this.gameManager.getNearestAliveMonster(); } /* * 创建单个万剑诀实例 / private createWanJianJueInstance(): void { // 1. 找到万剑诀预制体 const wanJianJuePrefab = this.skillsPrefabs.find(prefab => prefab.name === “WanJianJue”); if (!wanJianJuePrefab) { console.error(“万剑诀预制体未找到!”); return; } // 确保英雄节点有效 if (!this.heroNode || !this.heroNode.isValid) { console.warn(“英雄节点无效,无法创建万剑诀实例”); return; } // 创建实例 const instance = instantiate(wanJianJuePrefab); // 获取英雄位置 const heroPos = this.heroNode.position.clone(); // 位置生成参数 const minX = heroPos.x - 350 + 4700.6; const maxX = heroPos.x + 350 + 4700.6; const minY = -350 - 1850.6; const maxY = -50 -185*0.6; const minDistance = 80; // 距离英雄的最小距离 let position: Vec3; let attempts = 0; const maxAttempts = 10; // 最大尝试次数 // 尝试找到一个满足条件的位置 do { attempts++; // 在指定范围内生成随机位置 const randomX = Math.random() * (maxX - minX) + minX; const randomY = Math.random() * (maxY - minY) + minY; position = v3(randomX, randomY, heroPos.z); // 检查是否满足距离要求 const distanceToHero = Vec3.distance(position, heroPos); // 如果满足距离要求或达到最大尝试次数 if (distanceToHero >= minDistance || attempts >= maxAttempts) { break; } } while (true); // 设置位置 instance.setPosition(position); // 添加到场景 this.heroNode.parent.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); // 增加生成计数 this.wanJianJueSpawnCount++; // 0.5秒后检测伤害(基于该实例位置) this.scheduleOnce(() => { this.detectWanJianJueDamageForInstance(position); // 0.3秒后删除该实例(总共0.8秒) this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeWanJianJueSkills.indexOf(instance); if (index !== -1) { this.activeWanJianJueSkills.splice(index, 1); } } }, 0.25); }, 0.5); } /** * 为单个万剑诀实例检测伤害 * @param position 实例位置 / private detectWanJianJueDamageForInstance(position: Vec3): void { if (!this.gameManager) { console.warn(“GameManager未设置,无法检测技能伤害”); return; } // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 计算距离(基于怪兽尺寸半径) const distance = Vec3.distance(monster.position, position); const monsterRadius = controller.MonsterSize; // 获取怪兽尺寸半径 // 计算总攻击范围 = 怪物半径 + 30像素攻击范围 const totalRange = monsterRadius + this.WAN_JIAN_JUE_ATTACK_RANGE; // 如果距离小于等于怪兽尺寸半径,造成伤害 if (distance <= totalRange) { // 对怪物造成伤害 controller.takeDamage(60); } } } /* * 清空所有激活的技能实例 / private clearActiveSkills(): void { for (const skill of this.activeWanJianJueSkills) { if (skill.isValid) { skill.destroy(); } } this.activeWanJianJueSkills = []; } /* * 启动横扫千军技能 / public buttenHengSaoQianJun() { // 在英雄位置创建横扫千军特效 this.startHengSaoQianJun(); } /* * 创建横扫千军技能 / private startHengSaoQianJun(): void { // 1. 找到横扫千军预制体 const hengSaoQianJunPrefab = this.skillsPrefabs.find(prefab => prefab.name === “HengSaoQianJun1”); if (!hengSaoQianJunPrefab) { console.error(“横扫千军预制体未找到!”); return; } // 确保英雄节点有效 if (!this.heroNode || !this.heroNode.isValid) { console.warn(“英雄节点无效,无法创建横扫千军特效”); return; } // 创建实例 const instance = instantiate(hengSaoQianJunPrefab); // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 设置偏移量 - 根据英雄朝向调整X方向 const offsetX = isHeroFacingLeft ? 364 : -364; const offset = new Vec3(offsetX, 25, 0); // 计算最终位置 const heroPos = this.heroNode.position.clone(); const position = new Vec3( heroPos.x + offset.x, heroPos.y + offset.y, heroPos.z + offset.z ); instance.setPosition(position); // 调整技能朝向 - 与英雄朝向一致 const currentScale = instance.scale; if (isHeroFacingLeft) { // 英雄朝左,技能朝左(Scale.x为正) instance.setScale(new Vec3(Math.abs(currentScale.x), currentScale.y, currentScale.z)); } else { // 英雄朝右,技能朝右(Scale.x为负) instance.setScale(new Vec3(-Math.abs(currentScale.x), currentScale.y, currentScale.z)); } // 添加到场景 this.node.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); // 添加伤害检测 this.scheduleOnce(() => { this.detectHengSaoDamage(position); }, 0.7); // 0.7秒后检测伤害 // 1.7秒后删除技能实例 this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeWanJianJueSkills.indexOf(instance); if (index !== -1) { this.activeWanJianJueSkills.splice(index, 1); } } }, 1.6667); } /* * 检测横扫千军伤害 * @param position 技能位置 / private detectHengSaoDamage(position: Vec3): void { if (!this.gameManager) { console.warn(“GameManager未设置,无法检测技能伤害”); return; } // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 获取英雄位置 const heroPos = this.heroNode.position.clone(); // 定义伤害区域参数 const damageLength = 400; // 伤害区域长度(像素) const damageWidth = 200; // 伤害区域宽度(像素) const damageAmount = 80; // 伤害值80点 // 计算伤害区域边界 let minX: number, maxX: number; let minY: number, maxY: number; if (isHeroFacingLeft) { // 英雄朝左,伤害区域向左延伸 minX = heroPos.x - damageLength; maxX = heroPos.x; } else { // 英雄朝右,伤害区域向右延伸 minX = heroPos.x; maxX = heroPos.x + damageLength; } // Y轴范围(以英雄位置为中心) minY = heroPos.y - damageWidth / 2; maxY = heroPos.y + damageWidth / 2; // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 获取怪物位置 const monsterPos = monster.position; // 检查怪物是否在伤害区域内 const inXRange = monsterPos.x >= minX && monsterPos.x <= maxX; const inYRange = monsterPos.y >= minY && monsterPos.y <= maxY; if (inXRange && inYRange) { // 对怪物造成伤害 controller.takeDamage(damageAmount); } } } // 按键启动渡劫术 public buttonDuJieShu() { // 获取所有存活的怪兽 const allMonsters = this.getAllAliveMonsters(); if (allMonsters.length > 0) { this.startDuJieShu(allMonsters); } else { console.warn(“没有存活的怪兽作为渡劫术目标”); } } /* * 获取所有存活的怪兽 * @returns 存活怪兽节点数组 / private getAllAliveMonsters(): Node[] { if (!this.gameManager) { console.warn(“GameManager未设置”); return []; } return this.gameManager.getAllMonsters(); } /* * 启动渡劫术技能 * @param targetMonsters 目标怪物节点数组 / private startDuJieShu(targetMonsters: Node[]): void { // 1. 找到渡劫术预制体 const duJieShuPrefab = this.skillsPrefabs.find(prefab => prefab.name === “DuJieShu-1”); if (!duJieShuPrefab) { console.error(“渡劫术预制体未找到!”); return; } // 2. 为每个怪物创建渡劫术实例 for (const monster of targetMonsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 创建渡劫术实例 const instance = instantiate(duJieShuPrefab); // 设置位置为怪物位置 instance.setPosition(monster.position.clone()); // 添加到场景 this.heroNode.parent.addChild(instance); // 添加到激活技能列表 this.activeDuJieShuSkills.push(instance); // 3. 立即对目标怪物造成伤害 this.applyDuJieShuDamage(monster); // 4. 0.4667秒后删除技能实例 this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeDuJieShuSkills.indexOf(instance); if (index !== -1) { this.activeDuJieShuSkills.splice(index, 1); } } }, 0.4667); } } /* * 应用渡劫术伤害 * @param targetMonster 目标怪物节点 */ private applyDuJieShuDamage(targetMonster: Node): void { if (!targetMonster || !targetMonster.isValid) return; const controller = targetMonster.getComponent(MonsterController); if (!controller || controller.isDie) return; // 直接对怪物造成20点伤害 controller.takeDamage(10); console.log(渡劫术对 ${targetMonster.name} 造成20点伤害!); } // 组件销毁时清理资源 protected onDestroy(): void { this.clearActiveSkills(); } }新加一个功能,横扫千军在计算伤害的同时(此时巨剑砸到地面刚好适合)屏幕抖动一次(和GameManager.ts里的暴击一样)

filetype

// SkillManager.ts import { _decorator, Component, Node, Prefab, Vec3, v3, instantiate, Tween, tween } from ‘cc’; const { ccclass, property } = _decorator; import { GameManager } from ‘./GameManager’; // 导入GameManager import { MonsterController } from ‘./MonsterController’; // 导入MonsterController @ccclass(‘SkillManager’) export class SkillManager extends Component { @property({type: [Prefab]}) private skillsPrefabs: Prefab[] = []; // 技能特效节点预制体数组 // 添加对GameManager的引用 @property({type: Node}) private gameManagerNode: Node; // 挂载GameManager的节点 private gameManager: GameManager | null = null; // 存储当前激活的技能实例 private activeWanJianJueSkills: Node[] = []; // 英雄节点引用 private heroNode: Node | null = null; protected onLoad(): void { // 获取GameManager组件 if (this.gameManagerNode) { this.gameManager = this.gameManagerNode.getComponent(GameManager); // 获取英雄节点 this.heroNode = this.gameManager.HeroNode; } } //按键启动万剑诀 public buttenWanJianJue(){ // 获取最近的怪兽作为万剑诀落点 let nearestMonster = this.getNearestMonsterForSkill(); if (nearestMonster) { // 使用怪兽位置作为落点 const position = new Vec3(470, -185, 0); position.add(nearestMonster.position); // 在怪兽位置基础上调整偏移 this.startWanJianJue(position); } else { console.warn("没有找到有效的怪兽作为万剑诀落点"); } } /** * 获取最近的怪兽节点作为技能目标 * @returns 最近的怪兽节点或null */ private getNearestMonsterForSkill(): Node | null { if (!this.gameManager) { console.warn("GameManager未设置"); return null; } return this.gameManager.getNearestAliveMonster(); } /** * 启动万剑诀技能 * @param targetPosition 打击位置 */ private startWanJianJue(targetPosition: Vec3): void { // 1. 找到万剑诀预制体 const wanJianJuePrefab = this.skillsPrefabs.find(prefab => prefab.name === "WanJianJue"); if (!wanJianJuePrefab) { console.error("万剑诀预制体未找到!"); return; } // 2. 清空之前的技能实例 this.clearActiveSkills(); // 3. 创建20个万剑诀实例 for (let i = 0; i < 20; i++) { this.createWanJianJueInstance(wanJianJuePrefab, targetPosition); } // 4. 0.6秒后检测伤害 this.scheduleOnce(() => { this.detectSkillDamage(targetPosition.add(new Vec3(-470, +185, 0))); }, 0.6); // 5. 0.8秒后删除所有技能实例 this.scheduleOnce(() => this.clearActiveSkills(), 0.8); } /** * 检测技能伤害 * @param targetPosition 技能中心位置 */ private detectSkillDamage(targetPosition: Vec3): void { if (!this.gameManager) { console.warn("GameManager未设置,无法检测技能伤害"); return; } // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); const damageRadius = 150; // 伤害半径150像素 const damageAmount = 80; // 伤害值80点 for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 计算距离 const distance = Vec3.distance(monster.position, targetPosition); if (distance <= damageRadius) { // 对怪物造成伤害 controller.takeDamage(damageAmount); } } } /** * 创建单个万剑诀实例 * @param prefab 预制体 * @param targetPosition 目标位置 */ private createWanJianJueInstance(prefab: Prefab, targetPosition: Vec3): void { // 创建实例 const instance = instantiate(prefab); // 计算随机位置 (在半径200像素范围内) const randomAngle = Math.random() * Math.PI * 2; const randomRadius = Math.random() * 200; const offsetX = Math.cos(randomAngle) * randomRadius; const offsetY = Math.sin(randomAngle) * randomRadius; const position = v3( targetPosition.x + offsetX, targetPosition.y + offsetY, targetPosition.z ); // 设置初始位置 instance.setPosition(position); // 添加到场景 this.node.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); } /** * 清空所有激活的技能实例 */ private clearActiveSkills(): void { for (const skill of this.activeWanJianJueSkills) { if (skill.isValid) { // 添加消失动画 skill.destroy() } } this.activeWanJianJueSkills = []; } /** * 启动横扫千军技能 */ public buttenHengSaoQianJun() { // 在英雄位置创建横扫千军特效 this.startHengSaoQianJun(); } /** * 创建横扫千军技能 */ private startHengSaoQianJun(): void { // 1. 找到横扫千军预制体 const hengSaoQianJunPrefab = this.skillsPrefabs.find(prefab => prefab.name === "HengSaoQianJun1"); if (!hengSaoQianJunPrefab) { console.error("横扫千军预制体未找到!"); return; } // 确保英雄节点有效 if (!this.heroNode || !this.heroNode.isValid) { console.warn("英雄节点无效,无法创建横扫千军特效"); return; } // 创建实例 const instance = instantiate(hengSaoQianJunPrefab); // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 设置偏移量 - 根据英雄朝向调整X方向 const offsetX = isHeroFacingLeft ? 520 : -520; const offset = new Vec3(offsetX, 25, 0); // 计算最终位置 const heroPos = this.heroNode.position.clone(); const position = new Vec3( heroPos.x + offset.x, heroPos.y + offset.y, heroPos.z + offset.z ); instance.setPosition(position); // 调整技能朝向 - 与英雄朝向一致 const currentScale = instance.scale; if (isHeroFacingLeft) { // 英雄朝左,技能朝左(Scale.x为正) instance.setScale(new Vec3(Math.abs(currentScale.x), currentScale.y, currentScale.z)); } else { // 英雄朝右,技能朝右(Scale.x为负) instance.setScale(new Vec3(-Math.abs(currentScale.x), currentScale.y, currentScale.z)); } // 添加到场景 this.node.addChild(instance); // 添加到激活技能列表 this.activeWanJianJueSkills.push(instance); // 添加伤害检测 this.scheduleOnce(() => { this.detectHengSaoDamage(position); }, 0.7); // 0.7秒后检测伤害 // 1.7秒后删除技能实例 this.scheduleOnce(() => { if (instance.isValid) { instance.destroy(); // 从激活列表中移除 const index = this.activeWanJianJueSkills.indexOf(instance); if (index !== -1) { this.activeWanJianJueSkills.splice(index, 1); } } }, 1.6667); } /** * 检测横扫千军伤害 * @param position 技能位置 */ private detectHengSaoDamage(position: Vec3): void { if (!this.gameManager) { console.warn("GameManager未设置,无法检测技能伤害"); return; } // 获取英雄朝向(Scale.x为正表示朝左,为负表示朝右) const heroScaleX = this.heroNode.scale.x; const isHeroFacingLeft = heroScaleX > 0; // 获取英雄位置 const heroPos = this.heroNode.position.clone(); // 定义伤害区域参数 const damageLength = 400; // 伤害区域长度(像素) const damageWidth = 200; // 伤害区域宽度(像素) const damageAmount = 80; // 伤害值80点 // 计算伤害区域边界 let minX: number, maxX: number; let minY: number, maxY: number; if (isHeroFacingLeft) { // 英雄朝左,伤害区域向左延伸 minX = heroPos.x - damageLength; maxX = heroPos.x; } else { // 英雄朝右,伤害区域向右延伸 minX = heroPos.x; maxX = heroPos.x + damageLength; } // Y轴范围(以英雄位置为中心) minY = heroPos.y - damageWidth / 2; maxY = heroPos.y + damageWidth / 2; // 获取所有怪物 const monsters = this.gameManager.getAllMonsters(); for (const monster of monsters) { if (!monster || !monster.isValid) continue; const controller = monster.getComponent(MonsterController); if (!controller || controller.isDie) continue; // 获取怪物位置 const monsterPos = monster.position; // 检查怪物是否在伤害区域内 const inXRange = monsterPos.x >= minX && monsterPos.x <= maxX; const inYRange = monsterPos.y >= minY && monsterPos.y <= maxY; if (inXRange && inYRange) { // 对怪物造成伤害 controller.takeDamage(damageAmount); } } } // 组件销毁时清理资源 protected onDestroy(): void { this.clearActiveSkills(); } }参考前面的万剑诀添加一个渡劫术功能,在预制体数组中获得一个名为DuJieShu-1的预制体,启动渡劫术时,将该预制体实例移动到距离英雄角色最近的怪物上,渡劫术预制体落点(放置位置)周围半径50像素的怪物收到80伤害(没有延迟,启动渡劫术后就判断有没有伤害),启动渡劫术后0.4667秒删除预制体实例

资源评论
用户头像
食色也
2025.06.30
标签中的ofx表明其易用性和兼容性。
用户头像
东郊椰林放猪散仙
2025.06.06
Monsters+OFX功能强大,适用于复杂的视觉效果制作。
用户头像
kdbshi
2025.02.25
该插件为nuke用户提供了更多的创意可能。
dog46572
  • 粉丝: 0
上传资源 快速赚钱