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 if(frameTweenType == null) 69 frameTweenType = 0; 70 var frameTweenParameterNum = actionFrameDic["tweenParameter"]; 71 72 var frameTweenParameter = []; 73 for (var j = 0; j < frameTweenParameterNum; j++){ 74 var value = actionFrameDic["tweenParameter"][j]; 75 frameTweenParameter.push(value); 76 } 77 78 var actionFrame, actionArray; 79 if (actionFrameDic["positionx"] !== undefined) { 80 var positionX = actionFrameDic["positionx"]; 81 var positionY = actionFrameDic["positiony"]; 82 actionFrame = new ccs.ActionMoveFrame(); 83 actionFrame.frameIndex = frameInex; 84 actionFrame.setEasingType(frameTweenType); 85 actionFrame.setEasingParameter(frameTweenParameter); 86 actionFrame.setPosition(positionX, positionY); 87 actionArray = this._frameArray[ccs.FRAME_TYPE_MOVE]; 88 actionArray.push(actionFrame); 89 } 90 91 if (actionFrameDic["scalex"] !== undefined) { 92 var scaleX = actionFrameDic["scalex"]; 93 var scaleY = actionFrameDic["scaley"]; 94 actionFrame = new ccs.ActionScaleFrame(); 95 actionFrame.frameIndex = frameInex; 96 actionFrame.setEasingType(frameTweenType); 97 actionFrame.setEasingParameter(frameTweenParameter); 98 actionFrame.setScaleX(scaleX); 99 actionFrame.setScaleY(scaleY); 100 actionArray = this._frameArray[ccs.FRAME_TYPE_SCALE]; 101 actionArray.push(actionFrame); 102 } 103 104 if (actionFrameDic["rotation"] !== undefined) { 105 var rotation = actionFrameDic["rotation"]; 106 actionFrame = new ccs.ActionRotationFrame(); 107 actionFrame.frameIndex = frameInex; 108 actionFrame.setEasingType(frameTweenType); 109 actionFrame.setEasingParameter(frameTweenParameter); 110 actionFrame.setRotation(rotation); 111 actionArray = this._frameArray[ccs.FRAME_TYPE_ROTATE]; 112 actionArray.push(actionFrame); 113 } 114 115 if (actionFrameDic["opacity"] !== undefined) { 116 var opacity = actionFrameDic["opacity"]; 117 actionFrame = new ccs.ActionFadeFrame(); 118 actionFrame.frameIndex = frameInex; 119 actionFrame.setEasingType(frameTweenType); 120 actionFrame.setEasingParameter(frameTweenParameter); 121 actionFrame.setOpacity(opacity); 122 actionArray = this._frameArray[ccs.FRAME_TYPE_FADE]; 123 actionArray.push(actionFrame); 124 } 125 126 if (actionFrameDic["colorr"] !== undefined) { 127 var colorR = actionFrameDic["colorr"]; 128 var colorG = actionFrameDic["colorg"]; 129 var colorB = actionFrameDic["colorb"]; 130 actionFrame = new ccs.ActionTintFrame(); 131 actionFrame.frameIndex = frameInex; 132 actionFrame.setEasingType(frameTweenType); 133 actionFrame.setEasingParameter(frameTweenParameter); 134 actionFrame.setColor(cc.color(colorR, colorG, colorB)); 135 actionArray = this._frameArray[ccs.FRAME_TYPE_TINT]; 136 actionArray.push(actionFrame); 137 } 138 actionFrameDic = null; 139 } 140 this.initActionNodeFromRoot(root); 141 }, 142 143 initActionNodeFromRoot: function (root) { 144 if (root instanceof ccui.Widget) { 145 var widget = ccui.helper.seekActionWidgetByActionTag(root, this.getActionTag()); 146 if (widget) { 147 this.setObject(widget); 148 } 149 } 150 }, 151 152 /** 153 * Sets the time interval of frame. 154 * @param {number} time 155 */ 156 setUnitTime: function (time) { 157 this._unitTime = time; 158 this.refreshActionProperty(); 159 }, 160 161 /** 162 * Gets the time interval of frame. 163 * @returns {number} 164 */ 165 getUnitTime: function () { 166 return this._unitTime; 167 }, 168 169 /** 170 * Sets tag for ActionNode 171 * @param tag 172 */ 173 setActionTag: function (tag) { 174 this._actionTag = tag; 175 }, 176 177 /** 178 * Gets tag for ActionNode 179 * @returns {number} 180 */ 181 getActionTag: function () { 182 return this._actionTag; 183 }, 184 185 /** 186 * Sets node which will run a action. 187 * @param {Object} node 188 */ 189 setObject: function (node) { 190 this._object = node; 191 }, 192 193 /** 194 * Gets node which will run a action. 195 * @returns {*} 196 */ 197 getObject: function () { 198 return this._object; 199 }, 200 201 /** 202 * get actionNode 203 * @returns {cc.Node} 204 */ 205 getActionNode: function () { 206 if (this._object instanceof cc.Node) { 207 return this._object; 208 } 209 else if (this._object instanceof ccui.Widget) { 210 return this._object; 211 } 212 return null; 213 }, 214 215 /** 216 * Insets a ActionFrame to ActionNode. 217 * @param {number} index 218 * @param {ccs.ActionFrame} frame 219 */ 220 insertFrame: function (index, frame) { 221 if (frame == null) { 222 return; 223 } 224 var frameType = frame.frameType; 225 var array = this._frameArray[frameType]; 226 array.splice(index, 0, frame); 227 }, 228 229 /** 230 * Pushs back a ActionFrame to ActionNode. 231 * @param {ccs.ActionFrame} frame 232 */ 233 addFrame: function (frame) { 234 if (!frame) { 235 return; 236 } 237 var frameType = frame.frameType; 238 var array = this._frameArray[frameType]; 239 array.push(frame); 240 }, 241 242 /** 243 * Remove a ActionFrame from ActionNode. 244 * @param {ccs.ActionFrame} frame 245 */ 246 deleteFrame: function (frame) { 247 if (frame == null) { 248 return; 249 } 250 var frameType = frame.frameType; 251 var array = this._frameArray[frameType]; 252 cc.arrayRemoveObject(array, frame); 253 }, 254 255 /** 256 * Remove all ActionFrames from ActionNode. 257 */ 258 clearAllFrame: function () { 259 for (var i = 0; i < this._frameArrayNum; i++) { 260 this._frameArray[i] = []; 261 } 262 }, 263 264 /** 265 * Refresh property of action 266 * @returns {null} 267 */ 268 refreshActionProperty: function () { 269 if (this._object == null) { 270 return null; 271 } 272 var locSpawnArray = []; 273 for (var i = 0; i < this._frameArrayNum; i++) { 274 var locArray = this._frameArray[i]; 275 if (locArray.length <= 0) { 276 continue; 277 } 278 var locSequenceArray = []; 279 for (var j = 0; j < locArray.length; j++) { 280 var locFrame = locArray[j]; 281 if (j != 0) { 282 var locSrcFrame = locArray[j - 1]; 283 var locDuration = (locFrame.frameIndex - locSrcFrame.frameIndex) * this.getUnitTime(); 284 var locAction = locFrame.getAction(locDuration); 285 if(locAction){ 286 locSequenceArray.push(locAction); 287 } 288 } 289 } 290 if(locSequenceArray){ 291 var locSequence = cc.sequence(locSequenceArray); 292 if (locSequence != null) { 293 locSpawnArray.push(locSequence); 294 } 295 } 296 } 297 298 this._action = null; 299 this._actionSpawn = cc.spawn(locSpawnArray); 300 return this._actionSpawn; 301 }, 302 303 /** 304 * Play the action. 305 * @param {cc.CallFunc} fun 306 */ 307 playAction: function (fun) { 308 if (this._object == null || this._actionSpawn == null) { 309 return; 310 } 311 if(fun){ 312 this._action = cc.sequence(this._actionSpawn,fun); 313 }else{ 314 this._action = cc.sequence(this._actionSpawn); 315 } 316 this.runAction(); 317 }, 318 319 /** 320 * Run action. 321 */ 322 runAction: function () { 323 var node = this.getActionNode(); 324 if (node != null && this._action != null) { 325 node.runAction(this._action); 326 } 327 }, 328 329 /** 330 * Stop action. 331 */ 332 stopAction: function () { 333 var node = this.getActionNode(); 334 if (node != null && this._action != null) { 335 if(!this._action.isDone()) 336 node.stopAction(this._action); 337 } 338 }, 339 340 /** 341 * Gets index of first ActionFrame. 342 * @returns {number} 343 */ 344 getFirstFrameIndex: function () { 345 var locFrameindex = 99999; 346 var locIsFindFrame = false; 347 for (var i = 0; i < this._frameArrayNum; i++) { 348 var locArray = this._frameArray[i]; 349 if (locArray.length <= 0) { 350 continue; 351 } 352 locIsFindFrame = true; 353 var locFrame = locArray[0]; 354 var locFrameIndex = locFrame.frameIndex; 355 locFrameindex = locFrameindex > locFrameIndex ? locFrameIndex : locFrameindex; 356 } 357 if (!locIsFindFrame) { 358 locFrameindex = 0; 359 } 360 return locFrameindex; 361 }, 362 363 /** 364 * Gets index of last ActionFrame. 365 * @returns {number} 366 */ 367 getLastFrameIndex: function () { 368 var locFrameindex = -1; 369 var locIsFindFrame = false; 370 for (var i = 0; i < this._frameArrayNum; i++) { 371 var locArray = this._frameArray[i]; 372 if (locArray.length <= 0) { 373 continue; 374 } 375 locIsFindFrame = true; 376 var locFrame = locArray[locArray.length - 1]; 377 var locFrameIndex = locFrame.frameIndex; 378 locFrameindex = locFrameindex < locFrameIndex ? locFrameIndex : locFrameindex; 379 } 380 if (!locIsFindFrame) { 381 locFrameindex = 0; 382 } 383 return locFrameindex; 384 }, 385 386 /** 387 * Updates action states to some time. 388 * @param time 389 * @returns {boolean} 390 */ 391 updateActionToTimeLine: function (time) { 392 var locIsFindFrame = false; 393 var locUnitTime = this.getUnitTime(); 394 for (var i = 0; i < this._frameArrayNum; i++) { 395 var locArray = this._frameArray[i]; 396 if (locArray == null) { 397 continue; 398 } 399 400 for (var j = 0; j < locArray.length; j++) { 401 var locFrame = locArray[j]; 402 if (locFrame.frameIndex * locUnitTime == time) { 403 this.easingToFrame(1.0, 1.0, locFrame); 404 locIsFindFrame = true; 405 break; 406 } 407 else if (locFrame.frameIndex * locUnitTime > time) { 408 if (j == 0) { 409 this.easingToFrame(1.0, 1.0, locFrame); 410 locIsFindFrame = false; 411 } 412 else { 413 var locSrcFrame = locArray[j - 1]; 414 var locDuration = (locFrame.frameIndex - locSrcFrame.frameIndex) * locUnitTime; 415 var locDelaytime = time - locSrcFrame.frameIndex * locUnitTime; 416 this.easingToFrame(locDuration, 1.0, locSrcFrame); 417 this.easingToFrame(locDuration, locDelaytime / locDuration, locFrame); 418 locIsFindFrame = true; 419 } 420 break; 421 } 422 } 423 } 424 return locIsFindFrame; 425 }, 426 427 /** 428 * Easing to frame 429 * @param {number} duration 430 * @param {number} delayTime 431 * @param {ccs.ActionFrame} destFrame 432 */ 433 easingToFrame: function (duration, delayTime, destFrame) { 434 var action = destFrame.getAction(duration); 435 var node = this.getActionNode(); 436 if (action == null || node == null) { 437 return; 438 } 439 action.startWithTarget(node); 440 action.update(delayTime); 441 }, 442 443 isActionDoneOnce: function () { 444 if (this._action == null) { 445 return true; 446 } 447 return this._action.isDone(); 448 } 449 });