CocosCreator 源码cc.Sequence详解

欢迎关注公众号:“Cocos Creator 源码讲解”,一起学习。

/**
 * @module cc
 */

/*
 * Runs actions sequentially, one after another.
 * @class Sequence
 * @extends ActionInterval
 * @param {Array|FiniteTimeAction} tempArray
 * @example
 * // create sequence with actions
 * var seq = new cc.Sequence(act1, act2);
 *
 * // create sequence with array
 * var seq = new cc.Sequence(actArray);
 */
/* 按顺序、一个接一个地运行操作。 */
cc.Sequence = cc.Class({
    name: 'cc.Sequence',
    extends: cc.ActionInterval,

    /* 构造函数 */
    ctor: function (tempArray) {
        /* 存储action到数组 */
        this._actions = [];
        this._split = null;
        this._last = 0;
        this._reversed = false;

        /* sequance 的参数,必须有length属性,array类型的话直接用这个参数,假如不是,直接用arguments */
        var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
        if (paramArray.length === 1) {
            /* Failed to construct, Sequence construction needs two or more actions. */
            cc.errorID(1019);
            return;
        }
        /* 参数array长度-1,最后一个位置的下标 */
        var last = paramArray.length - 1;
        if ((last >= 0) && (paramArray[last] == null))
            /* parameters should not be ending with null in Javascript 最后一个参数不能为空 */
            cc.logID(1015);

        if (last >= 0) {
            /* 获取第一个action,定义为pre;声明一个action1 变量 */
            var prev = paramArray[0], action1;
            for (var i = 1; i < last; i++) {
                if (paramArray[i]) {
                    action1 = prev;
                    /*_actionOneTwo返回一个新sequence,  */
                    prev = cc.Sequence._actionOneTwo(action1, paramArray[i]);
                }
            }
            /* 初始化最后一个和倒数第二个 action */
            this.initWithTwoActions(prev, paramArray[last]);
        }
    },

    /*
     * Initializes the action <br/>
     * @param {FiniteTimeAction} actionOne
     * @param {FiniteTimeAction} actionTwo
     * @return {Boolean}
     */
    /* 初始化的时候,有两个参数的情况 */
    initWithTwoActions: function (actionOne, actionTwo) {
        /* 两个action必须都不为空 */
        if (!actionOne || !actionTwo) {
            cc.errorID(1025);
            return false;
        }
        /* 第一个action 和第二个action的运行时间 */
        var durationOne = actionOne._duration, durationTwo = actionTwo._duration;
        /* 假如存在循环次数,则分别获取总共需要消耗的时间 */
        durationOne *= actionOne._repeatMethod ? actionOne._timesForRepeat : 1;
        durationTwo *= actionTwo._repeatMethod ? actionTwo._timesForRepeat : 1;
        /* 两个action的总时间 */
        var d = durationOne + durationTwo;
        /* 初始化父类参数,总共时间属性 */
        this.initWithDuration(d);
        /* 存储两个action */
        this._actions[0] = actionOne;
        this._actions[1] = actionTwo;
        return true;
    },
    /* 复制一个队列 */
    clone: function () {
        var action = new cc.Sequence();
        this._cloneDecoration(action);
        action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone());
        return action;
    },

    /* 执行startWithTarget */
    startWithTarget: function (target) {
        /* cc.Sequence[this] 调用 cc.ActionInterval的startWithTarget function ,参数为 target*/
        cc.ActionInterval.prototype.startWithTarget.call(this, target);
        /* 第一个action占用总时间的比例 */
        this._split = this._actions[0]._duration / this._duration;
        /* 这个action的单个占用比例,乘以次数,就是总共占用时间的比例 */
        this._split *= this._actions[0]._repeatMethod ? this._actions[0]._timesForRepeat : 1;
        this._last = -1;
    },

    /* 停止action队列 */
    stop: function () {
        // Issue #1305
        /* 还没有播放完毕的时候 */
        if (this._last !== -1)/* 获取当前正在播放的action进行stop */
            this._actions[this._last].stop();
        cc.Action.prototype.stop.call(this);
    },
    /* 每帧更新 */
    update: function (dt) {
        /*声明变量new_t, found  */
        var new_t, found = 0;
        /* 获取分割时间, 声明变量locActions, locLast actionFound */
        var locSplit = this._split, locActions = this._actions, locLast = this._last, actionFound;

        dt = this._computeEaseTime(dt);
        if (dt < locSplit) {
            // action[0]
            new_t = (locSplit !== 0) ? dt / locSplit : 1;

            if (found === 0 && locLast === 1 && this._reversed) {
                // Reverse mode ?
                // XXX: Bug. this case doesn't contemplate when _last==-1, found=0 and in "reverse mode"
                // since it will require a hack to know if an action is on reverse mode or not.
                // "step" should be overriden, and the "reverseMode" value propagated to inner Sequences.
                locActions[1].update(0);
                locActions[1].stop();
            }
        } else {
            // action[1]
            found = 1;
            new_t = (locSplit === 1) ? 1 : (dt - locSplit) / (1 - locSplit);

            if (locLast === -1) {
                // action[0] was skipped, execute it.//action[0] 被跳过,执行它。
                locActions[0].startWithTarget(this.target);
                locActions[0].update(1);
                locActions[0].stop();
            }
            if (locLast === 0) {
                // switching to action 1. stop action 0.// 切换到动作 1。停止动作 0。
                locActions[0].update(1);
                locActions[0].stop();
            }
        }

        actionFound = locActions[found];
        // Last action found and it is done.
        /* // 找到最后一个操作并完成。 */
        if (locLast === found && actionFound.isDone())
            return;

        // Last action not found// 未找到最后一个操作
        if (locLast !== found)
            actionFound.startWithTarget(this.target);

        new_t = new_t * actionFound._timesForRepeat;
        actionFound.update(new_t > 1 ? new_t % 1 : new_t);
        this._last = found;
    },

    /* 翻转动作序列 */
    reverse: function () {
        var action = cc.Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse());
        this._cloneDecoration(action);
        this._reverseEaseList(action);
        action._reversed = true;
        return action;
    }
});

/**
 * !#en
 * Helper constructor to create an array of sequenceable actions
 * The created action will run actions sequentially, one after another.
 * !#zh 顺序执行动作,创建的动作将按顺序依次运行。
 * @method sequence
 * @param {FiniteTimeAction|FiniteTimeAction[]} actionOrActionArray
 * @param {FiniteTimeAction} ...tempArray
 * @return {ActionInterval}
 * @example
 * // example
 * // create sequence with actions
 * var seq = cc.sequence(act1, act2);
 *
 * // create sequence with array
 * var seq = cc.sequence(actArray);
 */
// todo: It should be use new
cc.sequence = function (/*Multiple Arguments*/tempArray) {
    /*paramArray 假如是数组类型,直接适用,假如不是,用arguments属性,  */
    var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
    /* 长度为1的时候报错 */
    if (paramArray.length === 1) {
        cc.errorID(1019);
        return null;
    }
    /* 最后一个index */
    var last = paramArray.length - 1;
    /* 大于一个参数,并且最后一个内容为空的话,报错 */
    if ((last >= 0) && (paramArray[last] == null))
        cc.logID(1015);

    var result = null;
    /* 大于一个参数,直接遍历 */
    if (last >= 0) {
        result = paramArray[0];
        for (var i = 1; i <= last; i++) {
            if (paramArray[i]) {
                /* 遍历生成sequence */
                result = cc.Sequence._actionOneTwo(result, paramArray[i]);
            }
        }
    }

    return result;
};

/* 初始化-两个action */
cc.Sequence._actionOneTwo = function (actionOne, actionTwo) {
    var sequence = new cc.Sequence();
    sequence.initWithTwoActions(actionOne, actionTwo);
    return sequence;
};

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值