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