scheduleOnce的注意事项

博客内容讲述了关于使用`scheduleOnce`方法时的注意事项,强调了执行顺序。在指定延迟时间0.8秒后,代码会执行一系列操作,包括添加Cell对象和检查稳定状态。若满足特定条件,将调用`_dongzuo2`函数,并提到了如何调整scheduleOnce的执行顺序来确保正确执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

this.scheduleOnce(function () {
    for (var i = 0; i < WN; i++) {
        for (var j = 0; j < HN; j++) {
            if(this._arr[i][j] == null){
                var sp = new Cell();
                sp.setPosition(cc.winSize.width - 575 + (40 * i), cc.winSize.height - 60 - (40 * j));
                this.addChild(sp);
                sp.setArrIndex(i, j);
                this._arr[i][j] = sp

            }
        }
    }
    var end = this._bianli();
    if(end.length < 1){             
        cc.log("稳定状态")
    }else{
        this.scheduleOnce(function(){ 
            this._dongzuo2(end)    
        },0.52)
    }
},0.8)

注意! scheduleOnce方法会先执行时间后面的代码,如果想要先执行scheduleOnce,可以把后面的代码放在scheduleOnce
如果有两个scheduleOnce,它也会先执行后面的那个scheduleOnce如果需要先执行前面的,可以把后面的scheduleOnce放在前面的里面,如上面代码

import { _decorator, Component, Animation, Node, director } from 'cc'; const { ccclass, property } = _decorator; @ccclass('BossWarningManager') export class BossWarningManager extends Component { private static _instance: BossWarningManager | null = null; @property(Node) private bossWarningNode: Node | null = null; // BossWarning节点引用 private bossAnim: Animation | null = null; // BossWarning节点的动画组件缓存 private bgAnim: Animation | null = null; // BossWarningBG2子节点的动画组件缓存 // 获取单例实例 public static get instance(): BossWarningManager { if (!BossWarningManager._instance) { // 创建单例节点 const node = new Node('BossWarningManager'); director.getScene().addChild(node); BossWarningManager._instance = node.addComponent(BossWarningManager); // 设置为常驻节点,切换场景时不会被销毁 director.addPersistRootNode(node); } return BossWarningManager._instance; } onLoad() { // 确保单例唯一性 if (BossWarningManager._instance && BossWarningManager._instance !== this) { this.node.destroy(); return; } BossWarningManager._instance = this; // 初始化动画组件 if (this.bossWarningNode) { // 缓存BossWarning节点自身的动画组件 this.bossAnim = this.bossWarningNode.getComponent(Animation); // 缓存BossWarningBG2子节点的动画组件 const bossWarningBG2 = this.bossWarningNode.getChildByName('BossWarningBG2'); if (bossWarningBG2) { this.bgAnim = bossWarningBG2.getComponent(Animation); } } } // 显示Boss警告并播放动画 public showBossWarning(): void { if (!this.bossWarningNode) return; // 启用节点 this.bossWarningNode.active = true; // 播放背景动画 if (this.bgAnim) { this.bgAnim.play('BossWarningBG'); } // 播放主警告动画 if (this.bossAnim) { // 立即播放第一个动画 this.bossAnim.play('BossWarning1'); // 0.45秒后播放第二个动画 this.scheduleOnce(() => { this.bossAnim?.play('BossWarning2'); }, 0.45); } } // 隐藏Boss警告 public hideBossWarning(): void { if (this.bossWarningNode) { this.bossWarningNode.active = false; } } } 隐藏警告时要注意将设置初始化,以免下次调用的会有冲突
最新发布
08-13
// 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秒删除预制体实例
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值