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