首页 > 其他分享 >Cocos Creator 2.x之通用计时器

Cocos Creator 2.x之通用计时器

时间:2023-12-24 18:00:50浏览次数:26  
标签:timerParam Cocos repeat Creator ICommonTimerParam private flag 计时器 itemTimer

一, 代码核心

1,CommonTimer.ts

/**
 * 通用计时器
 */
import {CommonTimerModeType, ICommonTimerInfo} from "./CommomTimerDefine";

export default class CommonTimerMgr extends cc.Component {
    public static instance: CommonTimerMgr;
    private timerList: ICommonTimerParam[];
    /**ms*/
    private localTime: number;
    private deleteList: ICommonTimerParam[];

    protected onl oad(): void {
        if (!CommonTimerMgr.instance) {
            this.init();
            CommonTimerMgr.instance = this;
        } else {
            CC_DEBUG && console.log(`[Fishdom] %cCommonTimerMgr 为单例类`, "color:#F00");
            this.destroy();
        }
    }

    private init(): void {
        this.timerList = [];
        this.deleteList = [];
        this.resetLocalTimer();
    }

    private resetIsExecOnceTrue(timerParam: ICommonTimerParam): void {
        if (!timerParam) return;
        !timerParam.isExecOnce && timerParam.isExecOnceMust && (timerParam.isExecOnce = true);
    }

    private addItemInfo(timerInfo: ICommonTimerInfo): void {
        let timerParam: ICommonTimerParam = timerInfo;
        if (timerInfo.repeat == undefined) {
            timerInfo.repeat = 1;
        }
        if (!timerParam.mode) {
            timerParam.mode = CommonTimerModeType.TIMER;
        }
        timerParam.isExecOnce = false;
        if (timerParam.mode == CommonTimerModeType.TIMER) {
            if (timerParam.isInitExec) {
                timerParam.callback.call(
                    timerParam.target,
                    timerParam.flag,
                    timerParam.duration,
                    false,
                    timerParam.callbackParam
                );
                this.resetIsExecOnceTrue(timerParam);
            }
            timerParam.startTime = this.localTime;
        }
        timerParam.curExecCnt = 0;
        this.timerList.push(timerParam);
    }
    /**
     * 添加一个计时器
     */
    public addTimer(data: ICommonTimerInfo): void {
        if (!cc.isValid(this.node)) return;
        if (!data || !data.callback || !data.target || !data.flag) {
            CC_DEBUG && console.log(`[Fishdom] %c Error添加计时器出错!`, "color:#F00");
            return;
        }
        if (CC_BUILD && data.flag.trim().length <= 0) {
            CC_DEBUG && console.log(`[Fishdom] %c Error 添加计时器flag参数不能为空!`, "color:#F00");
            return;
        }
        if (this.timerList.length == 0) {
            this.localTime = 0;
            this.addItemInfo(data);
        } else {
            let timerParam: ICommonTimerParam;
            for (let i: number = 0; i < this.timerList.length; i++) {
                timerParam = this.timerList[i];
                if (timerParam.flag == data.flag) {
                    this.doMuskExecFinal(timerParam);
                    this.timerList.splice(i, 1);
                    break;
                }
            }
            this.addItemInfo(data);
        }
    }

    private doMuskExecFinal(timerParam: ICommonTimerParam): void {
        if (!timerParam) return;
        if (!timerParam.isExecOnceMust || timerParam.isExecOnce) return;
        timerParam.callback.call(
            timerParam.target,
            timerParam.flag,
            timerParam.duration,
            true,
            timerParam.callbackParam
        );
    }

    /**
     * 删除计时器
     * @param flag null: 删除所有计时器(清空)
     * @param isCheckExecCnt 是否需要检查执行的次数
     */
    public removeTimer(flag: string, isCheckExecCnt: boolean = false): void {
        if (!this.timerList || this.timerList.length == 0) return;
        let itemTimer: ICommonTimerParam;
        for (let i: number = 0, j: number = this.timerList.length; i < j; i++) {
            itemTimer = this.timerList[i];
            if (flag != null && flag.trim().length > 0) {
                if (itemTimer.flag == flag) {
                    if (!isCheckExecCnt || itemTimer.repeat <= 0) {
                        this.doMuskExecFinal(itemTimer);
                        this.timerList.splice(i, 1);
                    } else {
                        if (itemTimer.curExecCnt >= itemTimer.repeat) {
                            this.doMuskExecFinal(itemTimer);
                            this.timerList.splice(i, 1);
                        }
                    }
                    break;
                }
            } else if (flag == null || flag.trim().length <= 0) {
                itemTimer = this.timerList[i];
                this.doMuskExecFinal(itemTimer);
                this.timerList.splice(i, 1);
                i--;
                j--;
            }
        }
        this.resetLocalTimer();
    }

    protected update(dt: number): void {
        if (!this.timerList || this.timerList.length <= 0) return;
        this.onTimerHandler.call(this, dt * 1000);
    }

    private onTimerHandler: (msDt: number) => void = (msDt) => {
        this.localTime += msDt;
        let itemTimer: ICommonTimerParam;
        let cloneArr: ICommonTimerParam[] = this.shallowCloneTimerList(this.timerList);
        if (cloneArr == null || cloneArr.length <= 0) {
            this.resetLocalTimer();
            return;
        }
        let asyncHandler: Promise<void>[] = [];
        for (let i: number = 0, j: number = cloneArr.length; i < j; i++) {
            itemTimer = this.timerList[i];
            asyncHandler.push(this.doTimerAsync(itemTimer, i, msDt));
        }
        Promise.all(asyncHandler).then(() => {
            if (
                !this.deleteList ||
                this.deleteList.length == 0 ||
                !this.timerList ||
                this.timerList.length == 0
            ) {
                this.resetLocalTimer();
                return;
            }

            let deleteArr: ICommonTimerParam[] = this.shallowCloneTimerList(this.deleteList);
            if (deleteArr != null && deleteArr.length > 0) {
                let item: ICommonTimerParam;
                for (let i: number = 0; i < deleteArr.length; i++) {
                    item = deleteArr[i];
                    this.removeTimer(item.flag, true);
                }
            }
            this.resetLocalTimer();
        });
    };

    private async doTimerAsync(
        itemTimer: ICommonTimerParam,
        i: number,
        msDt: number
    ): Promise<void> {
        return new Promise<void>((resolve) => {
            if (i == 0) this.deleteList.length = 0;
            if (itemTimer.mode == CommonTimerModeType.TIMER) {
                if (this.localTime - itemTimer.startTime < itemTimer.duration) {
                    resolve();
                    return;
                }
                if (itemTimer.repeat != null && itemTimer.repeat > 0) {
                    //非永久执行
                    itemTimer.curExecCnt += 1;
                    if (itemTimer.curExecCnt >= itemTimer.repeat) {
                        if (itemTimer.curExecCnt == itemTimer.repeat)
                            itemTimer.callback.call(
                                itemTimer.target,
                                itemTimer.flag,
                                itemTimer.duration,
                                true,
                                itemTimer.callbackParam
                            );
                        this.deleteList.push(itemTimer);
                        this.resetIsExecOnceTrue(itemTimer);
                    } else {
                        itemTimer.startTime = this.localTime;
                        itemTimer.callback.call(
                            itemTimer.target,
                            itemTimer.flag,
                            itemTimer.duration,
                            false,
                            itemTimer.callbackParam
                        );
                        this.resetIsExecOnceTrue(itemTimer);
                    }
                } else {
                    itemTimer.startTime = this.localTime;
                    itemTimer.callback.call(
                        itemTimer.target,
                        itemTimer.flag,
                        itemTimer.duration,
                        false,
                        itemTimer.callbackParam
                    ); //永久执行
                    this.resetIsExecOnceTrue(itemTimer);
                }
            } else if (itemTimer.mode == CommonTimerModeType.FRAME) {
                //非永久执行
                if (itemTimer.repeat != null && itemTimer.repeat > 0) {
                    itemTimer.curExecCnt += 1;
                    if (itemTimer.curExecCnt >= itemTimer.repeat) {
                        if (itemTimer.curExecCnt == itemTimer.repeat)
                            itemTimer.callback.call(
                                itemTimer.target,
                                itemTimer.flag,
                                msDt,
                                true,
                                itemTimer.callbackParam
                            );
                        this.deleteList.push(itemTimer);
                        this.resetIsExecOnceTrue(itemTimer);
                    } else {
                        itemTimer.callback.call(
                            itemTimer.target,
                            itemTimer.flag,
                            msDt,
                            false,
                            itemTimer.callbackParam
                        );
                        this.resetIsExecOnceTrue(itemTimer);
                    }
                } else {
                    itemTimer.callback.call(
                        itemTimer.target,
                        itemTimer.flag,
                        msDt,
                        false,
                        itemTimer.callbackParam
                    ); //永久执行
                    this.resetIsExecOnceTrue(itemTimer);
                }
            }
            resolve();
        });
    }

    private shallowCloneTimerList(list: ICommonTimerParam[]): ICommonTimerParam[] {
        if (list == null || list.length <= 0) return null;
        let arr: ICommonTimerParam[] = [];
        for (let i: number = 0; i < list.length; i++) {
            arr.push(list[i]);
        }
        return arr;
    }
    /**通用起点归0处理*/
    private resetLocalTimer(): void {
        if (this.timerList.length == 0) {
            this.localTime = 0;
        } else {
            let itemTimer: ICommonTimerParam;
            for (let i: number = 0; i < this.timerList.length; i++) {
                itemTimer = this.timerList[i];
                if (itemTimer.mode == CommonTimerModeType.TIMER) {
                    return; //存在时间计时器,不予处理
                }
            }
            this.localTime = 0;
        }
    }

    /**
     * 销毁计时器
     */
    public destroyTimer(): void {
        if (CommonTimerMgr.instance) {
            if (CommonTimerMgr.instance.node) {
                CommonTimerMgr.instance.node.removeComponent(this);
            }
            this.timerList = null;
            this.deleteList = null;
            CommonTimerMgr.instance = null;
        }
    }
}

interface ICommonTimerParam extends ICommonTimerInfo {
    /**已经执行的次数*/
    curExecCnt?: number;
    /**开始的时间毫秒(ms)*/
    startTime?: number;
    /**是否已经执行过一次(初次执行也算)*/
    isExecOnce?: boolean;
}

2, CommonTimerMgr

/**
 * 时间计时类型
 */
export const enum CommonTimerModeType {
    /**时间*/
    TIMER = "timer",
    /**帧*/
    FRAME = "frame",
}

/**
 * 计时器数据
 */
export interface ICommonTimerInfo {
    /**计时器唯一标签,作为计时器的key*/
    flag: string;
    /**计时器模式:默认: CommonTimerModeType.TIMER*/
    mode?: CommonTimerModeType;
    /**执行次数 <=0 : 永久执行 默认: 1次*/
    repeat?: number;
    /**是否初始化先执行一次(只对TIMER模式有效) 默认:false*/
    isInitExec?: boolean;
    /**回调函数 isComplete: 是否为结束回调*/
    callback: (flag: string, dt?: number, isComplete?: boolean, param?: any) => void;
    /**回调函数 This*/
    target: any;
    /**间隔时间毫秒(ms):(只对TIMER模式有效) */
    duration?: number;
    /**回调至少要执行一次?防止强制清理计时器,导致必要的动作没有执行:比如请求加分,默认false*/
    isExecOnceMust?: boolean;
    /**回调参数*/
    callbackParam?: any;
}

二,使用

1, 挂载到节点

this.node.addComponent(CommonTimerMgr);

2, 使用

    private addTimer(): void{
        CommonTimerMgr.instance.addTimer({
            flag: "timer_common",
            mode: CommonTimerModeType.TIMER,
            callback: this.onTimerHandler,
            target: this,
            duration: 1000,
            callbackParam: "demo param",
            repeat: 3
        });
    }

    private onTimerHandler(flag: string, dt: number, isComplete: boolean, data: any): void{
        switch (flag){
            case "timer_common":
                cc.log(`得到的参数: ${data}`);
                break;
        }
    }
    /**删除timer_common计时器*/
    private removeTime(): void{
        CommonTimerMgr.instance.removeTimer("timer_common");
    }

三, 结果

Cocos Creator 2.x之通用计时器_Cocos

标签:timerParam,Cocos,repeat,Creator,ICommonTimerParam,private,flag,计时器,itemTimer
From: https://blog.51cto.com/aonaufly/8956346

相关文章

  • Cocos Creator 2.x之ScrollView分层渲染
    一,场景设计1,ScrollViewPrefab:挂载ScrollViewPrefab脚本。2,ScrollViewPrefabItem:挂载ScrollViewPrefabItem脚本。是内容item。二,传统做法,加入30个item三,分层处理,加入30个item1,代码:CommomScrollViewCDconst{ccclass,property}=cc._decorator;//绘画层classDraw{......
  • Spring的Bean后置处理器之AnnotationAwareAspectJAutoProxyCreator
    本文能帮你回答以下几个问题;AnnotationAwareAspectJAutoProxyCreator后置器的作用是什么?SpringAOP自动增强bean是如何实现的。如何在spring上下文添加AnnotationAwareAspectJAutoProxyCreator?如何利用ProxyFactory硬编码实现一个bean的增强?AnnotationAwareAspectJAutoProx......
  • 【教程】步兵 cocos2dx 加密和混淆
    文章目录摘要引言正文代码加密具体步骤代码加密具体步骤测试和配置阶段IPA重签名操作步骤总结参考资料 摘要本篇博客介绍了针对iOS应用中的Lua代码进行加密和混淆的相关技术。通过对Lua代码进行加密处理,可以确保应用代码的安全性,同时提高性能表现。文......
  • 【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)
    【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)文章目录概述问题概述1.代码混淆代码加密具体步骤测试和配置阶段IPA重签名操作步骤2.缺乏文档3.缺乏推荐的最佳实践4.性能问题总结 概述Cocos2dx是一个非常流行的跨平台游戏引擎,开发者可以使用这个引擎来开......
  • 【教程】使用ipagurd打包与混淆Cocos2d-x的Lua脚本
    【教程】使用ipagurd打包与混淆Cocos2d-x的Lua脚本文章目录摘要引言正文1.准备工作2.使用ipaguard处理Lua文件3.运行ipagurd进行混淆代码加密具体步骤测试和配置阶段IPA重签名操作步骤4.IPA重签名与发布总结 摘要本文将介绍如何使用ipagurd工具对Cocos2d-......
  • 【教程】cocos2dx资源加密混淆方案详解
    ​ 【教程】cocos2dx资源加密混淆方案详解1,加密,采用blowfish或其他2,自定是32个字符的混淆code3,对文件做blowfish加密,入口文件加密前将混淆code按约定格式(自定义的文件头或文件尾部)写入到文件4,遍历资源目录,对每个文件做md5混淆,混淆原始串=“相对路径”+“文件名”+混......
  • centos 6.10 安装 qtCreator6.0.2
    centos6.10安装qtCreator6.0.2在centos6.10上源码编译安装qtCreator6.0.2下载地址下载后解压然后执行下面命令cdqt-creator-opensource-src-6.0.2mkdirbuild&&cdbuildcmake..makeset(CMAKE_PREFIX_PATH/home/fla/soft/qt5.15.11/lib/cmake/Qt5)SET(CMAKE......
  • cocoscreator使用总结
    1.背景图的大小超过父节点的大小,要使背景图不超过父节点,可以在父节点上增加一个mask组件2.layout组件可以设置垂直或水平布局,垂直时可以设从上到下或从下到上,水平布局可以设置从左向右,从右向左,可以方便用来设置文字在右下角之类的3.ScrollView的bar可以移除,view里面......
  • Cocos 飞机大战 (难点分析 制作)
    前言自己也写了3个cocos项目,觉得前面确实有点难,但是熟悉上手之后应该就是好多了,就是熟能生巧吧下面就是我的一个项目分析和难点  就是我们常玩的打飞机先看下效果图我在手机上的截图 就是拖到触屏飞机进行射击和躲避子弹,感觉还行吧哈哈难点 1.就是物体直接......
  • cocos creator ScrollView不滚动问题
    拖放默认的ScrollView可以,可以滚动显示文字,结构如下:ScrollView scrollBar(滚动条结点,不显示滚动条时,可直接删除,删除后把ScrollView里面的VertticalScrollBar值清了) bar view(视图结点) content item(具体文本)content......