• cocos2d-html5 笔记5: 事件


    在cocos2d里面,通过Node的方式,将整个场景以及里面的object给组织起来,这样很容易画了,从root node开始遍历,把整棵树画出来就是了. 剩下就是animation,timer, 还有mouse, touch,keyboard的 事件的处理。在cocos2d里面提供了三个模块来管理这些,schedule负责timer和 animation的驱动,Action则负责改变对象的参数实现一些动画效果。还有event dispatcher负责事件的分发.

    Schedule

    cocos2d里面的scheduler用于管理时间的调度(timeout的回调),同时这个schedule也驱动着整个游戏,让游戏能够跑动起来.

    在前面的关于director笔记里面, 在Application run的时候,就是注册了一个timer,然后以一定的帧率去调用director的DrawScrene函数。这样能够保持游戏的画面不断的更新。

    Application.run -->SetInterval(Director.mainloop, animationInterval)
    
    Director.mainloop --> Director.drawScrene --> Director.runningScrene.vist()
    

    在游戏里面除了要不断的更新画面以外,还要更新游戏中的一些数据和状态(比如游戏里面游戏主题位置,场景的滚动之类的),还有一些动画效果,也要 定时的更新物体的的一些参数,好让物体动起来。

    所以cocos2d里面就提供了schedule来管理time的调度, 在drawScene的每里面,也就是游戏的每一帧里面都会调用scheduler 的update。

    //function in class Director
    drawScene:function () {
        // calculate "global" dt
        this.calculateDeltaTime();
    
        if (!this._paused)
            this._scheduler.update(this._deltaTime);
        //other codes
    

    在CCScheduler.js里面提供了两个class, 一个是Timer, timer负责回调函数和时间的计算,另外一个是Scheduler,它负责管理Timer的实例。 所以当注册了一个timerout的函数之后,它的回调函数被调用的流程如下:

    drawScene --> scheduler.update(delta_time) --> Timer.update --> Timer.callSelector --> timer.selector.call(target, elapsed_time)
    

    在Timer.update里面会判断是不是timerout了,如果是的话,就去调用回调函数, 否则就啥都不干。

    在scheduler还提供了priority来调用timer的回调函数, priority越小,越被早调到。scheduler里面有三个updateList: updatesNegList, update0List, updatePosList; 在scheduler update的时候,会去分别遍历这三个list, 调用里面每个元素的update, 之后检查如果元素被markForDeletion的话,就把它从list中去掉。schedule中还提供了 Hash方便timer的查找。

    在Node里面提供了schedule相关的函数, schedule, unschedule, scheduleUpdate, unscheduleUpdate, unscheduleAllCallbacks, scheduleOnce。这一族函数就是 在schedule的基础上做一些封装,target就是Node的this.

    //function in class Node
    schedule:function (callback_fn, interval, repeat, delay) {
        interval = interval || 0;
    
        cc.Assert(callback_fn, "Argument must be non-nil");
        cc.Assert(interval >= 0, "Argument must be positive");
    
        repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat;
        delay = delay || 0;
    
        this.getScheduler().scheduleCallbackForTarget(this, callback_fn, interval, repeat, delay, !this._running);
    }
    

    感觉最常用的是schedule和scheduleUpdate, sheduleUpdate这个会在每一帧去回调Node的update函数。

    Action

    Action用于实现一些动画效果。所谓的的动画效果就是改变Node的一些参数。 Action的基类对象里面有target,和tag, tag用于便于ActionManager管理Action, 然后target就指向要需要改变的对象.

    cc.Action = cc.Class.extend(/** @lends cc.Action# */{
        //***********variables*************
        _originalTarget:null,
        _target:null,
        _tag:cc.ACTION_TAG_INVALID,
    

    在cocos2d里面action是这样跑起来的,首先在director初始化的时候会将actionManager放到schedule里面:

        //in function Director.init
            this._scheduler = new cc.Scheduler();
            //action manager
            this._actionManager = new cc.ActionManager();
            this._scheduler.scheduleUpdateForTarget(this._actionManager, cc.PRIORITY_SYSTEM, false);
    

    这样每一帧就会去调用actionManager的update. 在ActionManager里面会遍历所有的action,然后调用action的step, 之后如果 action isDone的话,就把action从list中去掉。 调用流程如下:

    Director.drawScrene -->schedule.update --> ActionManager.Update --> action.step
    

    然后在Node里面runAction函数,会把action添加到ActionManager里面

    //in class Node
    runAction:function (action) {
        cc.Assert(action != null, "Argument must be non-nil");
        this.getActionManager().addAction(action, this, !this._running);
        return action;
    }
    

    在Node里面还提供了action的其他函数, stopAction, stopAllAction, stopActionByTag, getActionByTag, 这些也都是对ActionManager的相应函数的封装。

    Event dispatcher

    在cocos2d里面的touch, mouse等事件的处理还是很清晰的。以mouse 为例

    System event  -->  MouseDispatchter --> MouseDelegate
    

    如果要处理mouse事件的话,首先实现MouseEventDelegate这个接口,然后在调用MouseDispahter的addMouseDelegate方法将自己加进去。 在MouseDispatcher收到系统事件后,它会遍历所有注册的delegate,然后去调用相应的方法.

    具体的例子可以看CClayer, CCLayer在onEnter的时候,把自己注册到MouseDispahter里面,然后在onExit的时候取消注册

  • 相关阅读:
    Vue异步数据交互 promise axios async fetch
    JS数组或对象转为JSON字符换 JavaScript JSON.stringify()
    JS返回数组的最大值与最小值
    Error: Cannot find module './application'
    Express框架
    NodeJS项目制作流程
    模板引擎art-template
    基于NodeJS的网络响应原理与HTTP协议
    leetcode 953. 验证外星语词典 做题笔记
    leetcode 771. 宝石与石头 做题笔记
  • 原文地址:https://www.cnblogs.com/zhepama/p/3167537.html
Copyright © 2020-2023  润新知