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 * @ignore 28 */ 29 ccs.CONST_VERSION = "version"; 30 ccs.CONST_VERSION_2_0 = 2.0; 31 ccs.CONST_VERSION_COMBINED = 0.3; 32 33 ccs.CONST_SKELETON = "skeleton"; 34 ccs.CONST_ARMATURES = "armatures"; 35 ccs.CONST_ARMATURE = "armature"; 36 ccs.CONST_BONE = "b"; 37 ccs.CONST_DISPLAY = "d"; 38 39 ccs.CONST_ANIMATIONS = "animations"; 40 ccs.CONST_ANIMATION = "animation"; 41 ccs.CONST_MOVEMENT = "mov"; 42 ccs.CONST_FRAME = "f"; 43 44 ccs.CONST_TEXTURE_ATLAS = "TextureAtlas"; 45 ccs.CONST_SUB_TEXTURE = "SubTexture"; 46 47 ccs.CONST_A_NAME = "name"; 48 ccs.CONST_A_DURATION = "dr"; 49 ccs.CONST_A_FRAME_INDEX = "fi"; 50 ccs.CONST_A_DURATION_TO = "to"; 51 ccs.CONST_A_DURATION_TWEEN = "drTW"; 52 ccs.CONST_A_LOOP = "lp"; 53 ccs.CONST_A_MOVEMENT_SCALE = "sc"; 54 ccs.CONST_A_MOVEMENT_DELAY = "dl"; 55 ccs.CONST_A_DISPLAY_INDEX = "dI"; 56 57 ccs.CONST_A_VERT = "vert"; 58 ccs.CONST_A_FRAG = "frag"; 59 ccs.CONST_A_PLIST = "plist"; 60 61 ccs.CONST_A_PARENT = "parent"; 62 ccs.CONST_A_SKEW_X = "kX"; 63 ccs.CONST_A_SKEW_Y = "kY"; 64 ccs.CONST_A_SCALE_X = "cX"; 65 ccs.CONST_A_SCALE_Y = "cY"; 66 ccs.CONST_A_Z = "z"; 67 ccs.CONST_A_EVENT = "evt"; 68 ccs.CONST_A_SOUND = "sd"; 69 ccs.CONST_A_SOUND_EFFECT = "sdE"; 70 ccs.CONST_A_TWEEN_EASING = "twE"; 71 ccs.CONST_A_TWEEN_ROTATION = "twR"; 72 ccs.CONST_A_EASING_PARAM = "twEP"; 73 ccs.CONST_A_IS_ARMATURE = "isArmature"; 74 ccs.CONST_A_DISPLAY_TYPE = "displayType"; 75 ccs.CONST_A_MOVEMENT = "mov"; 76 ccs.CONST_A_BLEND_TYPE = "bd"; 77 ccs.CONST_A_BLEND_SRC = "bd_src"; 78 ccs.CONST_A_BLEND_DST = "bd_dst"; 79 80 ccs.CONST_A_X = "x"; 81 ccs.CONST_A_Y = "y"; 82 83 ccs.CONST_A_COCOS2DX_X = "cocos2d_x"; 84 ccs.CONST_A_COCOS2DX_Y = "cocos2d_y"; 85 86 ccs.CONST_A_WIDTH = "width"; 87 ccs.CONST_A_HEIGHT = "height"; 88 ccs.CONST_A_PIVOT_X = "pX"; 89 ccs.CONST_A_PIVOT_Y = "pY"; 90 91 ccs.CONST_A_COCOS2D_PIVOT_X = "cocos2d_pX"; 92 ccs.CONST_A_COCOS2D_PIVOT_Y = "cocos2d_pY"; 93 94 ccs.CONST_A_ALPHA = "a"; 95 ccs.CONST_A_RED = "r"; 96 ccs.CONST_A_GREEN = "g"; 97 ccs.CONST_A_BLUE = "b"; 98 ccs.CONST_A_ALPHA_OFFSET = "aM"; 99 ccs.CONST_A_RED_OFFSET = "rM"; 100 ccs.CONST_A_GREEN_OFFSET = "gM"; 101 ccs.CONST_A_BLUE_OFFSET = "bM"; 102 ccs.CONST_A_COLOR_TRANSFORM = "colorTransform"; 103 ccs.CONST_A_TWEEN_FRAME = "tweenFrame"; 104 ccs.CONST_A_ROTATION = "rotation"; 105 ccs.CONST_A_USE_COLOR_INFO = "uci"; 106 107 ccs.CONST_CONTOUR = "con"; 108 ccs.CONST_CONTOUR_VERTEX = "con_vt"; 109 110 ccs.CONST_MOVEMENT_EVENT_FRAME = "movementEventFrame"; 111 ccs.CONST_SOUND_FRAME = "soundFrame"; 112 113 ccs.CONST_FL_NAN = "NaN"; 114 115 ccs.CONST_FRAME_DATA = "frame_data"; 116 ccs.CONST_MOVEMENT_BONE_DATA = "mov_bone_data"; 117 ccs.CONST_MOVEMENT_FRAME_DATA = "mov_frame_data"; 118 ccs.CONST_MOVEMENT_DATA = "mov_data"; 119 ccs.CONST_ANIMATION_DATA = "animation_data"; 120 ccs.CONST_DISPLAY_DATA = "display_data"; 121 ccs.CONST_SKIN_DATA = "skin_data"; 122 ccs.CONST_BONE_DATA = "bone_data"; 123 ccs.CONST_ARMATURE_DATA = "armature_data"; 124 ccs.CONST_CONTOUR_DATA = "contour_data"; 125 ccs.CONST_TEXTURE_DATA = "texture_data"; 126 ccs.CONST_VERTEX_POINT = "vertex"; 127 ccs.CONST_COLOR_INFO = "color"; 128 129 ccs.CONST_CONFIG_FILE_PATH = "config_file_path"; 130 ccs.CONST_CONTENT_SCALE = "content_scale"; 131 132 /** 133 * @ignore 134 * @constructor 135 */ 136 ccs.DataInfo = function () { 137 this.asyncStruct = null; 138 this.configFileQueue = []; 139 this.contentScale = 1; 140 this.filename = ""; 141 this.baseFilePath = ""; 142 this.flashToolVersion = 0; 143 this.cocoStudioVersion = 0 144 }; 145 146 /** 147 * CocoStudio data reader helper 148 * @namespace 149 * @name ccs.dataReaderHelper 150 */ 151 ccs.dataReaderHelper = /** @lends ccs.dataReaderHelper# */{ 152 _configFileList: [], 153 _flashToolVersion: ccs.CONST_VERSION_2_0, 154 _cocoStudioVersion: ccs.CONST_VERSION_COMBINED, 155 _positionReadScale: 1, 156 _asyncRefCount: 0, 157 _asyncRefTotalCount: 0, 158 159 setPositionReadScale: function (scale) { 160 this._positionReadScale = scale; 161 }, 162 163 getPositionReadScale: function () { 164 return this._positionReadScale; 165 }, 166 167 clear: function () { 168 this._configFileList = []; 169 this._asyncRefCount = 0; 170 this._asyncRefTotalCount = 0; 171 }, 172 173 addDataFromFile: function (filePath, isLoadSpriteFrame) { 174 if (this._configFileList.indexOf(filePath) != -1) { 175 return; 176 } 177 this._configFileList.push(filePath); 178 179 this._initBaseFilePath(filePath); 180 181 var str = cc.path.extname(filePath).toLowerCase(); 182 183 var dataInfo = new ccs.DataInfo(); 184 dataInfo.filename = filePath; 185 dataInfo.basefilePath = this._initBaseFilePath(filePath); 186 if (str == ".xml") { 187 this.addDataFromXML(filePath, dataInfo); 188 } 189 else if (str == ".json" || str == ".exportjson") { 190 this.addDataFromJson(filePath, dataInfo, isLoadSpriteFrame); 191 } 192 }, 193 194 addDataFromFileAsync: function (filePath, target, selector, isLoadSpriteFrame) { 195 if (this._configFileList.indexOf(filePath) != -1) { 196 if (target && selector) { 197 if (this._asyncRefTotalCount == 0 && this._asyncRefCount == 0) 198 this._asyncCallBack(target, selector, 1); 199 else 200 this._asyncCallBack(target, selector, (this._asyncRefTotalCount - this._asyncRefCount) / this._asyncRefTotalCount); 201 } 202 return; 203 } 204 this._asyncRefTotalCount++; 205 this._asyncRefCount++; 206 var self = this; 207 var fun = function () { 208 self.addDataFromFile(filePath, isLoadSpriteFrame); 209 self._asyncRefCount--; 210 self._asyncCallBack(target, selector, (self._asyncRefTotalCount - self._asyncRefCount) / self._asyncRefTotalCount); 211 }; 212 cc.director.getScheduler().scheduleCallbackForTarget(this, fun, 0.1, false); 213 }, 214 215 _asyncCallBack: function (target, selector, percent) { 216 if (target && (typeof(selector) == "string")) { 217 target[selector](percent); 218 } else if (target && (typeof(selector) == "function")) { 219 selector.call(target, percent); 220 } 221 }, 222 /** 223 * find the base file path 224 * @param filePath 225 * @returns {String} 226 * @private 227 */ 228 _initBaseFilePath: function (filePath) { 229 var path = filePath; 230 var pos = path.lastIndexOf("/"); 231 if (pos > -1) 232 path = path.substr(0, pos + 1); 233 else 234 path = ""; 235 return path; 236 }, 237 238 addDataFromXML: function (xml, dataInfo) { 239 /* 240 * Need to get the full path of the xml file, or the Tiny XML can't find the xml at IOS 241 */ 242 var xmlStr = cc.loader.getRes(xml); 243 if (!xmlStr) throw "Please load the resource first : " + xml; 244 var skeletonXML = cc.saxParser.parse(xmlStr); 245 var skeleton = skeletonXML.documentElement; 246 if (skeleton) { 247 this.addDataFromCache(skeleton, dataInfo); 248 } 249 }, 250 251 addDataFromCache: function (skeleton, dataInfo) { 252 if (!skeleton) { 253 cc.log("XML error or XML is empty."); 254 return; 255 } 256 dataInfo.flashToolVersion = parseFloat(skeleton.getAttribute(ccs.CONST_VERSION)); 257 var armaturesXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_ARMATURES + " > " + ccs.CONST_ARMATURE + ""); 258 var armatureDataManager = ccs.armatureDataManager; 259 for (var i = 0; i < armaturesXML.length; i++) { 260 var armatureData = this.decodeArmature(armaturesXML[i], dataInfo); 261 armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename); 262 } 263 264 var animationsXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_ANIMATIONS + " > " + ccs.CONST_ANIMATION + ""); 265 for (var i = 0; i < animationsXML.length; i++) { 266 var animationData = this.decodeAnimation(animationsXML[i], dataInfo); 267 armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename); 268 } 269 270 var texturesXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_TEXTURE_ATLAS + " > " + ccs.CONST_SUB_TEXTURE + ""); 271 for (var i = 0; i < texturesXML.length; i++) { 272 var textureData = this.decodeTexture(texturesXML[i], dataInfo); 273 armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename); 274 } 275 skeleton = null; 276 }, 277 278 decodeArmature: function (armatureXML, dataInfo) { 279 var name = armatureXML.getAttribute(ccs.CONST_A_NAME); 280 var armatureData = new ccs.ArmatureData(); 281 armatureData.name = name; 282 283 var bonesXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE + " > " + ccs.CONST_BONE); 284 285 for (var i = 0; i < bonesXML.length; i++) { 286 var boneXML = bonesXML[i]; 287 var parentName = boneXML.getAttribute(ccs.CONST_A_PARENT); 288 var parentXML = null; 289 if (parentName) { 290 //parentXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE+" > "+ccs.CONST_BONE); 291 for (var j = 0; j < bonesXML.length; j++) { 292 parentXML = bonesXML[j]; 293 if (parentName == bonesXML[j].getAttribute(ccs.CONST_A_NAME)) { 294 //todo 295 break; 296 } 297 } 298 } 299 var boneData = this.decodeBone(boneXML, parentXML, dataInfo); 300 armatureData.addBoneData(boneData); 301 } 302 return armatureData; 303 }, 304 305 decodeBone: function (boneXML, parentXML, dataInfo) { 306 307 var name = boneXML.getAttribute(ccs.CONST_A_NAME); 308 if (name == "") { 309 return; 310 } 311 var boneData = new ccs.BoneData(); 312 boneData.name = name; 313 boneData.parentName = boneXML.getAttribute(ccs.CONST_A_PARENT) || ""; 314 boneData.zOrder = parseInt(boneXML.getAttribute(ccs.CONST_A_Z)) || 0; 315 316 var displaysXML = boneXML.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_DISPLAY); 317 318 var displayXML; 319 for (var i = 0; i < displaysXML.length; i++) { 320 displayXML = displaysXML[i]; 321 var displayData = this.decodeBoneDisplay(displayXML, dataInfo); 322 boneData.addDisplayData(displayData); 323 } 324 return boneData; 325 }, 326 decodeBoneDisplay: function (displayXML, dataInfo) { 327 var isArmature = parseFloat(displayXML.getAttribute(ccs.CONST_A_IS_ARMATURE)) || 0; 328 var displayData = null; 329 330 if (isArmature == 1) { 331 displayData = new ccs.ArmatureDisplayData(); 332 displayData.displayType = ccs.DISPLAY_TYPE_ARMATURE; 333 } 334 else { 335 displayData = new ccs.SpriteDisplayData(); 336 displayData.displayType = ccs.DISPLAY_TYPE_SPRITE; 337 } 338 var displayName = displayXML.getAttribute(ccs.CONST_A_NAME) || ""; 339 if (displayName) { 340 displayData.displayName = displayName; 341 } 342 return displayData; 343 }, 344 345 346 decodeAnimation: function (animationXML, dataInfo) { 347 var name = animationXML.getAttribute(ccs.CONST_A_NAME); 348 var aniData = new ccs.AnimationData(); 349 var armatureData = ccs.armatureDataManager.getArmatureData(name); 350 aniData.name = name; 351 352 var movementsXML = animationXML.querySelectorAll(ccs.CONST_ANIMATION + " > " + ccs.CONST_MOVEMENT); 353 var movementXML = null; 354 for (var i = 0; i < movementsXML.length; i++) { 355 movementXML = movementsXML[i]; 356 var movementData = this.decodeMovement(movementXML, armatureData, dataInfo); 357 aniData.addMovement(movementData); 358 } 359 return aniData; 360 }, 361 362 decodeMovement: function (movementXML, armatureData, dataInfo) { 363 var movName = movementXML.getAttribute(ccs.CONST_A_NAME); 364 var movementData = new ccs.MovementData(); 365 movementData.name = movName; 366 var duration, durationTo, durationTween, loop = 0, tweenEasing = 0; 367 368 duration = parseFloat(movementXML.getAttribute(ccs.CONST_A_DURATION)) || 0; 369 movementData.duration = duration; 370 371 durationTo = parseFloat(movementXML.getAttribute(ccs.CONST_A_DURATION_TO)) || 0; 372 movementData.durationTo = durationTo; 373 374 durationTween = parseFloat(movementXML.getAttribute(ccs.CONST_A_DURATION_TWEEN)) || 0; 375 movementData.durationTween = durationTween; 376 377 loop = movementXML.getAttribute(ccs.CONST_A_LOOP); 378 movementData.loop = loop ? Boolean(parseFloat(loop)) : true; 379 380 var easing = movementXML.getAttribute(ccs.CONST_A_TWEEN_EASING); 381 if (easing) { 382 if (easing != ccs.CONST_FL_NAN) { 383 tweenEasing = parseFloat(easing) || 0; 384 movementData.tweenEasing = tweenEasing == 2 ? ccs.TweenType.sineEaseInOut : tweenEasing; 385 } else { 386 movementData.tweenEasing = ccs.TweenType.linear; 387 } 388 } 389 390 var movBonesXml = movementXML.querySelectorAll(ccs.CONST_MOVEMENT + " > " + ccs.CONST_BONE); 391 var movBoneXml = null; 392 for (var i = 0; i < movBonesXml.length; i++) { 393 movBoneXml = movBonesXml[i]; 394 var boneName = movBoneXml.getAttribute(ccs.CONST_A_NAME); 395 396 if (movementData.getMovementBoneData(boneName)) { 397 continue; 398 } 399 400 var boneData = armatureData.getBoneData(boneName); 401 var parentName = boneData.parentName; 402 403 var parentXML = null; 404 if (parentName != "") { 405 for (var j = 0; j < movBonesXml.length; j++) { 406 parentXML = movBonesXml[j]; 407 if (parentName == parentXML.getAttribute(ccs.CONST_A_NAME)) { 408 break; 409 } 410 } 411 } 412 var moveBoneData = this.decodeMovementBone(movBoneXml, parentXML, boneData, dataInfo); 413 movementData.addMovementBoneData(moveBoneData); 414 } 415 return movementData; 416 }, 417 418 decodeMovementBone: function (movBoneXml, parentXml, boneData, dataInfo) { 419 var movBoneData = new ccs.MovementBoneData(); 420 var scale, delay; 421 422 if (movBoneXml) { 423 scale = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_SCALE)) || 0; 424 movBoneData.scale = scale; 425 426 delay = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_DELAY)) || 0; 427 if (delay > 0) { 428 delay -= 1; 429 } 430 movBoneData.delay = delay; 431 } 432 433 var length = 0; 434 var parentTotalDuration = 0; 435 var currentDuration = 0; 436 var parentFrameXML = null; 437 var parentXMLList = []; 438 439 //* get the parent frame xml list, we need get the origin data 440 if (parentXml != null) { 441 var parentFramesXML = parentXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME); 442 for (var i = 0; i < parentFramesXML.length; i++) { 443 parentXMLList.push(parentFramesXML[i]); 444 } 445 length = parentXMLList.length; 446 } 447 448 449 var totalDuration = 0; 450 451 var name = movBoneXml.getAttribute(ccs.CONST_A_NAME); 452 movBoneData.name = name; 453 var framesXML = movBoneXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME); 454 var j = 0; 455 for (var ii = 0; ii < framesXML.length; ii++) { 456 var frameXML = framesXML[ii]; 457 if (parentXml) { 458 //* in this loop we get the corresponding parent frame xml 459 while (j < length && (parentFrameXML ? (totalDuration < parentTotalDuration || totalDuration >= parentTotalDuration + currentDuration) : true)) { 460 parentFrameXML = parentXMLList[j]; 461 parentTotalDuration += currentDuration; 462 currentDuration = parseFloat(parentFrameXML.getAttribute(ccs.CONST_A_DURATION)); 463 j++; 464 } 465 } 466 var frameData = this.decodeFrame(frameXML, parentFrameXML, boneData, dataInfo); 467 movBoneData.addFrameData(frameData); 468 frameData.frameID = totalDuration; 469 totalDuration += frameData.duration; 470 movBoneData.duration = totalDuration; 471 } 472 473 //Change rotation range from (-180 -- 180) to (-infinity -- infinity) 474 var frames = movBoneData.frameList; 475 var pi = Math.PI; 476 for (var i = frames.length - 1; i >= 0; i--) { 477 if (i > 0) { 478 var difSkewX = frames[i].skewX - frames[i - 1].skewX; 479 var difSkewY = frames[i].skewY - frames[i - 1].skewY; 480 481 if (difSkewX < -pi || difSkewX > pi) { 482 frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi; 483 } 484 485 if (difSkewY < -pi || difSkewY > pi) { 486 frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi; 487 } 488 } 489 } 490 491 if (movBoneData.frameList.length > 0) { 492 var frameData = new ccs.FrameData(); 493 frameData.copy(movBoneData.frameList[movBoneData.frameList.length - 1]); 494 frameData.frameID = movBoneData.duration; 495 movBoneData.addFrameData(frameData); 496 } 497 return movBoneData; 498 }, 499 decodeFrame: function (frameXML, parentFrameXml, boneData, dataInfo) { 500 var frameData = new ccs.FrameData(); 501 frameData.movement = frameXML.getAttribute(ccs.CONST_A_MOVEMENT) || ""; 502 frameData.event = frameXML.getAttribute(ccs.CONST_A_EVENT) || ""; 503 frameData.blendType = parseInt(frameXML.getAttribute(ccs.CONST_A_BLEND_TYPE)) || ccs.BLEND_TYPE_NORMAL; 504 505 var blendFunc = frameData.blendFunc; 506 switch (frameData.blendType) { 507 case ccs.BLEND_TYPE_NORMAL: 508 blendFunc.src = cc.BLEND_SRC; 509 blendFunc.dst = cc.BLEND_DST; 510 break; 511 case ccs.BLEND_TYPE_ADD: 512 blendFunc.src = cc.SRC_ALPHA; 513 blendFunc.dst = cc.ONE; 514 break; 515 case ccs.BLEND_TYPE_MULTIPLY: 516 blendFunc.src = cc.ONE_MINUS_SRC_ALPHA; 517 blendFunc.dst = cc.ONE_MINUS_DST_COLOR; 518 break; 519 case ccs.BLEND_TYPE_SCREEN: 520 blendFunc.src = cc.ONE; 521 blendFunc.dst = cc.ONE_MINUS_DST_COLOR; 522 break; 523 default: 524 break; 525 } 526 527 frameData.sound = frameXML.getAttribute(ccs.CONST_A_SOUND) || ""; 528 frameData.soundEffect = frameXML.getAttribute(ccs.CONST_A_SOUND_EFFECT) || ""; 529 530 var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME); 531 if(isTween == null) 532 isTween = true; 533 frameData.isTween = Boolean(isTween); 534 535 if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) { 536 frameData.x = parseFloat(frameXML.getAttribute(ccs.CONST_A_COCOS2DX_X)) || 0; 537 frameData.y = -parseFloat(frameXML.getAttribute(ccs.CONST_A_COCOS2DX_Y)) || 0; 538 } 539 else { 540 frameData.x = parseFloat(frameXML.getAttribute(ccs.CONST_A_X)) || 0; 541 frameData.y = -parseFloat(frameXML.getAttribute(ccs.CONST_A_Y)) || 0; 542 } 543 frameData.x *= this._positionReadScale; 544 frameData.y *= this._positionReadScale; 545 frameData.scaleX = parseFloat(frameXML.getAttribute(ccs.CONST_A_SCALE_X)) || 0; 546 frameData.scaleY = parseFloat(frameXML.getAttribute(ccs.CONST_A_SCALE_Y)) || 0; 547 frameData.skewX = cc.degreesToRadians(parseFloat(frameXML.getAttribute(ccs.CONST_A_SKEW_X)) || 0); 548 frameData.skewY = cc.degreesToRadians(-parseFloat(frameXML.getAttribute(ccs.CONST_A_SKEW_Y)) || 0); 549 frameData.duration = parseFloat(frameXML.getAttribute(ccs.CONST_A_DURATION)) || 0; 550 frameData.displayIndex = parseFloat(frameXML.getAttribute(ccs.CONST_A_DISPLAY_INDEX)) || 0; 551 frameData.zOrder = parseFloat(frameXML.getAttribute(ccs.CONST_A_Z)) || 0; 552 frameData.tweenRotate = parseFloat(frameXML.getAttribute(ccs.CONST_A_TWEEN_ROTATION)) || 0; 553 554 var colorTransformXMLList = frameXML.querySelectorAll(ccs.CONST_FRAME + " > " + ccs.CONST_A_COLOR_TRANSFORM); 555 if (colorTransformXMLList.length > 0) { 556 var colorTransformXML = colorTransformXMLList[0]; 557 var alpha = 0, red = 0, green = 0, blue = 0; 558 var alphaOffset = 0, redOffset = 0, greenOffset = 0, blueOffset = 100; 559 560 alpha = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_ALPHA)) || alpha; 561 red = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_RED)) || red; 562 green = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_GREEN)) || green; 563 blue = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_BLUE)) || blue; 564 565 var str_alphaOffset = colorTransformXML.getAttribute(ccs.CONST_A_ALPHA_OFFSET); 566 if (str_alphaOffset) { 567 alphaOffset = parseFloat(str_alphaOffset); 568 } 569 var str_redOffset = colorTransformXML.getAttribute(ccs.CONST_A_RED_OFFSET); 570 if (str_redOffset) { 571 redOffset = parseFloat(str_redOffset); 572 } 573 var str_greenOffset = colorTransformXML.getAttribute(ccs.CONST_A_GREEN_OFFSET); 574 if (str_redOffset) { 575 greenOffset = parseFloat(str_greenOffset); 576 } 577 var str_blueOffset = colorTransformXML.getAttribute(ccs.CONST_A_BLUE_OFFSET); 578 if (str_blueOffset) { 579 blueOffset = parseFloat(str_blueOffset); 580 } 581 582 frameData.a = 2.55 * alphaOffset + alpha; 583 frameData.r = 2.55 * redOffset + red; 584 frameData.g = 2.55 * greenOffset + green; 585 frameData.b = 2.55 * blueOffset + blue; 586 587 frameData.isUseColorInfo = true; 588 } 589 if (frameData.displayIndex == -1) { 590 frameData.a = 0; 591 } 592 593 var tweenEasing = frameXML.getAttribute(ccs.CONST_A_TWEEN_EASING); 594 if (tweenEasing) { 595 if (tweenEasing != ccs.CONST_FL_NAN) { 596 frameData.tweenEasing = tweenEasing == 2 ? ccs.TweenType.sineEaseInOut : tweenEasing; 597 } else { 598 frameData.tweenEasing = ccs.TweenType.linear; 599 } 600 } 601 602 if (parentFrameXml) { 603 //* recalculate frame data from parent frame data, use for translate matrix 604 var helpNode = new ccs.BaseData(); 605 if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) { 606 helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_X)) || 0; 607 helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_Y)) || 0; 608 } 609 else { 610 helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_X)) || 0; 611 helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_Y)) || 0; 612 } 613 helpNode.skewX = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_X)) || 0; 614 helpNode.skewY = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_Y)) || 0; 615 616 helpNode.y = -helpNode.y; 617 helpNode.skewX = cc.degreesToRadians(helpNode.skewX); 618 helpNode.skewY = cc.degreesToRadians(-helpNode.skewY); 619 ccs.TransformHelp.transformFromParent(frameData, helpNode); 620 } 621 return frameData; 622 }, 623 624 decodeTexture: function (textureXML, dataInfo) { 625 var textureData = new ccs.TextureData(); 626 if (textureXML.getAttribute(ccs.CONST_A_NAME)) { 627 textureData.name = textureXML.getAttribute(ccs.CONST_A_NAME); 628 } 629 var px, py, width, height = 0; 630 if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) { 631 px = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_X)) || 0; 632 py = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_Y)) || 0; 633 } 634 else { 635 px = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_X)) || 0; 636 py = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_Y)) || 0; 637 } 638 width = parseFloat(textureXML.getAttribute(ccs.CONST_A_WIDTH)) || 0; 639 height = parseFloat(textureXML.getAttribute(ccs.CONST_A_HEIGHT)) || 0; 640 641 var anchorPointX = px / width; 642 var anchorPointY = (height - py) / height; 643 644 textureData.pivotX = anchorPointX; 645 textureData.pivotY = anchorPointY; 646 647 var contoursXML = textureXML.querySelectorAll(ccs.CONST_SUB_TEXTURE + " > " + ccs.CONST_CONTOUR); 648 for (var i = 0; i < contoursXML.length; i++) { 649 this.decodeContour(contoursXML[i], dataInfo); 650 } 651 return textureData; 652 }, 653 654 decodeContour: function (contourXML, dataInfo) { 655 var contourData = new ccs.ContourData(); 656 var vertexDatasXML = contourXML.querySelectorAll(ccs.CONST_CONTOUR + " > " + ccs.CONST_CONTOUR_VERTEX); 657 var vertexDataXML; 658 for (var i = 0; i < vertexDatasXML.length; i++) { 659 vertexDataXML = vertexDatasXML[i]; 660 var vertex = cc.p(0, 0); 661 vertex.x = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_X)) || 0; 662 vertex.y = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_Y)) || 0; 663 //vertex.y = - vertex.y;//todo 664 contourData.vertexList.push(vertex); 665 } 666 return contourData; 667 668 }, 669 670 addDataFromJson: function (filePath, dataInfo, isLoadSpriteFrame) { 671 var fileContent = cc.loader.getRes(filePath); 672 this.addDataFromJsonCache(fileContent, dataInfo, isLoadSpriteFrame); 673 }, 674 addDataFromJsonCache: function (dic, dataInfo, isLoadSpriteFrame) { 675 dataInfo.contentScale = dic[ccs.CONST_CONTENT_SCALE] || 1; 676 var armatureDataArr = dic[ccs.CONST_ARMATURE_DATA] || []; 677 var armatureData; 678 for (var i = 0; i < armatureDataArr.length; i++) { 679 armatureData = this.decodeArmatureFromJSON(armatureDataArr[i], dataInfo); 680 ccs.armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename); 681 } 682 683 var animationDataArr = dic[ccs.CONST_ANIMATION_DATA] || []; 684 var animationData; 685 for (var i = 0; i < animationDataArr.length; i++) { 686 animationData = this.decodeAnimationFromJson(animationDataArr[i], dataInfo); 687 ccs.armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename); 688 } 689 690 var textureDataArr = dic[ccs.CONST_TEXTURE_DATA] || []; 691 var textureData; 692 for (var i = 0; i < textureDataArr.length; i++) { 693 textureData = this.decodeTextureFromJson(textureDataArr[i], dataInfo); 694 ccs.armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename); 695 } 696 697 if (isLoadSpriteFrame) { 698 var configFiles = dic[ccs.CONST_CONFIG_FILE_PATH] || []; 699 var locFilePath, locPos, locPlistPath, locImagePath; 700 for (var i = 0; i < configFiles.length; i++) { 701 locFilePath = configFiles[i]; 702 locPos = locFilePath.lastIndexOf("."); 703 locFilePath = locFilePath.substring(0, locPos); 704 locPlistPath = dataInfo.basefilePath + locFilePath + ".plist"; 705 locImagePath = dataInfo.basefilePath + locFilePath + ".png"; 706 ccs.armatureDataManager.addSpriteFrameFromFile(locPlistPath, locImagePath, dataInfo.filename); 707 } 708 } 709 710 armatureData = null; 711 animationData = null; 712 }, 713 714 decodeArmatureFromJSON: function (json, dataInfo) { 715 var armatureData = new ccs.ArmatureData(); 716 717 var name = json[ccs.CONST_A_NAME]; 718 if (name) { 719 armatureData.name = name; 720 } 721 722 dataInfo.cocoStudioVersion = armatureData.dataVersion = json[ccs.CONST_VERSION] || 0.1; 723 724 var boneDataList = json[ccs.CONST_BONE_DATA]; 725 for (var i = 0; i < boneDataList.length; i++) { 726 armatureData.addBoneData(this.decodeBoneFromJson(boneDataList[i], dataInfo)); 727 } 728 return armatureData; 729 }, 730 731 decodeBoneFromJson: function (json, dataInfo) { 732 var boneData = new ccs.BoneData(); 733 this.decodeNodeFromJson(boneData, json, dataInfo); 734 boneData.name = json[ccs.CONST_A_NAME] || ""; 735 boneData.parentName = json[ccs.CONST_A_PARENT] || ""; 736 var displayDataList = json[ccs.CONST_DISPLAY_DATA] || []; 737 for (var i = 0; i < displayDataList.length; i++) { 738 var locDisplayData = this.decodeBoneDisplayFromJson(displayDataList[i], dataInfo); 739 boneData.addDisplayData(locDisplayData); 740 } 741 return boneData; 742 }, 743 744 decodeBoneDisplayFromJson: function (json, dataInfo) { 745 var displayType = json[ccs.CONST_A_DISPLAY_TYPE] || ccs.DISPLAY_TYPE_SPRITE; 746 var displayData = null; 747 switch (displayType) { 748 case ccs.DISPLAY_TYPE_SPRITE: 749 displayData = new ccs.SpriteDisplayData(); 750 displayData.displayName = json[ccs.CONST_A_NAME] || ""; 751 752 var dicArray = json[ccs.CONST_SKIN_DATA] || []; 753 var dic = dicArray[0]; 754 if (dic) { 755 var skinData = displayData.skinData; 756 skinData.x = (dic[ccs.CONST_A_X] || 0) * this._positionReadScale; 757 skinData.y = (dic[ccs.CONST_A_Y] || 0) * this._positionReadScale; 758 if (dic[ccs.CONST_A_SCALE_X] !== undefined) { 759 skinData.scaleX = dic[ccs.CONST_A_SCALE_X]; 760 } 761 if (dic[ccs.CONST_A_SCALE_Y] !== undefined) { 762 skinData.scaleY = dic[ccs.CONST_A_SCALE_Y]; 763 } 764 skinData.skewX = dic[ccs.CONST_A_SKEW_X] || 0; 765 skinData.skewY = dic[ccs.CONST_A_SKEW_Y] || 0; 766 767 skinData.x *= dataInfo.contentScale; 768 skinData.y *= dataInfo.contentScale; 769 dic = null; 770 } 771 break; 772 case ccs.DISPLAY_TYPE_ARMATURE: 773 displayData = new ccs.ArmatureDisplayData(); 774 displayData.displayName = json[ccs.CONST_A_NAME] || ""; 775 break; 776 case ccs.DISPLAY_TYPE_PARTICLE: 777 displayData = new ccs.ParticleDisplayData(); 778 displayData.displayName = dataInfo.basefilePath + json[ccs.CONST_A_PLIST] || ""; 779 break; 780 default: 781 displayData = new ccs.SpriteDisplayData(); 782 break; 783 } 784 785 displayData.displayType = displayType; 786 787 return displayData; 788 }, 789 790 decodeAnimationFromJson: function (json, dataInfo) { 791 var aniData = new ccs.AnimationData(); 792 aniData.name = json[ccs.CONST_A_NAME] || ""; 793 var movementDataList = json[ccs.CONST_MOVEMENT_DATA] || []; 794 for (var i = 0; i < movementDataList.length; i++) { 795 var locMovementData = this.decodeMovementFromJson(movementDataList[i], dataInfo); 796 aniData.addMovement(locMovementData); 797 } 798 return aniData; 799 }, 800 801 decodeMovementFromJson: function (json, dataInfo) { 802 var movementData = new ccs.MovementData(); 803 804 movementData.loop = json[ccs.CONST_A_LOOP] || false; 805 movementData.durationTween = json[ccs.CONST_A_DURATION_TWEEN] || 0; 806 movementData.durationTo = json[ccs.CONST_A_DURATION_TO] || 0; 807 movementData.duration = json[ccs.CONST_A_DURATION] || 0; 808 if (json[ccs.CONST_A_MOVEMENT_SCALE] !== undefined) { 809 movementData.scale = json[ccs.CONST_A_MOVEMENT_SCALE] 810 } 811 movementData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] || ccs.TweenType.linear; 812 movementData.name = json[ccs.CONST_A_NAME] || ""; 813 814 var movementBoneList = json[ccs.CONST_MOVEMENT_BONE_DATA] || []; 815 for (var i = 0; i < movementBoneList.length; i++) { 816 var locMovementBoneData = this.decodeMovementBoneFromJson(movementBoneList[i], dataInfo); 817 movementData.addMovementBoneData(locMovementBoneData); 818 } 819 return movementData; 820 }, 821 822 decodeMovementBoneFromJson: function (json, dataInfo) { 823 var movementBoneData = new ccs.MovementBoneData(); 824 movementBoneData.delay = json[ccs.CONST_A_MOVEMENT_DELAY] || 0; 825 if (json[ccs.CONST_A_MOVEMENT_SCALE] !== undefined) { 826 movementBoneData.scale = json[ccs.CONST_A_MOVEMENT_SCALE]; 827 } 828 829 movementBoneData.name = json[ccs.CONST_A_NAME] || ""; 830 var frameDataList = json[ccs.CONST_FRAME_DATA] || []; 831 for (var i = 0; i < frameDataList.length; i++) { 832 var frameData = this.decodeFrameFromJson(frameDataList[i], dataInfo); 833 movementBoneData.addFrameData(frameData); 834 if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED) { 835 frameData.frameID = movementBoneData.duration; 836 movementBoneData.duration += frameData.duration; 837 } 838 } 839 840 if (dataInfo.cocoStudioVersion < ccs.VERSION_CHANGE_ROTATION_RANGE) { 841 //! Change rotation range from (-180 -- 180) to (-infinity -- infinity) 842 var frames = movementBoneData.frameList; 843 var pi = Math.PI; 844 for (var i = frames.length - 1; i >= 0; i--) { 845 if (i > 0) { 846 var difSkewX = frames[i].skewX - frames[i - 1].skewX; 847 var difSkewY = frames[i].skewY - frames[i - 1].skewY; 848 849 if (difSkewX < -pi || difSkewX > pi) { 850 frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi; 851 } 852 853 if (difSkewY < -pi || difSkewY > pi) { 854 frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi; 855 } 856 } 857 } 858 } 859 860 if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED) { 861 if (movementBoneData.frameList.length > 0) { 862 var frameData = new ccs.FrameData(); 863 frameData.copy(movementBoneData.frameList[movementBoneData.frameList.length - 1]); 864 movementBoneData.addFrameData(frameData); 865 frameData.frameID = movementBoneData.duration; 866 } 867 } 868 return movementBoneData; 869 }, 870 871 decodeFrameFromJson: function (json, dataInfo) { 872 var frameData = new ccs.FrameData(); 873 this.decodeNodeFromJson(frameData, json, dataInfo); 874 frameData.duration = json[ccs.CONST_A_DURATION] || 0; 875 frameData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] || ccs.TweenType.linear; 876 frameData.displayIndex = json[ccs.CONST_A_DISPLAY_INDEX] || 0; 877 878 var bd_src = json[ccs.CONST_A_BLEND_SRC] || cc.BLEND_SRC; 879 var bd_dst = json[ccs.CONST_A_BLEND_DST] || cc.BLEND_DST; 880 frameData.blendFunc.src = bd_src; 881 frameData.blendFunc.dst = bd_dst; 882 883 frameData.event = json[ccs.CONST_A_EVENT] || null; 884 if (json[ccs.CONST_A_TWEEN_FRAME] !== undefined) { 885 frameData.isTween = json[ccs.CONST_A_TWEEN_FRAME] 886 } 887 if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED) 888 frameData.duration = json[ccs.CONST_A_DURATION] || 0; 889 else 890 frameData.frameID = json[ccs.CONST_A_FRAME_INDEX] || 0; 891 892 var twEPs = json[ccs.CONST_A_EASING_PARAM] || []; 893 for (var i = 0; i < twEPs.length; i++) { 894 var twEP = twEPs[i]; 895 frameData.easingParams[i] = twEP; 896 } 897 898 return frameData; 899 }, 900 901 decodeTextureFromJson: function (json) { 902 var textureData = new ccs.TextureData(); 903 textureData.name = json[ccs.CONST_A_NAME] || ""; 904 textureData.width = json[ccs.CONST_A_WIDTH] || 0; 905 textureData.height = json[ccs.CONST_A_HEIGHT] || 0; 906 textureData.pivotX = json[ccs.CONST_A_PIVOT_X] || 0; 907 textureData.pivotY = json[ccs.CONST_A_PIVOT_Y] || 0; 908 909 var contourDataList = json[ccs.CONST_CONTOUR_DATA] || []; 910 for (var i = 0; i < contourDataList.length; i++) { 911 var locContourData = this.decodeContourFromJson(contourDataList[i]); 912 textureData.contourDataList.push(locContourData); 913 } 914 return textureData; 915 }, 916 917 decodeContourFromJson: function (json) { 918 var contourData = new ccs.ContourData(); 919 var vertexPointList = json[ccs.CONST_VERTEX_POINT] || []; 920 for (var i = 0; i < vertexPointList.length; i++) { 921 var dic = vertexPointList[i]; 922 var vertex = cc.p(0, 0); 923 vertex.x = dic[ccs.CONST_A_X] || 0; 924 vertex.y = dic[ccs.CONST_A_Y] || 0; 925 contourData.vertexList.push(vertex); 926 } 927 return contourData; 928 }, 929 930 decodeNodeFromJson: function (node, json, dataInfo) { 931 node.x = json[ccs.CONST_A_X] || 0; 932 node.y = json[ccs.CONST_A_Y] || 0; 933 934 node.x *= dataInfo.contentScale; 935 node.y *= dataInfo.contentScale; 936 937 node.zOrder = json[ccs.CONST_A_Z] || 0; 938 939 node.skewX = json[ccs.CONST_A_SKEW_X] || 0; 940 node.skewY = json[ccs.CONST_A_SKEW_Y] || 0; 941 if (json[ccs.CONST_A_SCALE_X] !== undefined) { 942 node.scaleX = json[ccs.CONST_A_SCALE_X]; 943 } 944 if (json[ccs.CONST_A_SCALE_Y] !== undefined) { 945 node.scaleY = json[ccs.CONST_A_SCALE_Y]; 946 } 947 948 var colorDic = json[ccs.CONST_COLOR_INFO] || null; 949 if (colorDic) { 950 //compatible old version 951 if (dataInfo.cocoStudioVersion < ccs.VERSION_COLOR_READING) { 952 colorDic = colorDic[0]; 953 } 954 node.a = colorDic[ccs.CONST_A_ALPHA]; 955 node.r = colorDic[ccs.CONST_A_RED]; 956 node.g = colorDic[ccs.CONST_A_GREEN]; 957 node.b = colorDic[ccs.CONST_A_BLUE]; 958 node.isUseColorInfo = true; 959 delete colorDic; 960 } 961 }, 962 963 removeConfigFile: function (configFile) { 964 cc.arrayRemoveObject(this._configFileList, configFile); 965 } 966 };