1 /**************************************************************************** 2 Copyright (c) 2011-2012 cocos2d-x.org 3 Copyright (c) 2013-2014 Chukong Technologies Inc. 4 5 http://www.cocos2d-x.org 6 7 Permission is hereby granted, free of charge, to any person obtaining a copy 8 of this software and associated documentation files (the "Software"), to deal 9 in the Software without restriction, including without limitation the rights 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 copies of the Software, and to permit persons to whom the Software is 12 furnished to do so, subject to the following conditions: 13 14 The above copyright notice and this permission notice shall be included in 15 all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 THE SOFTWARE. 24 ****************************************************************************/ 25 26 /** 27 * Base class for ccs.ActionNode 28 * @class 29 * @extends ccs.Class 30 */ 31 ccs.ActionNode = ccs.Class.extend(/** @lends ccs.ActionNode# */{ 32 _currentFrameIndex: 0, 33 _destFrameIndex: 0, 34 _unitTime: 0, 35 _actionTag: 0, 36 _bject: null, 37 _actionSpawn: null, 38 _action: null, 39 _frameArray: null, 40 _frameArrayNum: 0, 41 ctor: function () { 42 this._currentFrameIndex = 0; 43 this._destFrameIndex = 0; 44 this._unitTime = 0.1; 45 this._actionTag = 0; 46 this._bject = null; 47 this._actionSpawn = null; 48 this._action = null; 49 this._frameArray = []; 50 this._frameArrayNum = ccs.FRAME_TYPE_MAX; 51 for (var i = 0; i < this._frameArrayNum; i++) { 52 this._frameArray.push([]); 53 } 54 }, 55 56 /** 57 * Init properties with a json dictionary 58 * @param {Object} dic 59 * @param {Object} root 60 */ 61 initWithDictionary: function (dic, root) { 62 this.setActionTag(dic["ActionTag"]); 63 var actionframelist = dic["actionframelist"]; 64 for (var i = 0; i < actionframelist.length; i++) { 65 var actionFrameDic = actionframelist[i]; 66 var frameInex = actionFrameDic["frameid"]; 67 var frameTweenType = actionFrameDic["tweenType"]; 68 var frameTweenParameterNum = actionFrameDic["tweenParameter"]; 69 70 var frameTweenParameter = []; 71 for (var j = 0; j < frameTweenParameterNum; j++){ 72 var value = actionFrameDic["tweenParameter"][j]; 73 frameTweenParameter.push(value); 74 } 75 76 if (actionFrameDic["positionx"] !== undefined) { 77 var positionX = actionFrameDic["positionx"]; 78 var positionY = actionFrameDic["positiony"]; 79 var actionFrame = new ccs.ActionMoveFrame(); 80 // actionFrame.easingType = frameTweenType; 81 // actionFrame.frameIndex = frameInex; 82 actionFrame.setEasingType(frameTweenType); 83 actionFrame.setEasingParameter(frameTweenParameter); 84 actionFrame.setPosition(positionX, positionY); 85 var actionArray = this._frameArray[ccs.FRAME_TYPE_MOVE]; 86 actionArray.push(actionFrame); 87 } 88 89 if (actionFrameDic["scalex"] !== undefined) { 90 var scaleX = actionFrameDic["scalex"]; 91 var scaleY = actionFrameDic["scaley"]; 92 var actionFrame = new ccs.ActionScaleFrame(); 93 // actionFrame.easingType = frameTweenType; 94 // actionFrame.frameIndex = frameInex; 95 actionFrame.setEasingType(frameTweenType); 96 actionFrame.setEasingParameter(frameTweenParameter); 97 actionFrame.setScaleX(scaleX); 98 actionFrame.setScaleY(scaleY); 99 var actionArray = this._frameArray[ccs.FRAME_TYPE_SCALE]; 100 actionArray.push(actionFrame); 101 } 102 103 if (actionFrameDic["rotation"] !== undefined) { 104 var rotation = actionFrameDic["rotation"]; 105 var actionFrame = new ccs.ActionRotationFrame(); 106 // actionFrame.easingType = frameTweenType; 107 // actionFrame.frameIndex = frameInex; 108 actionFrame.setEasingType(frameTweenType); 109 actionFrame.setEasingParameter(frameTweenParameter); 110 actionFrame.setRotation(rotation); 111 var actionArray = this._frameArray[ccs.FRAME_TYPE_ROTATE]; 112 actionArray.push(actionFrame); 113 } 114 115 if (actionFrameDic["opacity"] !== undefined) { 116 var opacity = actionFrameDic["opacity"]; 117 var actionFrame = new ccs.ActionFadeFrame(); 118 // actionFrame.easingType = frameTweenType; 119 // actionFrame.frameIndex = frameInex; 120 actionFrame.setEasingType(frameTweenType); 121 actionFrame.setEasingParameter(frameTweenParameter); 122 actionFrame.setOpacity(opacity); 123 var actionArray = this._frameArray[ccs.FRAME_TYPE_FADE]; 124 actionArray.push(actionFrame); 125 } 126 127 if (actionFrameDic["colorr"] !== undefined) { 128 var colorR = actionFrameDic["colorr"]; 129 var colorG = actionFrameDic["colorg"]; 130 var colorB = actionFrameDic["colorb"]; 131 var actionFrame = new ccs.ActionTintFrame(); 132 // actionFrame.easingType = frameTweenType; 133 // actionFrame.frameIndex = frameInex; 134 actionFrame.setEasingType(frameTweenType); 135 actionFrame.setEasingParameter(frameTweenParameter); 136 actionFrame.setColor(cc.color(colorR, colorG, colorB)); 137 var actionArray = this._frameArray[ccs.FRAME_TYPE_TINT]; 138 actionArray.push(actionFrame); 139 } 140 actionFrameDic = null; 141 } 142 this.initActionNodeFromRoot(root); 143 }, 144 145 initActionNodeFromRoot: function (root) { 146 if (root instanceof ccui.Widget) { 147 var widget = ccui.helper.seekActionWidgetByActionTag(root, this.getActionTag()); 148 if (widget) { 149 this.setObject(widget); 150 } 151 } 152 }, 153 154 /** 155 * Sets the time interval of frame. 156 * @param {number} time 157 */ 158 setUnitTime: function (time) { 159 this._unitTime = time; 160 this.refreshActionProperty(); 161 }, 162 163 /** 164 * Gets the time interval of frame. 165 * @returns {number} 166 */ 167 getUnitTime: function () { 168 return this._unitTime; 169 }, 170 171 /** 172 * Sets tag for ActionNode 173 * @param tag 174 */ 175 setActionTag: function (tag) { 176 this._actionTag = tag; 177 }, 178 179 /** 180 * Gets tag for ActionNode 181 * @returns {number} 182 */ 183 getActionTag: function () { 184 return this._actionTag; 185 }, 186 187 /** 188 * Sets node which will run a action. 189 * @param {Object} node 190 */ 191 setObject: function (node) { 192 this._object = node; 193 }, 194 195 /** 196 * Gets node which will run a action. 197 * @returns {*} 198 */ 199 getObject: function () { 200 return this._object; 201 }, 202 203 /** 204 * get actionNode 205 * @returns {cc.Node} 206 */ 207 getActionNode: function () { 208 if (this._object instanceof cc.Node) { 209 return this._object; 210 } 211 else if (this._object instanceof ccui.Widget) { 212 return this._object; 213 } 214 return null; 215 }, 216 217 /** 218 * Insets a ActionFrame to ActionNode. 219 * @param {number} index 220 * @param {ccs.ActionFrame} frame 221 */ 222 insertFrame: function (index, frame) { 223 if (frame == null) { 224 return; 225 } 226 var frameType = frame.frameType; 227 var array = this._frameArray[frameType]; 228 array.splice(index, 0, frame); 229 }, 230 231 /** 232 * Pushs back a ActionFrame to ActionNode. 233 * @param {ccs.ActionFrame} frame 234 */ 235 addFrame: function (frame) { 236 if (!frame) { 237 return; 238 } 239 var frameType = frame.frameType; 240 var array = this._frameArray[frameType]; 241 array.push(frame); 242 }, 243 244 /** 245 * Remove a ActionFrame from ActionNode. 246 * @param {ccs.ActionFrame} frame 247 */ 248 deleteFrame: function (frame) { 249 if (frame == null) { 250 return; 251 } 252 var frameType = frame.frameType; 253 var array = this._frameArray[frameType]; 254 cc.arrayRemoveObject(array, frame); 255 }, 256 257 /** 258 * Remove all ActionFrames from ActionNode. 259 */ 260 clearAllFrame: function () { 261 for (var i = 0; i < this._frameArrayNum; i++) { 262 this._frameArray[i] = []; 263 } 264 }, 265 266 /** 267 * Refresh property of action 268 * @returns {null} 269 */ 270 refreshActionProperty: function () { 271 if (this._object == null) { 272 return null; 273 } 274 var locSpawnArray = []; 275 for (var i = 0; i < this._frameArrayNum; i++) { 276 var locArray = this._frameArray[i]; 277 if (locArray.length <= 0) { 278 continue; 279 } 280 var locSequenceArray = []; 281 for (var j = 0; j < locArray.length; j++) { 282 var locFrame = locArray[j]; 283 if (j != 0) { 284 var locSrcFrame = locArray[j - 1]; 285 var locDuration = (locFrame.frameIndex - locSrcFrame.frameIndex) * this.getUnitTime(); 286 var locAction = locFrame.getAction(locDuration); 287 if(locAction){ 288 locSequenceArray.push(locAction); 289 } 290 } 291 } 292 if(locSequenceArray){ 293 var locSequence = cc.Sequence.create(locSequenceArray); 294 if (locSequence != null) { 295 locSpawnArray.push(locSequence); 296 } 297 } 298 } 299 300 this._action = null; 301 this._actionSpawn = cc.Spawn.create(locSpawnArray); 302 return this._actionSpawn; 303 }, 304 305 /** 306 * Play the action. 307 * @param {Boolean} loop 308 * @param {cc.CallFunc} fun 309 */ 310 playAction: function (fun) { 311 if (this._object == null || this._actionSpawn == null) { 312 return; 313 } 314 if(fun){ 315 this._action = cc.Sequence.create(this._actionSpawn,fun); 316 }else{ 317 this._action = cc.Sequence.create(this._actionSpawn); 318 } 319 this.runAction(); 320 }, 321 322 /** 323 * Run action. 324 */ 325 runAction: function () { 326 var node = this.getActionNode(); 327 if (node != null && this._action != null) { 328 node.runAction(this._action); 329 } 330 }, 331 332 /** 333 * Stop action. 334 */ 335 stopAction: function () { 336 var node = this.getActionNode(); 337 if (node != null && this._action != null) { 338 if(!this._action.isDone()) 339 node.stopAction(this._action); 340 } 341 }, 342 343 /** 344 * Gets index of first ActionFrame. 345 * @returns {number} 346 */ 347 getFirstFrameIndex: function () { 348 var locFrameindex = 99999; 349 var locIsFindFrame = false; 350 for (var i = 0; i < this._frameArrayNum; i++) { 351 var locArray = this._frameArray[i]; 352 if (locArray.length <= 0) { 353 continue; 354 } 355 locIsFindFrame = true; 356 var locFrame = locArray[0]; 357 var locFrameIndex = locFrame.frameIndex; 358 locFrameindex = locFrameindex > locFrameIndex ? locFrameIndex : locFrameindex; 359 } 360 if (!locIsFindFrame) { 361 locFrameindex = 0; 362 } 363 return locFrameindex; 364 }, 365 366 /** 367 * Gets index of last ActionFrame. 368 * @returns {number} 369 */ 370 getLastFrameIndex: function () { 371 var locFrameindex = -1; 372 var locIsFindFrame = false; 373 for (var i = 0; i < this._frameArrayNum; i++) { 374 var locArray = this._frameArray[i]; 375 if (locArray.length <= 0) { 376 continue; 377 } 378 locIsFindFrame = true; 379 var locFrame = locArray[locArray.length - 1]; 380 var locFrameIndex = locFrame.frameIndex; 381 locFrameindex = locFrameindex < locFrameIndex ? locFrameIndex : locFrameindex; 382 } 383 if (!locIsFindFrame) { 384 locFrameindex = 0; 385 } 386 return locFrameindex; 387 }, 388 389 /** 390 * Updates action states to some time. 391 * @param time 392 * @returns {boolean} 393 */ 394 updateActionToTimeLine: function (time) { 395 var locIsFindFrame = false; 396 var locUnitTime = this.getUnitTime(); 397 for (var i = 0; i < this._frameArrayNum; i++) { 398 var locArray = this._frameArray[i]; 399 if (locArray == null) { 400 continue; 401 } 402 403 for (var j = 0; j < locArray.length; j++) { 404 var locFrame = locArray[j]; 405 if (locFrame.frameIndex * locUnitTime == time) { 406 this.easingToFrame(1.0, 1.0, locFrame); 407 locIsFindFrame = true; 408 break; 409 } 410 else if (locFrame.frameIndex * locUnitTime > time) { 411 if (j == 0) { 412 this.easingToFrame(1.0, 1.0, locFrame); 413 locIsFindFrame = false; 414 } 415 else { 416 var locSrcFrame = locArray[j - 1]; 417 var locDuration = (locFrame.frameIndex - locSrcFrame.frameIndex) * locUnitTime; 418 var locDelaytime = time - locSrcFrame.frameIndex * locUnitTime; 419 this.easingToFrame(locDuration, 1.0, locSrcFrame); 420 this.easingToFrame(locDuration, locDelaytime / locDuration, locFrame); 421 locIsFindFrame = true; 422 } 423 break; 424 } 425 } 426 } 427 return locIsFindFrame; 428 }, 429 430 /** 431 * Easing to frame 432 * @param {number} duration 433 * @param {number} delayTime 434 * @param {ccs.ActionFrame} destFrame 435 */ 436 easingToFrame: function (duration, delayTime, destFrame) { 437 var action = destFrame.getAction(duration); 438 var node = this.getActionNode(); 439 if (action == null || node == null) { 440 return; 441 } 442 action.startWithTarget(node); 443 action.update(delayTime); 444 }, 445 446 isActionDoneOnce: function () { 447 if (this._action == null) { 448 return true; 449 } 450 return this._action.isDone(); 451 } 452 });