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