mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 15:05:24 +00:00
初始化
This commit is contained in:
582
engine/cocos2d/actions/CCAction.js
Normal file
582
engine/cocos2d/actions/CCAction.js
Normal file
@@ -0,0 +1,582 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
require('../core/platform/CCClass');
|
||||
const misc = require('../core/utils/misc');
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/**
|
||||
* !#en Base class cc.Action for action classes.
|
||||
* !#zh Action 类是所有动作类型的基类。
|
||||
* @class Action
|
||||
*/
|
||||
cc.Action = cc.Class({
|
||||
name: 'cc.Action',
|
||||
|
||||
//**************Public Functions***********
|
||||
|
||||
ctor:function () {
|
||||
this.originalTarget = null;
|
||||
this.target = null;
|
||||
this.tag = cc.Action.TAG_INVALID;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* to copy object with deep copy.
|
||||
* returns a clone of action.
|
||||
* !#zh 返回一个克隆的动作。
|
||||
* @method clone
|
||||
* @return {Action}
|
||||
*/
|
||||
clone:function () {
|
||||
var action = new cc.Action();
|
||||
action.originalTarget = null;
|
||||
action.target = null;
|
||||
action.tag = this.tag;
|
||||
return action;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* return true if the action has finished.
|
||||
* !#zh 如果动作已完成就返回 true。
|
||||
* @method isDone
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isDone:function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
// called before the action start. It will also set the target.
|
||||
startWithTarget:function (target) {
|
||||
this.originalTarget = target;
|
||||
this.target = target;
|
||||
},
|
||||
|
||||
// called after the action has finished. It will set the 'target' to nil.
|
||||
stop:function () {
|
||||
this.target = null;
|
||||
},
|
||||
|
||||
// called every frame with it's delta time. <br />
|
||||
step:function (dt) {
|
||||
cc.logID(1006);
|
||||
},
|
||||
|
||||
// Called once per frame. Time is the number of seconds of a frame interval.
|
||||
update:function (dt) {
|
||||
cc.logID(1007);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en get the target.
|
||||
* !#zh 获取当前目标节点。
|
||||
* @method getTarget
|
||||
* @return {Node}
|
||||
*/
|
||||
getTarget:function () {
|
||||
return this.target;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en The action will modify the target properties.
|
||||
* !#zh 设置目标节点。
|
||||
* @method setTarget
|
||||
* @param {Node} target
|
||||
*/
|
||||
setTarget:function (target) {
|
||||
this.target = target;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en get the original target.
|
||||
* !#zh 获取原始目标节点。
|
||||
* @method getOriginalTarget
|
||||
* @return {Node}
|
||||
*/
|
||||
getOriginalTarget:function () {
|
||||
return this.originalTarget;
|
||||
},
|
||||
|
||||
// Set the original target, since target can be nil.
|
||||
// Is the target that were used to run the action.
|
||||
// Unless you are doing something complex, like cc.ActionManager, you should NOT call this method.
|
||||
setOriginalTarget:function (originalTarget) {
|
||||
this.originalTarget = originalTarget;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en get tag number.
|
||||
* !#zh 获取用于识别动作的标签。
|
||||
* @method getTag
|
||||
* @return {Number}
|
||||
*/
|
||||
getTag:function () {
|
||||
return this.tag;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en set tag number.
|
||||
* !#zh 设置标签,用于识别动作。
|
||||
* @method setTag
|
||||
* @param {Number} tag
|
||||
*/
|
||||
setTag:function (tag) {
|
||||
this.tag = tag;
|
||||
},
|
||||
|
||||
// Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
|
||||
// and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
|
||||
// This is a hack, and should be removed once JSB fixes the retain/release bug.
|
||||
retain:function () {
|
||||
},
|
||||
|
||||
// Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
|
||||
// and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
|
||||
// This is a hack, and should be removed once JSB fixes the retain/release bug.
|
||||
release:function () {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Default Action tag.
|
||||
* !#zh 默认动作标签。
|
||||
* @property TAG_INVALID
|
||||
* @constant
|
||||
* @static
|
||||
* @type {Number}
|
||||
* @default -1
|
||||
*/
|
||||
cc.Action.TAG_INVALID = -1;
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Base class actions that do have a finite time duration. <br/>
|
||||
* Possible actions: <br/>
|
||||
* - An action with a duration of 0 seconds. <br/>
|
||||
* - An action with a duration of 35.5 seconds.
|
||||
*
|
||||
* Infinite time actions are valid
|
||||
* !#zh 有限时间动作,这种动作拥有时长 duration 属性。
|
||||
* @class FiniteTimeAction
|
||||
* @extends Action
|
||||
*/
|
||||
cc.FiniteTimeAction = cc.Class({
|
||||
name: 'cc.FiniteTimeAction',
|
||||
extends: cc.Action,
|
||||
|
||||
ctor:function () {
|
||||
//! duration in seconds
|
||||
this._duration = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en get duration of the action. (seconds).
|
||||
* !#zh 获取动作以秒为单位的持续时间。
|
||||
* @method getDuration
|
||||
* @return {Number}
|
||||
*/
|
||||
getDuration:function () {
|
||||
return this._duration * (this._timesForRepeat || 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en set duration of the action. (seconds).
|
||||
* !#zh 设置动作以秒为单位的持续时间。
|
||||
* @method setDuration
|
||||
* @param {Number} duration
|
||||
*/
|
||||
setDuration:function (duration) {
|
||||
this._duration = duration;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Returns a reversed action. <br />
|
||||
* For example: <br />
|
||||
* - The action will be x coordinates of 0 move to 100. <br />
|
||||
* - The reversed action will be x of 100 move to 0.
|
||||
* - Will be rewritten
|
||||
* !#zh 返回一个新的动作,执行与原动作完全相反的动作。
|
||||
* @method reverse
|
||||
* @return {Null}
|
||||
*/
|
||||
reverse:function () {
|
||||
cc.logID(1008);
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* to copy object with deep copy.
|
||||
* returns a clone of action.
|
||||
* !#zh 返回一个克隆的动作。
|
||||
* @method clone
|
||||
* @return {FiniteTimeAction}
|
||||
*/
|
||||
clone:function () {
|
||||
return new cc.FiniteTimeAction();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changes the speed of an action, making it take longer (speed > 1)
|
||||
* or less (speed < 1) time. <br/>
|
||||
* Useful to simulate 'slow motion' or 'fast forward' effect.
|
||||
*
|
||||
* @warning This action can't be Sequenceable because it is not an cc.IntervalAction
|
||||
* @class Speed
|
||||
* @extends Action
|
||||
*
|
||||
* @param {ActionInterval} action
|
||||
* @param {Number} speed
|
||||
*/
|
||||
cc.Speed = cc.Class({
|
||||
name: 'cc.Speed',
|
||||
extends: cc.Action,
|
||||
|
||||
ctor:function (action, speed) {
|
||||
this._speed = 0;
|
||||
this._innerAction = null;
|
||||
|
||||
action && this.initWithAction(action, speed);
|
||||
},
|
||||
|
||||
/*
|
||||
* Gets the current running speed. <br />
|
||||
* Will get a percentage number, compared to the original speed.
|
||||
*
|
||||
* @method getSpeed
|
||||
* @return {Number}
|
||||
*/
|
||||
getSpeed:function () {
|
||||
return this._speed;
|
||||
},
|
||||
|
||||
/*
|
||||
* alter the speed of the inner function in runtime.
|
||||
* @method setSpeed
|
||||
* @param {Number} speed
|
||||
*/
|
||||
setSpeed:function (speed) {
|
||||
this._speed = speed;
|
||||
},
|
||||
|
||||
/*
|
||||
* initializes the action.
|
||||
* @method initWithAction
|
||||
* @param {ActionInterval} action
|
||||
* @param {Number} speed
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithAction:function (action, speed) {
|
||||
if (!action) {
|
||||
cc.errorID(1021);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._innerAction = action;
|
||||
this._speed = speed;
|
||||
return true;
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var action = new cc.Speed();
|
||||
action.initWithAction(this._innerAction.clone(), this._speed);
|
||||
return action;
|
||||
},
|
||||
|
||||
startWithTarget:function (target) {
|
||||
cc.Action.prototype.startWithTarget.call(this, target);
|
||||
this._innerAction.startWithTarget(target);
|
||||
},
|
||||
|
||||
stop:function () {
|
||||
this._innerAction.stop();
|
||||
cc.Action.prototype.stop.call(this);
|
||||
},
|
||||
|
||||
step:function (dt) {
|
||||
this._innerAction.step(dt * this._speed);
|
||||
},
|
||||
|
||||
isDone:function () {
|
||||
return this._innerAction.isDone();
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.Speed(this._innerAction.reverse(), this._speed);
|
||||
},
|
||||
|
||||
/*
|
||||
* Set inner Action.
|
||||
* @method setInnerAction
|
||||
* @param {ActionInterval} action
|
||||
*/
|
||||
setInnerAction:function (action) {
|
||||
if (this._innerAction !== action) {
|
||||
this._innerAction = action;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Get inner Action.
|
||||
* @method getInnerAction
|
||||
* @return {ActionInterval}
|
||||
*/
|
||||
getInnerAction:function () {
|
||||
return this._innerAction;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Creates the speed action which changes the speed of an action, making it take longer (speed > 1)
|
||||
* or less (speed < 1) time. <br/>
|
||||
* Useful to simulate 'slow motion' or 'fast forward' effect.
|
||||
* !#zh 修改目标动作的速率。
|
||||
* @warning This action can't be Sequenceable because it is not an cc.IntervalAction
|
||||
*
|
||||
* @method speed
|
||||
* @param {ActionInterval} action
|
||||
* @param {Number} speed
|
||||
* @return {Action}
|
||||
* @example
|
||||
* // change the target action speed;
|
||||
* var action = cc.scaleTo(0.2, 1, 0.6);
|
||||
* var newAction = cc.speed(action, 0.5);
|
||||
*/
|
||||
cc.speed = function (action, speed) {
|
||||
return new cc.Speed(action, speed);
|
||||
};
|
||||
|
||||
/*
|
||||
* cc.Follow is a follow action which makes its target follows another node.
|
||||
*
|
||||
* @example
|
||||
* //example
|
||||
* //Instead of using cc.Camera as a "follower", use this action instead.
|
||||
* layer.runAction(cc.follow(hero));
|
||||
*
|
||||
* @property {Number} leftBoundary - world leftBoundary.
|
||||
* @property {Number} rightBoundary - world rightBoundary.
|
||||
* @property {Number} topBoundary - world topBoundary.
|
||||
* @property {Number} bottomBoundary - world bottomBoundary.
|
||||
*
|
||||
* @param {cc.Node} followedNode
|
||||
* @param {Rect} rect
|
||||
* @example
|
||||
* // creates the action with a set boundary
|
||||
* var followAction = new cc.Follow(node, cc.rect(0, 0, s.width * 2 - 100, s.height));
|
||||
* this.runAction(followAction);
|
||||
*
|
||||
* // creates the action with no boundary set
|
||||
* var followAction = new cc.Follow(node);
|
||||
* this.runAction(followAction);
|
||||
*
|
||||
* @class
|
||||
* @extends Action
|
||||
*/
|
||||
cc.Follow = cc.Class({
|
||||
name: 'cc.Follow',
|
||||
extends: cc.Action,
|
||||
|
||||
/*
|
||||
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. <br />
|
||||
* creates the action with a set boundary. <br/>
|
||||
* creates the action with no boundary set.
|
||||
* @param {cc.Node} followedNode
|
||||
* @param {Rect} rect
|
||||
*/
|
||||
ctor:function (followedNode, rect) {
|
||||
// node to follow
|
||||
this._followedNode = null;
|
||||
// whether camera should be limited to certain area
|
||||
this._boundarySet = false;
|
||||
// if screen size is bigger than the boundary - update not needed
|
||||
this._boundaryFullyCovered = false;
|
||||
// fast access to the screen dimensions
|
||||
this._halfScreenSize = null;
|
||||
this._fullScreenSize = null;
|
||||
|
||||
this.leftBoundary = 0.0;
|
||||
this.rightBoundary = 0.0;
|
||||
this.topBoundary = 0.0;
|
||||
this.bottomBoundary = 0.0;
|
||||
this._worldRect = cc.rect(0, 0, 0, 0);
|
||||
|
||||
if(followedNode)
|
||||
rect ? this.initWithTarget(followedNode, rect)
|
||||
: this.initWithTarget(followedNode);
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var action = new cc.Follow();
|
||||
var locRect = this._worldRect;
|
||||
var rect = new cc.Rect(locRect.x, locRect.y, locRect.width, locRect.height);
|
||||
action.initWithTarget(this._followedNode, rect);
|
||||
return action;
|
||||
},
|
||||
|
||||
/*
|
||||
* Get whether camera should be limited to certain area.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isBoundarySet:function () {
|
||||
return this._boundarySet;
|
||||
},
|
||||
|
||||
/*
|
||||
* alter behavior - turn on/off boundary.
|
||||
*
|
||||
* @param {Boolean} value
|
||||
*/
|
||||
setBoundarySet:function (value) {
|
||||
this._boundarySet = value;
|
||||
},
|
||||
|
||||
/*
|
||||
* alter behavior - turn on/off boundary.
|
||||
*
|
||||
* @param {Boolean} value
|
||||
* @deprecated since v2.4.6 , cc.Follow.setBoudarySet is deprecated, please use cc.Follow.setBoundarySet.
|
||||
*/
|
||||
setBoudarySet:function (value) {
|
||||
this.setBoundarySet(value);
|
||||
},
|
||||
|
||||
/*
|
||||
* initializes the action with a set boundary.
|
||||
*
|
||||
* @param {cc.Node} followedNode
|
||||
* @param {Rect} [rect=]
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithTarget:function (followedNode, rect) {
|
||||
if (!followedNode) {
|
||||
cc.errorID(1022);
|
||||
return false;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
rect = rect || cc.rect(0, 0, 0, 0);
|
||||
_this._followedNode = followedNode;
|
||||
_this._worldRect = rect;
|
||||
|
||||
_this._boundarySet = !(rect.width === 0 && rect.height === 0);
|
||||
|
||||
_this._boundaryFullyCovered = false;
|
||||
|
||||
var winSize = cc.winSize;
|
||||
_this._fullScreenSize = cc.v2(winSize.width, winSize.height);
|
||||
_this._halfScreenSize = _this._fullScreenSize.mul(0.5);
|
||||
|
||||
if (_this._boundarySet) {
|
||||
_this.leftBoundary = -((rect.x + rect.width) - _this._fullScreenSize.x);
|
||||
_this.rightBoundary = -rect.x;
|
||||
_this.topBoundary = -rect.y;
|
||||
_this.bottomBoundary = -((rect.y + rect.height) - _this._fullScreenSize.y);
|
||||
|
||||
if (_this.rightBoundary < _this.leftBoundary) {
|
||||
// screen width is larger than world's boundary width
|
||||
//set both in the middle of the world
|
||||
_this.rightBoundary = _this.leftBoundary = (_this.leftBoundary + _this.rightBoundary) / 2;
|
||||
}
|
||||
if (_this.topBoundary < _this.bottomBoundary) {
|
||||
// screen width is larger than world's boundary width
|
||||
//set both in the middle of the world
|
||||
_this.topBoundary = _this.bottomBoundary = (_this.topBoundary + _this.bottomBoundary) / 2;
|
||||
}
|
||||
|
||||
if ((_this.topBoundary === _this.bottomBoundary) && (_this.leftBoundary === _this.rightBoundary))
|
||||
_this._boundaryFullyCovered = true;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
step:function (dt) {
|
||||
var targetWorldPos = this.target.convertToWorldSpaceAR(cc.Vec2.ZERO);
|
||||
var followedWorldPos = this._followedNode.convertToWorldSpaceAR(cc.Vec2.ZERO);
|
||||
// compute the offset between followed and target node
|
||||
var delta = targetWorldPos.sub(followedWorldPos);
|
||||
var tempPos = this.target.parent.convertToNodeSpaceAR(delta.add(this._halfScreenSize));
|
||||
|
||||
if (this._boundarySet) {
|
||||
// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
|
||||
if (this._boundaryFullyCovered)
|
||||
return;
|
||||
|
||||
this.target.setPosition(misc.clampf(tempPos.x, this.leftBoundary, this.rightBoundary), misc.clampf(tempPos.y, this.bottomBoundary, this.topBoundary));
|
||||
} else {
|
||||
this.target.setPosition(tempPos.x, tempPos.y);
|
||||
}
|
||||
},
|
||||
|
||||
isDone:function () {
|
||||
return ( !this._followedNode.activeInHierarchy );
|
||||
},
|
||||
|
||||
stop:function () {
|
||||
this.target = null;
|
||||
cc.Action.prototype.stop.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Create a follow action which makes its target follows another node.
|
||||
* !#zh 追踪目标节点的位置。
|
||||
* @method follow
|
||||
* @param {Node} followedNode
|
||||
* @param {Rect} rect
|
||||
* @return {Action|Null} returns the cc.Follow object on success
|
||||
* @example
|
||||
* // example
|
||||
* // creates the action with a set boundary
|
||||
* var followAction = cc.follow(targetNode, cc.rect(0, 0, screenWidth * 2 - 100, screenHeight));
|
||||
* node.runAction(followAction);
|
||||
*
|
||||
* // creates the action with no boundary set
|
||||
* var followAction = cc.follow(targetNode);
|
||||
* node.runAction(followAction);
|
||||
*/
|
||||
cc.follow = function (followedNode, rect) {
|
||||
return new cc.Follow(followedNode, rect);
|
||||
};
|
446
engine/cocos2d/actions/CCActionCatmullRom.js
Normal file
446
engine/cocos2d/actions/CCActionCatmullRom.js
Normal file
@@ -0,0 +1,446 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2008 Radu Gruian
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011 Vit Valentin
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Orignal code by Radu Gruian: http://www.codeproject.com/Articles/30838/Overhauser-Catmull-Rom-Splines-for-Camera-Animatio.So
|
||||
|
||||
Adapted to cocos2d-x by Vit Valentin
|
||||
|
||||
Adapted from cocos2d-x to cocos2d-iphone by Ricardo Quesada
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the Cardinal Spline position for a given set of control points, tension and time. <br />
|
||||
* CatmullRom Spline formula. <br />
|
||||
* s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
|
||||
*
|
||||
* @method cardinalSplineAt
|
||||
* @param {Vec2} p0
|
||||
* @param {Vec2} p1
|
||||
* @param {Vec2} p2
|
||||
* @param {Vec2} p3
|
||||
* @param {Number} tension
|
||||
* @param {Number} t
|
||||
* @return {Vec2}
|
||||
*/
|
||||
function cardinalSplineAt (p0, p1, p2, p3, tension, t) {
|
||||
var t2 = t * t;
|
||||
var t3 = t2 * t;
|
||||
|
||||
/*
|
||||
* Formula: s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
|
||||
*/
|
||||
var s = (1 - tension) / 2;
|
||||
|
||||
var b1 = s * ((-t3 + (2 * t2)) - t); // s(-t3 + 2 t2 - t)P1
|
||||
var b2 = s * (-t3 + t2) + (2 * t3 - 3 * t2 + 1); // s(-t3 + t2)P2 + (2 t3 - 3 t2 + 1)P2
|
||||
var b3 = s * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2); // s(t3 - 2 t2 + t)P3 + (-2 t3 + 3 t2)P3
|
||||
var b4 = s * (t3 - t2); // s(t3 - t2)P4
|
||||
|
||||
var x = (p0.x * b1 + p1.x * b2 + p2.x * b3 + p3.x * b4);
|
||||
var y = (p0.y * b1 + p1.y * b2 + p2.y * b3 + p3.y * b4);
|
||||
return cc.v2(x, y);
|
||||
};
|
||||
|
||||
/*
|
||||
* returns a point from the array
|
||||
* @method getControlPointAt
|
||||
* @param {Array} controlPoints
|
||||
* @param {Number} pos
|
||||
* @return {Array}
|
||||
*/
|
||||
function getControlPointAt (controlPoints, pos) {
|
||||
var p = Math.min(controlPoints.length - 1, Math.max(pos, 0));
|
||||
return controlPoints[p];
|
||||
};
|
||||
|
||||
function reverseControlPoints (controlPoints) {
|
||||
var newArray = [];
|
||||
for (var i = controlPoints.length - 1; i >= 0; i--) {
|
||||
newArray.push(cc.v2(controlPoints[i].x, controlPoints[i].y));
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
function cloneControlPoints (controlPoints) {
|
||||
var newArray = [];
|
||||
for (var i = 0; i < controlPoints.length; i++)
|
||||
newArray.push(cc.v2(controlPoints[i].x, controlPoints[i].y));
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Cardinal Spline path. http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline
|
||||
* Absolute coordinates.
|
||||
*
|
||||
* @class CardinalSplineTo
|
||||
* @extends ActionInterval
|
||||
*
|
||||
* @param {Number} duration
|
||||
* @param {Array} points array of control points
|
||||
* @param {Number} tension
|
||||
*
|
||||
* @example
|
||||
* //create a cc.CardinalSplineTo
|
||||
* var action1 = cc.cardinalSplineTo(3, array, 0);
|
||||
*/
|
||||
cc.CardinalSplineTo = cc.Class({
|
||||
name: 'cc.CardinalSplineTo',
|
||||
extends: cc.ActionInterval,
|
||||
|
||||
ctor: function (duration, points, tension) {
|
||||
/* Array of control points */
|
||||
this._points = [];
|
||||
this._deltaT = 0;
|
||||
this._tension = 0;
|
||||
this._previousPosition = null;
|
||||
this._accumulatedDiff = null;
|
||||
tension !== undefined && cc.CardinalSplineTo.prototype.initWithDuration.call(this, duration, points, tension);
|
||||
},
|
||||
|
||||
initWithDuration:function (duration, points, tension) {
|
||||
if (!points || points.length === 0) {
|
||||
cc.errorID(1024);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
|
||||
this.setPoints(points);
|
||||
this._tension = tension;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var action = new cc.CardinalSplineTo();
|
||||
action.initWithDuration(this._duration, cloneControlPoints(this._points), this._tension);
|
||||
return action;
|
||||
},
|
||||
|
||||
startWithTarget:function (target) {
|
||||
cc.ActionInterval.prototype.startWithTarget.call(this, target);
|
||||
// Issue #1441 from cocos2d-iphone
|
||||
this._deltaT = 1 / (this._points.length - 1);
|
||||
this._previousPosition = cc.v2(this.target.x, this.target.y);
|
||||
this._accumulatedDiff = cc.v2(0, 0);
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
dt = this._computeEaseTime(dt);
|
||||
var p, lt;
|
||||
var ps = this._points;
|
||||
// eg.
|
||||
// p..p..p..p..p..p..p
|
||||
// 1..2..3..4..5..6..7
|
||||
// want p to be 1, 2, 3, 4, 5, 6
|
||||
if (dt === 1) {
|
||||
p = ps.length - 1;
|
||||
lt = 1;
|
||||
} else {
|
||||
var locDT = this._deltaT;
|
||||
p = 0 | (dt / locDT);
|
||||
lt = (dt - locDT * p) / locDT;
|
||||
}
|
||||
|
||||
var newPos = cardinalSplineAt(
|
||||
getControlPointAt(ps, p - 1),
|
||||
getControlPointAt(ps, p - 0),
|
||||
getControlPointAt(ps, p + 1),
|
||||
getControlPointAt(ps, p + 2),
|
||||
this._tension, lt);
|
||||
|
||||
if (cc.macro.ENABLE_STACKABLE_ACTIONS) {
|
||||
var tempX, tempY;
|
||||
tempX = this.target.x - this._previousPosition.x;
|
||||
tempY = this.target.y - this._previousPosition.y;
|
||||
if (tempX !== 0 || tempY !== 0) {
|
||||
var locAccDiff = this._accumulatedDiff;
|
||||
tempX = locAccDiff.x + tempX;
|
||||
tempY = locAccDiff.y + tempY;
|
||||
locAccDiff.x = tempX;
|
||||
locAccDiff.y = tempY;
|
||||
newPos.x += tempX;
|
||||
newPos.y += tempY;
|
||||
}
|
||||
}
|
||||
this.updatePosition(newPos);
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
var reversePoints = reverseControlPoints(this._points);
|
||||
return cc.cardinalSplineTo(this._duration, reversePoints, this._tension);
|
||||
},
|
||||
|
||||
/*
|
||||
* update position of target
|
||||
* @method updatePosition
|
||||
* @param {Vec2} newPos
|
||||
*/
|
||||
updatePosition:function (newPos) {
|
||||
this.target.setPosition(newPos);
|
||||
this._previousPosition = newPos;
|
||||
},
|
||||
|
||||
/*
|
||||
* Points getter
|
||||
* @method getPoints
|
||||
* @return {Array}
|
||||
*/
|
||||
getPoints:function () {
|
||||
return this._points;
|
||||
},
|
||||
|
||||
/**
|
||||
* Points setter
|
||||
* @method setPoints
|
||||
* @param {Array} points
|
||||
*/
|
||||
setPoints:function (points) {
|
||||
this._points = points;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates an action with a Cardinal Spline array of points and tension.
|
||||
* !#zh 按基数样条曲线轨迹移动到目标位置。
|
||||
* @method cardinalSplineTo
|
||||
* @param {Number} duration
|
||||
* @param {Array} points array of control points
|
||||
* @param {Number} tension
|
||||
* @return {ActionInterval}
|
||||
*
|
||||
* @example
|
||||
* //create a cc.CardinalSplineTo
|
||||
* var action1 = cc.cardinalSplineTo(3, array, 0);
|
||||
*/
|
||||
cc.cardinalSplineTo = function (duration, points, tension) {
|
||||
return new cc.CardinalSplineTo(duration, points, tension);
|
||||
};
|
||||
|
||||
/*
|
||||
* Cardinal Spline path. http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline
|
||||
* Relative coordinates.
|
||||
*
|
||||
* @class CardinalSplineBy
|
||||
* @extends CardinalSplineTo
|
||||
*
|
||||
* @param {Number} duration
|
||||
* @param {Array} points
|
||||
* @param {Number} tension
|
||||
*
|
||||
* @example
|
||||
* //create a cc.CardinalSplineBy
|
||||
* var action1 = cc.cardinalSplineBy(3, array, 0);
|
||||
*/
|
||||
cc.CardinalSplineBy = cc.Class({
|
||||
name: 'cc.CardinalSplineBy',
|
||||
extends: cc.CardinalSplineTo,
|
||||
|
||||
ctor:function (duration, points, tension) {
|
||||
this._startPosition = cc.v2(0, 0);
|
||||
tension !== undefined && this.initWithDuration(duration, points, tension);
|
||||
},
|
||||
|
||||
startWithTarget:function (target) {
|
||||
cc.CardinalSplineTo.prototype.startWithTarget.call(this, target);
|
||||
this._startPosition.x = target.x;
|
||||
this._startPosition.y = target.y;
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
var copyConfig = this._points.slice();
|
||||
var current;
|
||||
//
|
||||
// convert "absolutes" to "diffs"
|
||||
//
|
||||
var p = copyConfig[0];
|
||||
for (var i = 1; i < copyConfig.length; ++i) {
|
||||
current = copyConfig[i];
|
||||
copyConfig[i] = current.sub(p);
|
||||
p = current;
|
||||
}
|
||||
|
||||
// convert to "diffs" to "reverse absolute"
|
||||
var reverseArray = reverseControlPoints(copyConfig);
|
||||
|
||||
// 1st element (which should be 0,0) should be here too
|
||||
p = reverseArray[ reverseArray.length - 1 ];
|
||||
reverseArray.pop();
|
||||
|
||||
p.x = -p.x;
|
||||
p.y = -p.y;
|
||||
|
||||
reverseArray.unshift(p);
|
||||
for (var i = 1; i < reverseArray.length; ++i) {
|
||||
current = reverseArray[i];
|
||||
current.x = -current.x;
|
||||
current.y = -current.y;
|
||||
current.x += p.x;
|
||||
current.y += p.y;
|
||||
reverseArray[i] = current;
|
||||
p = current;
|
||||
}
|
||||
return cc.cardinalSplineBy(this._duration, reverseArray, this._tension);
|
||||
},
|
||||
|
||||
/**
|
||||
* update position of target
|
||||
* @method updatePosition
|
||||
* @param {Vec2} newPos
|
||||
*/
|
||||
updatePosition:function (newPos) {
|
||||
var pos = this._startPosition;
|
||||
var posX = newPos.x + pos.x;
|
||||
var posY = newPos.y + pos.y;
|
||||
this._previousPosition.x = posX;
|
||||
this._previousPosition.y = posY;
|
||||
this.target.setPosition(posX, posY);
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var a = new cc.CardinalSplineBy();
|
||||
a.initWithDuration(this._duration, cloneControlPoints(this._points), this._tension);
|
||||
return a;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates an action with a Cardinal Spline array of points and tension.
|
||||
* !#zh 按基数样条曲线轨迹移动指定的距离。
|
||||
* @method cardinalSplineBy
|
||||
* @param {Number} duration
|
||||
* @param {Array} points
|
||||
* @param {Number} tension
|
||||
*
|
||||
* @return {ActionInterval}
|
||||
*/
|
||||
cc.cardinalSplineBy = function (duration, points, tension) {
|
||||
return new cc.CardinalSplineBy(duration, points, tension);
|
||||
};
|
||||
|
||||
/*
|
||||
* An action that moves the target with a CatmullRom curve to a destination point.<br/>
|
||||
* A Catmull Rom is a Cardinal Spline with a tension of 0.5. <br/>
|
||||
* http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline
|
||||
* Absolute coordinates.
|
||||
*
|
||||
* @class CatmullRomTo
|
||||
* @extends CardinalSplineTo
|
||||
*
|
||||
* @param {Number} dt
|
||||
* @param {Array} points
|
||||
*
|
||||
* @example
|
||||
* var action1 = cc.catmullRomTo(3, array);
|
||||
*/
|
||||
cc.CatmullRomTo = cc.Class({
|
||||
name: 'cc.CatmullRomTo',
|
||||
extends: cc.CardinalSplineTo,
|
||||
|
||||
ctor: function(dt, points) {
|
||||
points && this.initWithDuration(dt, points);
|
||||
},
|
||||
|
||||
initWithDuration:function (dt, points) {
|
||||
return cc.CardinalSplineTo.prototype.initWithDuration.call(this, dt, points, 0.5);
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var action = new cc.CatmullRomTo();
|
||||
action.initWithDuration(this._duration, cloneControlPoints(this._points));
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates an action with a Cardinal Spline array of points and tension.
|
||||
* !#zh 按 Catmull Rom 样条曲线轨迹移动到目标位置。
|
||||
* @method catmullRomTo
|
||||
* @param {Number} dt
|
||||
* @param {Array} points
|
||||
* @return {ActionInterval}
|
||||
*
|
||||
* @example
|
||||
* var action1 = cc.catmullRomTo(3, array);
|
||||
*/
|
||||
cc.catmullRomTo = function (dt, points) {
|
||||
return new cc.CatmullRomTo(dt, points);
|
||||
};
|
||||
|
||||
/*
|
||||
* An action that moves the target with a CatmullRom curve by a certain distance. <br/>
|
||||
* A Catmull Rom is a Cardinal Spline with a tension of 0.5.<br/>
|
||||
* http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline
|
||||
* Relative coordinates.
|
||||
*
|
||||
* @class CatmullRomBy
|
||||
* @extends CardinalSplineBy
|
||||
*
|
||||
* @param {Number} dt
|
||||
* @param {Array} points
|
||||
*
|
||||
* @example
|
||||
* var action1 = cc.catmullRomBy(3, array);
|
||||
*/
|
||||
cc.CatmullRomBy = cc.Class({
|
||||
name: 'cc.CatmullRomBy',
|
||||
extends: cc.CardinalSplineBy,
|
||||
|
||||
ctor: function(dt, points) {
|
||||
points && this.initWithDuration(dt, points);
|
||||
},
|
||||
|
||||
initWithDuration:function (dt, points) {
|
||||
return cc.CardinalSplineTo.prototype.initWithDuration.call(this, dt, points, 0.5);
|
||||
},
|
||||
|
||||
clone:function () {
|
||||
var action = new cc.CatmullRomBy();
|
||||
action.initWithDuration(this._duration, cloneControlPoints(this._points));
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates an action with a Cardinal Spline array of points and tension.
|
||||
* !#zh 按 Catmull Rom 样条曲线轨迹移动指定的距离。
|
||||
* @method catmullRomBy
|
||||
* @param {Number} dt
|
||||
* @param {Array} points
|
||||
* @return {ActionInterval}
|
||||
* @example
|
||||
* var action1 = cc.catmullRomBy(3, array);
|
||||
*/
|
||||
cc.catmullRomBy = function (dt, points) {
|
||||
return new cc.CatmullRomBy(dt, points);
|
||||
};
|
1047
engine/cocos2d/actions/CCActionEase.js
Normal file
1047
engine/cocos2d/actions/CCActionEase.js
Normal file
File diff suppressed because it is too large
Load Diff
569
engine/cocos2d/actions/CCActionInstant.js
Normal file
569
engine/cocos2d/actions/CCActionInstant.js
Normal file
@@ -0,0 +1,569 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/**
|
||||
* !#en Instant actions are immediate actions. They don't have a duration like the ActionInterval actions.
|
||||
* !#zh 即时动作,这种动作立即就会执行,继承自 FiniteTimeAction。
|
||||
* @class ActionInstant
|
||||
* @extends FiniteTimeAction
|
||||
*/
|
||||
cc.ActionInstant = cc.Class({
|
||||
name: 'cc.ActionInstant',
|
||||
extends: cc.FiniteTimeAction,
|
||||
isDone:function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
step:function (dt) {
|
||||
this.update(1);
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
//nothing
|
||||
},
|
||||
|
||||
/**
|
||||
* returns a reversed action. <br />
|
||||
* For example: <br />
|
||||
* - The action is x coordinates of 0 move to 100. <br />
|
||||
* - The reversed action will be x of 100 move to 0.
|
||||
* @returns {Action}
|
||||
*/
|
||||
reverse:function(){
|
||||
return this.clone();
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
return new cc.ActionInstant();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/*
|
||||
* Show the node.
|
||||
* @class Show
|
||||
* @extends ActionInstant
|
||||
*/
|
||||
cc.Show = cc.Class({
|
||||
name: 'cc.Show',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
update:function (dt) {
|
||||
var _renderComps = this.target.getComponentsInChildren(cc.RenderComponent);
|
||||
for (var i = 0; i < _renderComps.length; ++i) {
|
||||
var render = _renderComps[i];
|
||||
render.enabled = true;
|
||||
}
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.Hide();
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
return new cc.Show();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Show the Node.
|
||||
* !#zh 立即显示。
|
||||
* @method show
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* // example
|
||||
* var showAction = cc.show();
|
||||
*/
|
||||
cc.show = function () {
|
||||
return new cc.Show();
|
||||
};
|
||||
|
||||
/*
|
||||
* Hide the node.
|
||||
* @class Hide
|
||||
* @extends ActionInstant
|
||||
*/
|
||||
cc.Hide = cc.Class({
|
||||
name: 'cc.Hide',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
update:function (dt) {
|
||||
var _renderComps = this.target.getComponentsInChildren(cc.RenderComponent);
|
||||
for (var i = 0; i < _renderComps.length; ++i) {
|
||||
var render = _renderComps[i];
|
||||
render.enabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.Show();
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
return new cc.Hide();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Hide the node.
|
||||
* !#zh 立即隐藏。
|
||||
* @method hide
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* // example
|
||||
* var hideAction = cc.hide();
|
||||
*/
|
||||
cc.hide = function () {
|
||||
return new cc.Hide();
|
||||
};
|
||||
|
||||
/*
|
||||
* Toggles the visibility of a node.
|
||||
* @class ToggleVisibility
|
||||
* @extends ActionInstant
|
||||
*/
|
||||
cc.ToggleVisibility = cc.Class({
|
||||
name: 'cc.ToggleVisibility',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
update:function (dt) {
|
||||
var _renderComps = this.target.getComponentsInChildren(cc.RenderComponent);
|
||||
for (var i = 0; i < _renderComps.length; ++i) {
|
||||
var render = _renderComps[i];
|
||||
render.enabled = !render.enabled;
|
||||
}
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.ToggleVisibility();
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
return new cc.ToggleVisibility();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Toggles the visibility of a node.
|
||||
* !#zh 显隐状态切换。
|
||||
* @method toggleVisibility
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* // example
|
||||
* var toggleVisibilityAction = cc.toggleVisibility();
|
||||
*/
|
||||
cc.toggleVisibility = function () {
|
||||
return new cc.ToggleVisibility();
|
||||
};
|
||||
|
||||
/*
|
||||
* Delete self in the next frame.
|
||||
* @class RemoveSelf
|
||||
* @extends ActionInstant
|
||||
* @param {Boolean} [isNeedCleanUp=true]
|
||||
*
|
||||
* @example
|
||||
* // example
|
||||
* var removeSelfAction = new cc.RemoveSelf(false);
|
||||
*/
|
||||
cc.RemoveSelf = cc.Class({
|
||||
name: 'cc.RemoveSelf',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
ctor:function(isNeedCleanUp){
|
||||
this._isNeedCleanUp = true;
|
||||
isNeedCleanUp !== undefined && this.init(isNeedCleanUp);
|
||||
},
|
||||
|
||||
update:function(dt){
|
||||
this.target.removeFromParent(this._isNeedCleanUp);
|
||||
},
|
||||
|
||||
init:function(isNeedCleanUp){
|
||||
this._isNeedCleanUp = isNeedCleanUp;
|
||||
return true;
|
||||
},
|
||||
|
||||
reverse:function(){
|
||||
return new cc.RemoveSelf(this._isNeedCleanUp);
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
return new cc.RemoveSelf(this._isNeedCleanUp);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Create a RemoveSelf object with a flag indicate whether the target should be cleaned up while removing.
|
||||
* !#zh 从父节点移除自身。
|
||||
* @method removeSelf
|
||||
* @param {Boolean} [isNeedCleanUp = true]
|
||||
* @return {ActionInstant}
|
||||
*
|
||||
* @example
|
||||
* // example
|
||||
* var removeSelfAction = cc.removeSelf();
|
||||
*/
|
||||
cc.removeSelf = function(isNeedCleanUp){
|
||||
return new cc.RemoveSelf(isNeedCleanUp);
|
||||
};
|
||||
|
||||
/*
|
||||
* Create an action to destroy self.
|
||||
* @class DestroySelf
|
||||
* @extends ActionInstant
|
||||
*
|
||||
* @example
|
||||
* var destroySelfAction = new cc.DestroySelf();
|
||||
*/
|
||||
cc.DestroySelf = cc.Class({
|
||||
name: 'cc.DestroySelf',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
update () {
|
||||
this.target.destroy();
|
||||
},
|
||||
|
||||
reverse () {
|
||||
return new cc.DestroySelf();
|
||||
},
|
||||
|
||||
clone () {
|
||||
return new cc.DestroySelf();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Destroy self
|
||||
* !#zh 创建一个销毁自身的动作。
|
||||
* @method destroySelf
|
||||
* @return {ActionInstant}
|
||||
*
|
||||
* @example
|
||||
* var destroySelfAction = cc.destroySelf();
|
||||
*/
|
||||
cc.destroySelf = function () {
|
||||
return new cc.DestroySelf();
|
||||
};
|
||||
|
||||
/*
|
||||
* Flips the sprite horizontally.
|
||||
* @class FlipX
|
||||
* @extends ActionInstant
|
||||
* @param {Boolean} flip Indicate whether the target should be flipped or not
|
||||
*
|
||||
* @example
|
||||
* var flipXAction = new cc.FlipX(true);
|
||||
*/
|
||||
cc.FlipX = cc.Class({
|
||||
name: 'cc.FlipX',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
ctor:function(flip){
|
||||
this._flippedX = false;
|
||||
flip !== undefined && this.initWithFlipX(flip);
|
||||
},
|
||||
|
||||
/*
|
||||
* initializes the action with a set flipX.
|
||||
* @param {Boolean} flip
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithFlipX:function (flip) {
|
||||
this._flippedX = flip;
|
||||
return true;
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
this.target.scaleX = Math.abs(this.target.scaleX) * (this._flippedX ? -1 : 1);
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.FlipX(!this._flippedX);
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
var action = new cc.FlipX();
|
||||
action.initWithFlipX(this._flippedX);
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Create a FlipX action to flip or unflip the target.
|
||||
* !#zh X轴翻转。
|
||||
* @method flipX
|
||||
* @param {Boolean} flip Indicate whether the target should be flipped or not
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* var flipXAction = cc.flipX(true);
|
||||
*/
|
||||
cc.flipX = function (flip) {
|
||||
return new cc.FlipX(flip);
|
||||
};
|
||||
|
||||
/*
|
||||
* Flips the sprite vertically
|
||||
* @class FlipY
|
||||
* @extends ActionInstant
|
||||
* @param {Boolean} flip
|
||||
* @example
|
||||
* var flipYAction = new cc.FlipY(true);
|
||||
*/
|
||||
cc.FlipY = cc.Class({
|
||||
name: 'cc.FlipY',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
ctor: function(flip){
|
||||
this._flippedY = false;
|
||||
flip !== undefined && this.initWithFlipY(flip);
|
||||
},
|
||||
|
||||
/*
|
||||
* initializes the action with a set flipY.
|
||||
* @param {Boolean} flip
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithFlipY:function (flip) {
|
||||
this._flippedY = flip;
|
||||
return true;
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
this.target.scaleY = Math.abs(this.target.scaleY) * (this._flippedY ? -1 : 1);
|
||||
},
|
||||
|
||||
reverse:function () {
|
||||
return new cc.FlipY(!this._flippedY);
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
var action = new cc.FlipY();
|
||||
action.initWithFlipY(this._flippedY);
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Create a FlipY action to flip or unflip the target.
|
||||
* !#zh Y轴翻转。
|
||||
* @method flipY
|
||||
* @param {Boolean} flip
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* var flipYAction = cc.flipY(true);
|
||||
*/
|
||||
cc.flipY = function (flip) {
|
||||
return new cc.FlipY(flip);
|
||||
};
|
||||
|
||||
/*
|
||||
* Places the node in a certain position
|
||||
* @class Place
|
||||
* @extends ActionInstant
|
||||
* @param {Vec2|Number} pos
|
||||
* @param {Number} [y]
|
||||
* @example
|
||||
* var placeAction = new cc.Place(cc.v2(200, 200));
|
||||
* var placeAction = new cc.Place(200, 200);
|
||||
*/
|
||||
cc.Place = cc.Class({
|
||||
name: 'cc.Place',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
ctor:function(pos, y){
|
||||
this._x = 0;
|
||||
this._y = 0;
|
||||
|
||||
if (pos !== undefined) {
|
||||
if (pos.x !== undefined) {
|
||||
y = pos.y;
|
||||
pos = pos.x;
|
||||
}
|
||||
this.initWithPosition(pos, y);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Initializes a Place action with a position
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithPosition: function (x, y) {
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
return true;
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
this.target.setPosition(this._x, this._y);
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
var action = new cc.Place();
|
||||
action.initWithPosition(this._x, this._y);
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates a Place action with a position.
|
||||
* !#zh 放置在目标位置。
|
||||
* @method place
|
||||
* @param {Vec2|Number} pos
|
||||
* @param {Number} [y]
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* // example
|
||||
* var placeAction = cc.place(cc.v2(200, 200));
|
||||
* var placeAction = cc.place(200, 200);
|
||||
*/
|
||||
cc.place = function (pos, y) {
|
||||
return new cc.Place(pos, y);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Calls a 'callback'.
|
||||
* @class CallFunc
|
||||
* @extends ActionInstant
|
||||
* @param {function} selector
|
||||
* @param {object} [selectorTarget=null]
|
||||
* @param {*} [data=null] data for function, it accepts all data types.
|
||||
* @example
|
||||
* // example
|
||||
* // CallFunc without data
|
||||
* var finish = new cc.CallFunc(this.removeSprite, this);
|
||||
*
|
||||
* // CallFunc with data
|
||||
* var finish = new cc.CallFunc(this.removeFromParentAndCleanup, this, true);
|
||||
*/
|
||||
cc.CallFunc = cc.Class({
|
||||
name: 'cc.CallFunc',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
/*
|
||||
* Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. <br />
|
||||
* Creates a CallFunc action with the callback.
|
||||
* @param {function} selector
|
||||
* @param {object} [selectorTarget=null]
|
||||
* @param {*} [data=null] data for function, it accepts all data types.
|
||||
*/
|
||||
ctor:function(selector, selectorTarget, data){
|
||||
this._selectorTarget = null;
|
||||
this._function = null;
|
||||
this._data = null;
|
||||
this.initWithFunction(selector, selectorTarget, data);
|
||||
},
|
||||
|
||||
/*
|
||||
* Initializes the action with a function or function and its target
|
||||
* @param {function} selector
|
||||
* @param {object|Null} selectorTarget
|
||||
* @param {*|Null} [data] data for function, it accepts all data types.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
initWithFunction:function (selector, selectorTarget, data) {
|
||||
if (selector) {
|
||||
this._function = selector;
|
||||
}
|
||||
if (selectorTarget) {
|
||||
this._selectorTarget = selectorTarget;
|
||||
}
|
||||
if (data !== undefined) {
|
||||
this._data = data;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
* execute the function.
|
||||
*/
|
||||
execute:function () {
|
||||
if (this._function) {
|
||||
this._function.call(this._selectorTarget, this.target, this._data);
|
||||
}
|
||||
},
|
||||
|
||||
update:function (dt) {
|
||||
this.execute();
|
||||
},
|
||||
|
||||
/*
|
||||
* Get selectorTarget.
|
||||
* @return {object}
|
||||
*/
|
||||
getTargetCallback:function () {
|
||||
return this._selectorTarget;
|
||||
},
|
||||
|
||||
/*
|
||||
* Set selectorTarget.
|
||||
* @param {object} sel
|
||||
*/
|
||||
setTargetCallback:function (sel) {
|
||||
if (sel !== this._selectorTarget) {
|
||||
if (this._selectorTarget)
|
||||
this._selectorTarget = null;
|
||||
this._selectorTarget = sel;
|
||||
}
|
||||
},
|
||||
|
||||
clone:function(){
|
||||
var action = new cc.CallFunc();
|
||||
action.initWithFunction(this._function, this._selectorTarget, this._data);
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Creates the action with the callback.
|
||||
* !#zh 执行回调函数。
|
||||
* @method callFunc
|
||||
* @param {function} selector
|
||||
* @param {object} [selectorTarget=null]
|
||||
* @param {*} [data=null] - data for function, it accepts all data types.
|
||||
* @return {ActionInstant}
|
||||
* @example
|
||||
* // example
|
||||
* // CallFunc without data
|
||||
* var finish = cc.callFunc(this.removeSprite, this);
|
||||
*
|
||||
* // CallFunc with data
|
||||
* var finish = cc.callFunc(this.removeFromParentAndCleanup, this._grossini, true);
|
||||
*/
|
||||
cc.callFunc = function (selector, selectorTarget, data) {
|
||||
return new cc.CallFunc(selector, selectorTarget, data);
|
||||
};
|
2605
engine/cocos2d/actions/CCActionInterval.js
Normal file
2605
engine/cocos2d/actions/CCActionInterval.js
Normal file
File diff suppressed because it is too large
Load Diff
509
engine/cocos2d/actions/CCActionManager.js
Normal file
509
engine/cocos2d/actions/CCActionManager.js
Normal file
@@ -0,0 +1,509 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2011-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
require('../core/platform/CCClass');
|
||||
var js = require('../core/platform/js');
|
||||
|
||||
/*
|
||||
* @class HashElement
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
var HashElement = function () {
|
||||
this.actions = [];
|
||||
this.target = null; //ccobject
|
||||
this.actionIndex = 0;
|
||||
this.currentAction = null; //CCAction
|
||||
this.paused = false;
|
||||
this.lock = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* cc.ActionManager is a class that can manage actions.<br/>
|
||||
* Normally you won't need to use this class directly. 99% of the cases you will use the CCNode interface,
|
||||
* which uses this class's singleton object.
|
||||
* But there are some cases where you might need to use this class. <br/>
|
||||
* Examples:<br/>
|
||||
* - When you want to run an action where the target is different from a CCNode.<br/>
|
||||
* - When you want to pause / resume the actions<br/>
|
||||
* !#zh
|
||||
* cc.ActionManager 是可以管理动作的单例类。<br/>
|
||||
* 通常你并不需要直接使用这个类,99%的情况您将使用 CCNode 的接口。<br/>
|
||||
* 但也有一些情况下,您可能需要使用这个类。 <br/>
|
||||
* 例如:
|
||||
* - 当你想要运行一个动作,但目标不是 CCNode 类型时。 <br/>
|
||||
* - 当你想要暂停/恢复动作时。 <br/>
|
||||
* @class ActionManager
|
||||
* @example {@link cocos2d/core/CCActionManager/ActionManager.js}
|
||||
*/
|
||||
cc.ActionManager = function () {
|
||||
this._hashTargets = js.createMap(true);
|
||||
this._arrayTargets = [];
|
||||
this._currentTarget = null;
|
||||
cc.director._scheduler && cc.director._scheduler.enableForTarget(this);
|
||||
};
|
||||
cc.ActionManager.prototype = {
|
||||
constructor: cc.ActionManager,
|
||||
_elementPool: [],
|
||||
|
||||
_searchElementByTarget: function (arr, target) {
|
||||
for (var k = 0; k < arr.length; k++) {
|
||||
if (target === arr[k].target)
|
||||
return arr[k];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
_getElement: function (target, paused) {
|
||||
var element = this._elementPool.pop();
|
||||
if (!element) {
|
||||
element = new HashElement();
|
||||
}
|
||||
element.target = target;
|
||||
element.paused = !!paused;
|
||||
return element;
|
||||
},
|
||||
|
||||
_putElement: function (element) {
|
||||
element.actions.length = 0;
|
||||
element.actionIndex = 0;
|
||||
element.currentAction = null;
|
||||
element.paused = false;
|
||||
element.target = null;
|
||||
element.lock = false;
|
||||
this._elementPool.push(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Adds an action with a target.<br/>
|
||||
* If the target is already present, then the action will be added to the existing target.
|
||||
* If the target is not present, a new instance of this target will be created either paused or not, and the action will be added to the newly created target.
|
||||
* When the target is paused, the queued actions won't be 'ticked'.
|
||||
* !#zh
|
||||
* 增加一个动作,同时还需要提供动作的目标对象,目标对象是否暂停作为参数。<br/>
|
||||
* 如果目标已存在,动作将会被直接添加到现有的节点中。<br/>
|
||||
* 如果目标不存在,将为这一目标创建一个新的实例,并将动作添加进去。<br/>
|
||||
* 当目标状态的 paused 为 true,动作将不会被执行
|
||||
*
|
||||
* @method addAction
|
||||
* @param {Action} action
|
||||
* @param {Node} target
|
||||
* @param {Boolean} paused
|
||||
*/
|
||||
addAction: function (action, target, paused) {
|
||||
if (!action || !target) {
|
||||
cc.errorID(1000);
|
||||
return;
|
||||
}
|
||||
|
||||
//check if the action target already exists
|
||||
var element = this._hashTargets[target._id];
|
||||
//if doesn't exists, create a hashelement and push in mpTargets
|
||||
if (!element) {
|
||||
element = this._getElement(target, paused);
|
||||
this._hashTargets[target._id] = element;
|
||||
this._arrayTargets.push(element);
|
||||
}
|
||||
else if (!element.actions) {
|
||||
element.actions = [];
|
||||
}
|
||||
|
||||
element.actions.push(action);
|
||||
action.startWithTarget(target);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Removes all actions from all the targets.
|
||||
* !#zh 移除所有对象的所有动作。
|
||||
* @method removeAllActions
|
||||
*/
|
||||
removeAllActions: function () {
|
||||
var locTargets = this._arrayTargets;
|
||||
for (var i = 0; i < locTargets.length; i++) {
|
||||
var element = locTargets[i];
|
||||
if (element)
|
||||
this._putElement(element);
|
||||
}
|
||||
this._arrayTargets.length = 0;
|
||||
this._hashTargets = js.createMap(true);
|
||||
},
|
||||
/**
|
||||
* !#en
|
||||
* Removes all actions from a certain target. <br/>
|
||||
* All the actions that belongs to the target will be removed.
|
||||
* !#zh
|
||||
* 移除指定对象上的所有动作。<br/>
|
||||
* 属于该目标的所有的动作将被删除。
|
||||
* @method removeAllActionsFromTarget
|
||||
* @param {Node} target
|
||||
* @param {Boolean} forceDelete
|
||||
*/
|
||||
removeAllActionsFromTarget: function (target, forceDelete) {
|
||||
// explicit null handling
|
||||
if (target == null)
|
||||
return;
|
||||
var element = this._hashTargets[target._id];
|
||||
if (element) {
|
||||
element.actions.length = 0;
|
||||
this._deleteHashElement(element);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* !#en Removes an action given an action reference.
|
||||
* !#zh 移除指定的动作。
|
||||
* @method removeAction
|
||||
* @param {Action} action
|
||||
*/
|
||||
removeAction: function (action) {
|
||||
// explicit null handling
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
var target = action.getOriginalTarget();
|
||||
var element = this._hashTargets[target._id];
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < element.actions.length; i++) {
|
||||
if (element.actions[i] === action) {
|
||||
element.actions.splice(i, 1);
|
||||
// update actionIndex in case we are in tick. looping over the actions
|
||||
if (element.actionIndex >= i)
|
||||
element.actionIndex--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_removeActionByTag (tag, element, target) {
|
||||
for (var i = 0, l = element.actions.length; i < l; ++i) {
|
||||
var action = element.actions[i];
|
||||
if (action && action.getTag() === tag) {
|
||||
if (target && action.getOriginalTarget() !== target) {
|
||||
continue;
|
||||
}
|
||||
this._removeActionAtIndex(i, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_removeAllActionsByTag (tag, element, target) {
|
||||
for (var i = element.actions.length - 1; i >= 0; --i) {
|
||||
var action = element.actions[i];
|
||||
if (action && action.getTag() === tag) {
|
||||
if (target && action.getOriginalTarget() !== target) {
|
||||
continue;
|
||||
}
|
||||
this._removeActionAtIndex(i, element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Removes an action given its tag and the target.
|
||||
* !#zh 删除指定对象下特定标签的一个动作,将删除首个匹配到的动作。
|
||||
* @method removeActionByTag
|
||||
* @param {Number} tag
|
||||
* @param {Node} [target]
|
||||
*/
|
||||
removeActionByTag: function (tag, target) {
|
||||
if(tag === cc.Action.TAG_INVALID)
|
||||
cc.logID(1002);
|
||||
|
||||
let hashTargets = this._hashTargets;
|
||||
if (target) {
|
||||
var element = hashTargets[target._id];
|
||||
if (element) {
|
||||
this._removeActionByTag(tag, element, target);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let name in hashTargets) {
|
||||
let element = hashTargets[name];
|
||||
this._removeActionByTag(tag, element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Removes all actions given the tag and the target.
|
||||
* !#zh 删除指定对象下特定标签的所有动作。
|
||||
* @method removeAllActionsByTag
|
||||
* @param {Number} tag
|
||||
* @param {Node} [target]
|
||||
*/
|
||||
removeAllActionsByTag: function (tag, target) {
|
||||
if (tag === cc.Action.TAG_INVALID)
|
||||
cc.logID(1002);
|
||||
|
||||
let hashTargets = this._hashTargets;
|
||||
if (target) {
|
||||
var element = hashTargets[target._id];
|
||||
if (element) {
|
||||
this._removeAllActionsByTag(tag, element, target);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let name in hashTargets) {
|
||||
let element = hashTargets[name];
|
||||
this._removeAllActionsByTag(tag, element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Gets an action given its tag an a target.
|
||||
* !#zh 通过目标对象和标签获取一个动作。
|
||||
* @method getActionByTag
|
||||
* @param {Number} tag
|
||||
* @param {Node} target
|
||||
* @return {Action|Null} return the Action with the given tag on success
|
||||
*/
|
||||
getActionByTag: function (tag, target) {
|
||||
if(tag === cc.Action.TAG_INVALID)
|
||||
cc.logID(1004);
|
||||
|
||||
var element = this._hashTargets[target._id];
|
||||
if (element) {
|
||||
if (element.actions != null) {
|
||||
for (var i = 0; i < element.actions.length; ++i) {
|
||||
var action = element.actions[i];
|
||||
if (action && action.getTag() === tag)
|
||||
return action;
|
||||
}
|
||||
}
|
||||
cc.logID(1005, tag);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Returns the numbers of actions that are running in a certain target. <br/>
|
||||
* Composable actions are counted as 1 action. <br/>
|
||||
* Example: <br/>
|
||||
* - If you are running 1 Sequence of 7 actions, it will return 1. <br/>
|
||||
* - If you are running 7 Sequences of 2 actions, it will return 7.
|
||||
* !#zh
|
||||
* 返回指定对象下所有正在运行的动作数量。 <br/>
|
||||
* 组合动作被算作一个动作。<br/>
|
||||
* 例如:<br/>
|
||||
* - 如果您正在运行 7 个动作组成的序列动作(Sequence),这个函数将返回 1。<br/>
|
||||
* - 如果你正在运行 2 个序列动作(Sequence)和 5 个普通动作,这个函数将返回 7。<br/>
|
||||
*
|
||||
* @method getNumberOfRunningActionsInTarget
|
||||
* @param {Node} target
|
||||
* @return {Number}
|
||||
*/
|
||||
getNumberOfRunningActionsInTarget: function (target) {
|
||||
var element = this._hashTargets[target._id];
|
||||
if (element)
|
||||
return (element.actions) ? element.actions.length : 0;
|
||||
|
||||
return 0;
|
||||
},
|
||||
/**
|
||||
* !#en Pauses the target: all running actions and newly added actions will be paused.
|
||||
* !#zh 暂停指定对象:所有正在运行的动作和新添加的动作都将会暂停。
|
||||
* @method pauseTarget
|
||||
* @param {Node} target
|
||||
*/
|
||||
pauseTarget: function (target) {
|
||||
var element = this._hashTargets[target._id];
|
||||
if (element)
|
||||
element.paused = true;
|
||||
},
|
||||
/**
|
||||
* !#en Resumes the target. All queued actions will be resumed.
|
||||
* !#zh 让指定目标恢复运行。在执行序列中所有被暂停的动作将重新恢复运行。
|
||||
* @method resumeTarget
|
||||
* @param {Node} target
|
||||
*/
|
||||
resumeTarget: function (target) {
|
||||
var element = this._hashTargets[target._id];
|
||||
if (element)
|
||||
element.paused = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Pauses all running actions, returning a list of targets whose actions were paused.
|
||||
* !#zh 暂停所有正在运行的动作,返回一个包含了那些动作被暂停了的目标对象的列表。
|
||||
* @method pauseAllRunningActions
|
||||
* @return {Array} a list of targets whose actions were paused.
|
||||
*/
|
||||
pauseAllRunningActions: function () {
|
||||
var idsWithActions = [];
|
||||
var locTargets = this._arrayTargets;
|
||||
for(var i = 0; i < locTargets.length; i++){
|
||||
var element = locTargets[i];
|
||||
if(element && !element.paused){
|
||||
element.paused = true;
|
||||
idsWithActions.push(element.target);
|
||||
}
|
||||
}
|
||||
return idsWithActions;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Resume a set of targets (convenience function to reverse a pauseAllRunningActions or pauseTargets call).
|
||||
* !#zh 让一组指定对象恢复运行(用来逆转 pauseAllRunningActions 效果的便捷函数)。
|
||||
* @method resumeTargets
|
||||
* @param {Array} targetsToResume
|
||||
*/
|
||||
resumeTargets: function (targetsToResume) {
|
||||
if (!targetsToResume)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < targetsToResume.length; i++) {
|
||||
if(targetsToResume[i])
|
||||
this.resumeTarget(targetsToResume[i]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Pause a set of targets.
|
||||
* !#zh 暂停一组指定对象。
|
||||
* @method pauseTargets
|
||||
* @param {Array} targetsToPause
|
||||
*/
|
||||
pauseTargets: function (targetsToPause) {
|
||||
if (!targetsToPause)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < targetsToPause.length; i++) {
|
||||
if (targetsToPause[i])
|
||||
this.pauseTarget(targetsToPause[i]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* purges the shared action manager. It releases the retained instance. <br/>
|
||||
* because it uses this, so it can not be static.
|
||||
* !#zh
|
||||
* 清除共用的动作管理器。它释放了持有的实例。 <br/>
|
||||
* 因为它使用 this,因此它不能是静态的。
|
||||
* @method purgeSharedManager
|
||||
*/
|
||||
purgeSharedManager: function () {
|
||||
cc.director.getScheduler().unscheduleUpdate(this);
|
||||
},
|
||||
|
||||
//protected
|
||||
_removeActionAtIndex: function (index, element) {
|
||||
var action = element.actions[index];
|
||||
|
||||
element.actions.splice(index, 1);
|
||||
|
||||
// update actionIndex in case we are in tick. looping over the actions
|
||||
if (element.actionIndex >= index)
|
||||
element.actionIndex--;
|
||||
|
||||
if (element.actions.length === 0) {
|
||||
this._deleteHashElement(element);
|
||||
}
|
||||
},
|
||||
|
||||
_deleteHashElement: function (element) {
|
||||
var ret = false;
|
||||
if (element && !element.lock) {
|
||||
if (this._hashTargets[element.target._id]) {
|
||||
delete this._hashTargets[element.target._id];
|
||||
var targets = this._arrayTargets;
|
||||
for (var i = 0, l = targets.length; i < l; i++) {
|
||||
if (targets[i] === element) {
|
||||
targets.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this._putElement(element);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en The ActionManager update。
|
||||
* !#zh ActionManager 主循环。
|
||||
* @method update
|
||||
* @param {Number} dt delta time in seconds
|
||||
*/
|
||||
update: function (dt) {
|
||||
var locTargets = this._arrayTargets , locCurrTarget;
|
||||
for (var elt = 0; elt < locTargets.length; elt++) {
|
||||
this._currentTarget = locTargets[elt];
|
||||
locCurrTarget = this._currentTarget;
|
||||
if (!locCurrTarget.paused && locCurrTarget.actions) {
|
||||
locCurrTarget.lock = true;
|
||||
// The 'actions' CCMutableArray may change while inside this loop.
|
||||
for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
|
||||
locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
|
||||
if (!locCurrTarget.currentAction)
|
||||
continue;
|
||||
|
||||
//use for speed
|
||||
locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
|
||||
|
||||
if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
|
||||
locCurrTarget.currentAction.stop();
|
||||
var action = locCurrTarget.currentAction;
|
||||
// Make currentAction nil to prevent removeAction from salvaging it.
|
||||
locCurrTarget.currentAction = null;
|
||||
this.removeAction(action);
|
||||
}
|
||||
|
||||
locCurrTarget.currentAction = null;
|
||||
}
|
||||
locCurrTarget.lock = false;
|
||||
}
|
||||
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
|
||||
if (locCurrTarget.actions.length === 0) {
|
||||
this._deleteHashElement(locCurrTarget) && elt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (CC_TEST) {
|
||||
cc.ActionManager.prototype.isTargetPaused_TEST = function (target) {
|
||||
var element = this._hashTargets[target._id];
|
||||
return element.paused;
|
||||
};
|
||||
}
|
32
engine/cocos2d/actions/index.js
Normal file
32
engine/cocos2d/actions/index.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
require('./CCActionManager');
|
||||
require('./CCAction');
|
||||
require('./CCActionInterval');
|
||||
require('./CCActionInstant');
|
||||
require('./CCActionEase');
|
||||
require('./CCActionCatmullRom');
|
||||
require('./tween');
|
706
engine/cocos2d/actions/tween.js
Normal file
706
engine/cocos2d/actions/tween.js
Normal file
@@ -0,0 +1,706 @@
|
||||
import { bezier } from '../animation/bezier';
|
||||
|
||||
let _tweenID = 0;
|
||||
|
||||
let TweenAction = cc.Class({
|
||||
name: 'cc.TweenAction',
|
||||
extends: cc.ActionInterval,
|
||||
|
||||
ctor (duration, props, opts) {
|
||||
this._opts = opts = opts || Object.create(null);
|
||||
this._props = Object.create(null);
|
||||
|
||||
// global easing or progress used for this action
|
||||
opts.progress = opts.progress || this.progress;
|
||||
if (opts.easing && typeof opts.easing === 'string') {
|
||||
let easingName = opts.easing;
|
||||
opts.easing = cc.easing[easingName];
|
||||
!opts.easing && cc.warnID(1031, easingName);
|
||||
}
|
||||
|
||||
let relative = this._opts.relative;
|
||||
|
||||
for (let name in props) {
|
||||
let value = props[name];
|
||||
|
||||
// property may have custom easing or progress function
|
||||
let easing, progress;
|
||||
if (value.value !== undefined && (value.easing || value.progress)) {
|
||||
if (typeof value.easing === 'string') {
|
||||
easing = cc.easing[value.easing];
|
||||
!easing && cc.warnID(1031, value.easing);
|
||||
}
|
||||
else {
|
||||
easing = value.easing;
|
||||
}
|
||||
progress = value.progress;
|
||||
value = value.value;
|
||||
}
|
||||
|
||||
let isNumber = typeof value === 'number';
|
||||
if (!isNumber && (!value.lerp || (relative && !value.add && !value.mul) || !value.clone)) {
|
||||
cc.warn(`Can not animate ${name} property, because it do not have [lerp, (add|mul), clone] function.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let prop = Object.create(null);
|
||||
prop.value = value;
|
||||
prop.easing = easing;
|
||||
prop.progress = progress;
|
||||
this._props[name] = prop;
|
||||
}
|
||||
|
||||
this._originProps = props;
|
||||
this.initWithDuration(duration);
|
||||
},
|
||||
|
||||
clone () {
|
||||
var action = new TweenAction(this._duration, this._originProps, this._opts);
|
||||
this._cloneDecoration(action);
|
||||
return action;
|
||||
},
|
||||
|
||||
startWithTarget (target) {
|
||||
cc.ActionInterval.prototype.startWithTarget.call(this, target);
|
||||
|
||||
let relative = !!this._opts.relative;
|
||||
let props = this._props;
|
||||
for (let name in props) {
|
||||
let value = target[name];
|
||||
let prop = props[name];
|
||||
|
||||
if (typeof value === 'number') {
|
||||
prop.start = value;
|
||||
prop.current = value;
|
||||
prop.end = relative ? value + prop.value : prop.value;
|
||||
}
|
||||
else {
|
||||
prop.start = value.clone();
|
||||
prop.current = value.clone();
|
||||
prop.end = relative ? (value.add || value.mul).call(value, prop.value) : prop.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
update (t) {
|
||||
let opts = this._opts;
|
||||
let easingTime = t;
|
||||
if (opts.easing) easingTime = opts.easing(t);
|
||||
|
||||
let target = this.target;
|
||||
if (!target) return;
|
||||
|
||||
let props = this._props;
|
||||
let progress = opts.progress;
|
||||
for (let name in props) {
|
||||
let prop = props[name];
|
||||
let time = prop.easing ? prop.easing(t) : easingTime;
|
||||
let current = prop.current = (prop.progress || progress)(prop.start, prop.end, prop.current, time);
|
||||
target[name] = current;
|
||||
}
|
||||
|
||||
let onUpdate = opts.onUpdate;
|
||||
if (onUpdate) {
|
||||
onUpdate(target, t)
|
||||
}
|
||||
},
|
||||
|
||||
progress (start, end, current, t) {
|
||||
if (typeof start === 'number') {
|
||||
current = start + (end - start) * t;
|
||||
}
|
||||
else {
|
||||
start.lerp(end, t, current);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
});
|
||||
|
||||
let SetAction = cc.Class({
|
||||
name: 'cc.SetAction',
|
||||
extends: cc.ActionInstant,
|
||||
|
||||
ctor (props) {
|
||||
this._props = {};
|
||||
props !== undefined && this.init(props);
|
||||
},
|
||||
|
||||
init (props) {
|
||||
for (let name in props) {
|
||||
this._props[name] = props[name];
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
update () {
|
||||
let props = this._props;
|
||||
let target = this.target;
|
||||
for (let name in props) {
|
||||
target[name] = props[name];
|
||||
}
|
||||
},
|
||||
|
||||
clone () {
|
||||
var action = new SetAction();
|
||||
action.init(this._props);
|
||||
return action;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Tween provide a simple and flexible way to create action. Tween's api is more flexible than `cc.Action`:
|
||||
* - Support creating an action sequence in chained api.
|
||||
* - Support animate any objects' any properties, not limited to node's properties. By contrast, `cc.Action` needs to create a new action class to support new node property.
|
||||
* - Support working with `cc.Action`.
|
||||
* - Support easing and progress function.
|
||||
* !#zh
|
||||
* Tween 提供了一个简单灵活的方法来创建 action。相对于 Cocos 传统的 `cc.Action`,`cc.Tween` 在创建动画上要灵活非常多:
|
||||
* - 支持以链式结构的方式创建一个动画序列。
|
||||
* - 支持对任意对象的任意属性进行缓动,不再局限于节点上的属性,而 `cc.Action` 添加一个属性的支持时还需要添加一个新的 action 类型。
|
||||
* - 支持与 `cc.Action` 混用。
|
||||
* - 支持设置 {{#crossLink "Easing"}}{{/crossLink}} 或者 progress 函数。
|
||||
* @class Tween
|
||||
* @example
|
||||
* cc.tween(node)
|
||||
* .to(1, {scale: 2, position: cc.v3(100, 100, 100)})
|
||||
* .call(() => { console.log('This is a callback'); })
|
||||
* .by(1, {scale: 3, position: cc.v3(200, 200, 200)}, {easing: 'sineOutIn'})
|
||||
* .start(cc.find('Canvas/cocos'));
|
||||
* @typescript Tween<T = any>
|
||||
*/
|
||||
function Tween (target) {
|
||||
this._actions = [];
|
||||
this._finalAction = null;
|
||||
this._target = target;
|
||||
this._tag = cc.Action.TAG_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @method constructor
|
||||
* @param {Object} [target]
|
||||
*/
|
||||
|
||||
/**
|
||||
* !#en Stop all tweens
|
||||
* !#zh 停止所有缓动
|
||||
* @method stopAll
|
||||
* @static
|
||||
*/
|
||||
Tween.stopAll = function () {
|
||||
cc.director.getActionManager().removeAllActions();
|
||||
}
|
||||
/**
|
||||
* !#en Stop all tweens by tag
|
||||
* !#zh 停止所有指定标签的缓动
|
||||
* @method stopAllByTag
|
||||
* @static
|
||||
* @param {number} tag
|
||||
*/
|
||||
Tween.stopAllByTag = function (tag) {
|
||||
cc.director.getActionManager().removeAllActionsByTag(tag);
|
||||
}
|
||||
/**
|
||||
* !#en Stop all tweens by target
|
||||
* !#zh 停止所有指定对象的缓动
|
||||
* @method stopAllByTarget
|
||||
* @static
|
||||
* @param {Object} target
|
||||
*/
|
||||
Tween.stopAllByTarget = function (target) {
|
||||
cc.director.getActionManager().removeAllActionsFromTarget(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Insert an action or tween to this sequence
|
||||
* !#zh
|
||||
* 插入一个 action 或者 tween 到队列中
|
||||
* @method then
|
||||
* @param {Action|Tween} other
|
||||
* @return {Tween}
|
||||
* @typescript then(other: Action|Tween<T>): Tween<T>
|
||||
*/
|
||||
Tween.prototype.then = function (other) {
|
||||
if (other instanceof cc.Action) {
|
||||
this._actions.push(other.clone());
|
||||
}
|
||||
else {
|
||||
this._actions.push(other._union());
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Set tween target
|
||||
* !#zh
|
||||
* 设置 tween 的 target
|
||||
* @method target
|
||||
* @param {Object} target
|
||||
* @return {Tween}
|
||||
* @typescript target(target: any): Tween<T>
|
||||
*/
|
||||
Tween.prototype.target = function (target) {
|
||||
this._target = target;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Start this tween
|
||||
* !#zh
|
||||
* 运行当前 tween
|
||||
* @method start
|
||||
* @return {Tween}
|
||||
* @typescript start(): Tween<T>
|
||||
*/
|
||||
Tween.prototype.start = function () {
|
||||
let target = this._target;
|
||||
if (!target) {
|
||||
cc.warn('Please set target to tween first');
|
||||
return this;
|
||||
}
|
||||
if (target instanceof cc.Object && !target.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._finalAction) {
|
||||
cc.director.getActionManager().removeAction(this._finalAction);
|
||||
}
|
||||
this._finalAction = this._union();
|
||||
|
||||
if (target._id === undefined) {
|
||||
target._id = ++_tweenID;
|
||||
}
|
||||
|
||||
this._finalAction.setTag(this._tag);
|
||||
cc.director.getActionManager().addAction(this._finalAction, target, false);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Stop this tween
|
||||
* !#zh
|
||||
* 停止当前 tween
|
||||
* @method stop
|
||||
* @return {Tween}
|
||||
* @typescript stop(): Tween<T>
|
||||
*/
|
||||
Tween.prototype.stop = function () {
|
||||
if (this._finalAction) {
|
||||
cc.director.getActionManager().removeAction(this._finalAction);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* !#en Sets tween tag
|
||||
* !#zh 设置缓动的标签
|
||||
* @method tag
|
||||
* @param {number} tag
|
||||
* @return {Tween}
|
||||
* @typescript tag(tag: number): Tween<T>
|
||||
*/
|
||||
Tween.prototype.tag = function (tag) {
|
||||
this._tag = tag;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Clone a tween
|
||||
* !#zh
|
||||
* 克隆当前 tween
|
||||
* @method clone
|
||||
* @param {Object} [target]
|
||||
* @return {Tween}
|
||||
* @typescript clone(target?: any): Tween<T>
|
||||
*/
|
||||
Tween.prototype.clone = function (target) {
|
||||
let action = this._union();
|
||||
return cc.tween(target).then(action.clone());
|
||||
};
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Integrate all previous actions to an action.
|
||||
* !#zh
|
||||
* 将之前所有的 action 整合为一个 action。
|
||||
* @method union
|
||||
* @return {Tween}
|
||||
* @typescritp union(): Tween<T>
|
||||
*/
|
||||
Tween.prototype.union = function () {
|
||||
let action = this._union();
|
||||
this._actions.length = 0;
|
||||
this._actions.push(action);
|
||||
return this;
|
||||
};
|
||||
|
||||
Tween.prototype._union = function () {
|
||||
let actions = this._actions;
|
||||
|
||||
if (actions.length === 1) {
|
||||
actions = actions[0];
|
||||
}
|
||||
else {
|
||||
actions = cc.sequence(actions);
|
||||
}
|
||||
|
||||
return actions;
|
||||
};
|
||||
|
||||
Object.assign(Tween.prototype, {
|
||||
/**
|
||||
* !#en Sets target's position property according to the bezier curve.
|
||||
* !#zh 按照贝塞尔路径设置目标的 position 属性。
|
||||
* @method bezierTo
|
||||
* @param {number} duration
|
||||
* @param {cc.Vec2} c1
|
||||
* @param {cc.Vec2} c2
|
||||
* @param {cc.Vec2} to
|
||||
* @return {Tween}
|
||||
* @typescript bezierTo(duration: number, c1: Vec2, c2: Vec2, to: Vec2): Tween<T>
|
||||
*/
|
||||
bezierTo (duration, c1, c2, to, opts) {
|
||||
let c0x = c1.x, c0y = c1.y,
|
||||
c1x = c2.x, c1y = c2.y;
|
||||
opts = opts || Object.create(null);
|
||||
opts.progress = function (start, end, current, t) {
|
||||
current.x = bezier(start.x, c0x, c1x, end.x, t);
|
||||
current.y = bezier(start.y, c0y, c1y, end.y, t);
|
||||
return current;
|
||||
}
|
||||
return this.to(duration, { position: to }, opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Sets target's position property according to the bezier curve.
|
||||
* !#zh 按照贝塞尔路径设置目标的 position 属性。
|
||||
* @method bezierBy
|
||||
* @param {number} duration
|
||||
* @param {cc.Vec2} c1
|
||||
* @param {cc.Vec2} c2
|
||||
* @param {cc.Vec2} to
|
||||
* @return {Tween}
|
||||
* @typescript bezierBy(duration: number, c1: Vec2, c2: Vec2, to: Vec2): Tween<T>
|
||||
*/
|
||||
bezierBy (duration, c1, c2, to, opts) {
|
||||
let c0x = c1.x, c0y = c1.y,
|
||||
c1x = c2.x, c1y = c2.y;
|
||||
opts = opts || Object.create(null);
|
||||
opts.progress = function (start, end, current, t) {
|
||||
let sx = start.x, sy = start.y;
|
||||
current.x = bezier(sx, c0x + sx, c1x + sx, end.x, t);
|
||||
current.y = bezier(sy, c0y + sy, c1y + sy, end.y, t);
|
||||
return current;
|
||||
}
|
||||
return this.by(duration, { position: to }, opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Flips target's scaleX
|
||||
* !#zh 翻转目标的 scaleX 属性
|
||||
* @method flipX
|
||||
* @return {Tween}
|
||||
* @typescript flipX(): Tween<T>
|
||||
*/
|
||||
flipX () {
|
||||
return this.call(() => { this._target.scaleX *= -1; }, this);
|
||||
|
||||
},
|
||||
/**
|
||||
* !#en Flips target's scaleY
|
||||
* !#zh 翻转目标的 scaleY 属性
|
||||
* @method flipY
|
||||
* @return {Tween}
|
||||
* @typescript flipY(): Tween<T>
|
||||
*/
|
||||
flipY () {
|
||||
return this.call(() => { this._target.scaleY *= -1; }, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Blinks target by set target's opacity property
|
||||
* !#zh 通过设置目标的 opacity 属性达到闪烁效果
|
||||
* @method blink
|
||||
* @param {number} duration
|
||||
* @param {number} times
|
||||
* @param {Object} [opts]
|
||||
* @param {Function} [opts.progress]
|
||||
* @param {Function|String} [opts.easing]
|
||||
* @return {Tween}
|
||||
* @typescript blink(duration: number, times: number, opts?: {progress?: Function; easing?: Function|string; }): Tween<T>
|
||||
*/
|
||||
blink (duration, times, opts) {
|
||||
var slice = 1.0 / times;
|
||||
opts = opts || Object.create(null);
|
||||
opts.progress = function (start, end, current, t) {
|
||||
if (t >= 1) {
|
||||
return start;
|
||||
}
|
||||
else {
|
||||
var m = t % slice;
|
||||
return (m > (slice / 2)) ? 255 : 0;
|
||||
}
|
||||
};
|
||||
return this.to(duration, { opacity: 1 }, opts);
|
||||
},
|
||||
})
|
||||
|
||||
let tmp_args = [];
|
||||
|
||||
function wrapAction (action) {
|
||||
return function () {
|
||||
tmp_args.length = 0;
|
||||
for (let l = arguments.length, i = 0; i < l; i++) {
|
||||
let arg = tmp_args[i] = arguments[i];
|
||||
if (arg instanceof Tween) {
|
||||
tmp_args[i] = arg._union();
|
||||
}
|
||||
}
|
||||
|
||||
return action.apply(this, tmp_args);
|
||||
};
|
||||
}
|
||||
|
||||
let actions = {
|
||||
/**
|
||||
* !#en
|
||||
* Add an action which calculate with absolute value
|
||||
* !#zh
|
||||
* 添加一个对属性进行绝对值计算的 action
|
||||
* @method to
|
||||
* @param {Number} duration
|
||||
* @param {Object} props - {scale: 2, position: cc.v3(100, 100, 100)}
|
||||
* @param {Object} [opts]
|
||||
* @param {Function} [opts.progress]
|
||||
* @param {Function|String} [opts.easing]
|
||||
* @return {Tween}
|
||||
* @typescript
|
||||
* to<OPTS extends Partial<{ progress: Function, easing: Function | String, onUpdate: Function }>>(duration: number, props: ConstructorType<T>, opts?: OPTS): Tween<T>
|
||||
*/
|
||||
to (duration, props, opts) {
|
||||
opts = opts || Object.create(null);
|
||||
opts.relative = false;
|
||||
return new TweenAction(duration, props, opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Add an action which calculate with relative value
|
||||
* !#zh
|
||||
* 添加一个对属性进行相对值计算的 action
|
||||
* @method by
|
||||
* @param {Number} duration
|
||||
* @param {Object} props - {scale: 2, position: cc.v3(100, 100, 100)}
|
||||
* @param {Object} [opts]
|
||||
* @param {Function} [opts.progress]
|
||||
* @param {Function|String} [opts.easing]
|
||||
* @return {Tween}
|
||||
* @typescript
|
||||
* by<OPTS extends Partial<{ progress: Function, easing: Function | String, onUpdate: Function }>>(duration: number, props: ConstructorType<T>, opts?: OPTS): Tween<T>
|
||||
*/
|
||||
by (duration, props, opts) {
|
||||
opts = opts || Object.create(null);
|
||||
opts.relative = true;
|
||||
return new TweenAction(duration, props, opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Directly set target properties
|
||||
* !#zh
|
||||
* 直接设置 target 的属性
|
||||
* @method set
|
||||
* @param {Object} props
|
||||
* @return {Tween}
|
||||
* @typescript
|
||||
* set (props: ConstructorType<T>) : Tween<T>
|
||||
*/
|
||||
set (props) {
|
||||
return new SetAction(props);
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Add an delay action
|
||||
* !#zh
|
||||
* 添加一个延时 action
|
||||
* @method delay
|
||||
* @param {Number} duration
|
||||
* @return {Tween}
|
||||
* @typescript delay(duration: number): Tween<T>
|
||||
*/
|
||||
delay: cc.delayTime,
|
||||
/**
|
||||
* !#en
|
||||
* Add an callback action
|
||||
* !#zh
|
||||
* 添加一个回调 action
|
||||
* @method call
|
||||
* @param {Function} callback
|
||||
* @param {object} [selectTarget]
|
||||
* @return {Tween}
|
||||
* @typescript call(callback: Function, selectTarget?: object): Tween<T>
|
||||
*/
|
||||
call: cc.callFunc,
|
||||
/**
|
||||
* !#en
|
||||
* Add an hide action
|
||||
* !#zh
|
||||
* 添加一个隐藏 action
|
||||
* @method hide
|
||||
* @return {Tween}
|
||||
* @typescript hide(): Tween<T>
|
||||
*/
|
||||
hide: cc.hide,
|
||||
/**
|
||||
* !#en
|
||||
* Add an show action
|
||||
* !#zh
|
||||
* 添加一个显示 action
|
||||
* @method show
|
||||
* @return {Tween}
|
||||
* @typescript show(): Tween<T>
|
||||
*/
|
||||
show: cc.show,
|
||||
/**
|
||||
* !#en
|
||||
* Add an removeSelf action
|
||||
* !#zh
|
||||
* 添加一个移除自己 action
|
||||
* @method removeSelf
|
||||
* @return {Tween}
|
||||
* @typescript removeSelf(): Tween<T>
|
||||
*/
|
||||
removeSelf: cc.removeSelf,
|
||||
/**
|
||||
* !#en
|
||||
* Add an sequence action
|
||||
* !#zh
|
||||
* 添加一个队列 action
|
||||
* @method sequence
|
||||
* @param {Action|Tween} action
|
||||
* @param {Action|Tween} ...actions
|
||||
* @return {Tween}
|
||||
* @typescript sequence(action: Action|Tween<T>, ...actions: (Action|Tween<T>)[]): Tween<T>
|
||||
*/
|
||||
sequence: wrapAction(cc.sequence),
|
||||
/**
|
||||
* !#en
|
||||
* Add an parallel action
|
||||
* !#zh
|
||||
* 添加一个并行 action
|
||||
* @method parallel
|
||||
* @param {Action|Tween} action
|
||||
* @param {Action|Tween} ...actions
|
||||
* @return {Tween}
|
||||
* @typescript parallel(action: Action|Tween<T>, ...actions: (Action|Tween<T>)[]): Tween<T>
|
||||
*/
|
||||
parallel: wrapAction(cc.spawn)
|
||||
};
|
||||
|
||||
// these action will use previous action as their parameters
|
||||
let previousAsInputActions = {
|
||||
/**
|
||||
* !#en
|
||||
* Add an repeat action. This action will integrate before actions to a sequence action as their parameters.
|
||||
* !#zh
|
||||
* 添加一个重复 action,这个 action 会将前一个动作作为他的参数。
|
||||
* @method repeat
|
||||
* @param {Number} repeatTimes
|
||||
* @param {Action | Tween} [action]
|
||||
* @return {Tween}
|
||||
* @typescript repeat(repeatTimes: number, action?: Action|Tween<T>): Tween<T>
|
||||
*/
|
||||
repeat: cc.repeat,
|
||||
/**
|
||||
* !#en
|
||||
* Add an repeat forever action. This action will integrate before actions to a sequence action as their parameters.
|
||||
* !#zh
|
||||
* 添加一个永久重复 action,这个 action 会将前一个动作作为他的参数。
|
||||
* @method repeatForever
|
||||
* @param {Action | Tween} [action]
|
||||
* @return {Tween}
|
||||
* @typescript repeatForever(action?: Action|Tween<T>): Tween<T>
|
||||
*/
|
||||
repeatForever: cc.repeatForever,
|
||||
/**
|
||||
* !#en
|
||||
* Add an reverse time action. This action will integrate before actions to a sequence action as their parameters.
|
||||
* !#zh
|
||||
* 添加一个倒置时间 action,这个 action 会将前一个动作作为他的参数。
|
||||
* @method reverseTime
|
||||
* @param {Action | Tween} [action]
|
||||
* @return {Tween}
|
||||
* @typescript reverseTime(action?: Action|Tween<T>): Tween<T>
|
||||
*/
|
||||
reverseTime: cc.reverseTime,
|
||||
};
|
||||
|
||||
|
||||
let keys = Object.keys(actions);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i];
|
||||
Tween.prototype[key] = function () {
|
||||
let action = actions[key].apply(this, arguments);
|
||||
this._actions.push(action);
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
keys = Object.keys(previousAsInputActions);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i];
|
||||
Tween.prototype[key] = function () {
|
||||
|
||||
let actions = this._actions;
|
||||
let action = arguments[arguments.length - 1];
|
||||
let length = arguments.length - 1;
|
||||
|
||||
if (action instanceof cc.Tween) {
|
||||
action = action._union();
|
||||
}
|
||||
else if (!(action instanceof cc.Action)) {
|
||||
action = actions[actions.length - 1];
|
||||
actions.length -= 1;
|
||||
length += 1;
|
||||
}
|
||||
|
||||
let args = [action];
|
||||
for (let i = 0; i < length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
|
||||
action = previousAsInputActions[key].apply(this, args);
|
||||
actions.push(action);
|
||||
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @module cc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @method tween
|
||||
* @param {Object} [target] - the target to animate
|
||||
* @return {Tween}
|
||||
* @typescript
|
||||
* tween<T> (target?: T) : Tween<T>
|
||||
*/
|
||||
cc.tween = function (target) {
|
||||
return new Tween(target);
|
||||
};
|
||||
|
||||
cc.Tween = Tween;
|
||||
|
Reference in New Issue
Block a user