diff --git a/src/dragonBones/Armature.as b/src/dragonBones/Armature.as
index cf24e70..89d39f4 100644
--- a/src/dragonBones/Armature.as
+++ b/src/dragonBones/Armature.as
@@ -1,138 +1,94 @@
-package dragonBones
+package dragonBones
{
-
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0, Flash 10
- * @langversion 3.0
- * @version 2.0
- */
-
import dragonBones.animation.Animation;
+ import dragonBones.animation.AnimationState;
import dragonBones.animation.IAnimatable;
+ import dragonBones.animation.TimelineState;
+ import dragonBones.core.DBObject;
+ import dragonBones.core.dragonBones_internal;
import dragonBones.events.ArmatureEvent;
- import dragonBones.utils.dragonBones_internal;
+ import dragonBones.events.FrameEvent;
+ import dragonBones.events.SoundEvent;
+ import dragonBones.events.SoundEventManager;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.Frame;
import flash.events.EventDispatcher;
import flash.geom.ColorTransform;
use namespace dragonBones_internal;
+
+ /**
+ * Dispatched when a bone of the armature enters a frame.
+ */
+ [Event(name="zOrderUpdated", type="dragonBones.events.ArmatureEvent")]
/**
- * Dispatched when the movement of animation is changed.
+ * Dispatched when an animation state of the animation begins fade in.
*/
- [Event(name="movementChange", type="dragonBones.events.AnimationEvent")]
+ [Event(name="fadeIn", type="dragonBones.events.AnimationEvent")]
/**
- * Dispatched when the playback of a animation starts.
+ * Dispatched when an animation state of the animation begins fade out.
+ */
+ [Event(name="fadeOut", type="dragonBones.events.AnimationEvent")]
+
+ /**
+ * Dispatched when an animation state of the animation starts.
*/
[Event(name="start", type="dragonBones.events.AnimationEvent")]
/**
- * Dispatched when the playback of a animation stops.
+ * Dispatched when an animation state of the animation completes.
*/
[Event(name="complete", type="dragonBones.events.AnimationEvent")]
/**
- * Dispatched when the playback of a animation completes a loop.
+ * Dispatched when an animation state of the animation completes a loop.
*/
[Event(name="loopComplete", type="dragonBones.events.AnimationEvent")]
/**
- * Dispatched when the animation of the armature enter a frame.
+ * Dispatched when an animation state of the animation completes fade in.
*/
- [Event(name="movementFrameEvent", type="dragonBones.events.FrameEvent")]
+ [Event(name="fadeInComplete", type="dragonBones.events.AnimationEvent")]
/**
- * Dispatched when a bone of the armature enters a frame.
+ * Dispatched when an animation state of the animation completes fade out.
*/
- [Event(name="boneFrameEvent", type="dragonBones.events.FrameEvent")]
+ [Event(name="fadeOutComplete", type="dragonBones.events.AnimationEvent")]
+
+ /**
+ * Dispatched when an animation state of the animation enters a frame.
+ */
+ [Event(name="animationFrameEvent", type="dragonBones.events.FrameEvent")]
/**
- * A Armature instance is the core of the skeleton animation system. It contains the object to display, all sub-bones and the object animation(s).
- * @example
- *
Download the example files here:
- * This example builds an Armature instance called "dragon" and stores it into the member varaible called 'armature'.
- *
- * package
- * {
- * import dragonBones.Armature;
- * import dragonBones.factorys.BaseFactory;
- * import flash.display.Sprite;
- * import flash.events.Event;
- *
- * public class DragonAnimation extends Sprite
- * {
- * [Embed(source = "Dragon1.swf", mimeType = "application/octet-stream")]
- * private static const ResourcesData:Class;
- *
- * private var factory:BaseFactory;
- * private var armature:Armature;
- *
- * public function DragonAnimation()
- * {
- * factory = new BaseFactory();
- * factory.addEventListener(Event.COMPLETE, handleParseData);
- * factory.parseData(new ResourcesData(), 'Dragon');
- * }
- *
- * private function handleParseData(e:Event):void
- * {
- * armature = factory.buildArmature('Dragon');
- * addChild(armature.display as Sprite);
- * armature.animation.play();
- * addEventListener(Event.ENTER_FRAME, updateAnimation);
- * }
- *
- * private function updateAnimation(e:Event):void
- * {
- * armature.advanceTime(1 / stage.frameRate);
- * }
- * }
- * }
- *
- * @see dragonBones.Bone
- * @see dragonBones.animation.Animation
+ * Dispatched when a bone of the armature enters a frame.
*/
+ [Event(name="boneFrameEvent", type="dragonBones.events.FrameEvent")]
+
public class Armature extends EventDispatcher implements IAnimatable
{
+ private static const _soundManager:SoundEventManager = SoundEventManager.getInstance();
+
+ private const _helpArray:Array = [];
+
/**
- * The name of the Armature.
+ * The name of this DBObject instance's Armature instance.
*/
public var name:String;
/**
- * An object containing user data.
+ * An object that can contain any user extra data.
*/
public var userData:Object;
/** @private */
- dragonBones_internal var _bonesIndexChanged:Boolean;
+ dragonBones_internal var _slotsZOrderChanged:Boolean;
/** @private */
- dragonBones_internal var _boneDepthList:Vector.;
- /** @private */
- protected var _rootBoneList:Vector.;
-
- /** @private */
- dragonBones_internal var _colorTransformChange:Boolean;
-
- /** @private */
- protected var _colorTransform:ColorTransform;
-
-
+ dragonBones_internal var _slotList:Vector.;
/** @private */
- public function set colorTransform(value:ColorTransform):void
- {
- _colorTransform = value;
- _colorTransformChange = true;
- }
- /**
- * The ColorTransform instance assiociated with this instance.
- * @param The ColorTransform instance assiociated with this Armature instance.
- */
- public function get colorTransform():ColorTransform
- {
- return _colorTransform;
- }
+ dragonBones_internal var _boneList:Vector.;
/** @private */
protected var _display:Object;
@@ -154,7 +110,6 @@ package dragonBones
{
return _animation;
}
-
/**
* Creates a Armature blank instance.
@@ -162,79 +117,151 @@ package dragonBones
*/
public function Armature(display:Object)
{
- super();
+ super(this);
_display = display;
- _boneDepthList = new Vector.;
- _rootBoneList = new Vector.;
-
_animation = new Animation(this);
- _bonesIndexChanged = false;
+ _slotsZOrderChanged = false;
+
+ _slotList = new Vector.;
+ _slotList.fixed = true;
+ _boneList = new Vector.;
+ _boneList.fixed = true;
}
/**
- * Cleans up resources used by this Armature instance.
+ * Cleans up any resources used by this DBObject instance.
*/
public function dispose():void
{
- for each(var bone:Bone in _rootBoneList)
+ if(!_animation)
{
- bone.dispose();
+ return;
}
- _boneDepthList.length = 0;
- _rootBoneList.length = 0;
+ userData = null;
_animation.dispose();
+
+ for each(var slot:Slot in _slotList)
+ {
+ slot.dispose();
+ }
+
+ for each(var bone:Bone in _boneList)
+ {
+ bone.dispose();
+ }
+
+ _slotList.fixed = false;
+ _slotList.length = 0;
+ _boneList.fixed = false;
+ _boneList.length = 0;
+
_animation = null;
+ _slotList = null;
+ _boneList = null;
//_display = null;
+ }
+
+ /**
+ * Update the animation using this method typically in an ENTERFRAME Event or with a Timer.
+ * @param The amount of second to move the playhead ahead.
+ */
+ public function advanceTime(passedTime:Number):void
+ {
+ _animation.advanceTime(passedTime);
- userData = null;
+ var i:int = _boneList.length;
+ while(i --)
+ {
+ _boneList[i].update();
+ }
+
+ i = _slotList.length;
+ var slot:Slot;
+ while(i --)
+ {
+ slot = _slotList[i];
+ slot.update();
+ if(slot._isDisplayOnStage)
+ {
+ var childArmature:Armature = slot.childArmature;
+ if(childArmature)
+ {
+ childArmature.advanceTime(passedTime);
+ }
+ }
+ }
- if(_colorTransform)
+ if(_slotsZOrderChanged)
{
- _colorTransform = null;
+ updateSlotsZOrder();
+
+ if(this.hasEventListener(ArmatureEvent.Z_ORDER_UPDATED))
+ {
+ this.dispatchEvent(new ArmatureEvent(ArmatureEvent.Z_ORDER_UPDATED));
+ }
}
}
-
+
/**
- * Retreives a Bone by name
- * @param The name of the Bone to retreive.
- * @return A Bone instance or null if no Bone with that name exist.
+ * Get all Slot instance associated with this armature.
+ * @return A Vector.<Slot> instance.
+ * @see dragonBones.Slot
+ */
+ public function getSlots(returnCopy:Boolean = true):Vector.
+ {
+ return returnCopy?_slotList.concat():_slotList;
+ }
+
+ /**
+ * Get all Bone instance associated with this armature.
+ * @return A Vector.<Bone> instance.
* @see dragonBones.Bone
*/
- public function getBone(name:String):Bone
+ public function getBones(returnCopy:Boolean = true):Vector.
+ {
+ return returnCopy?_boneList.concat():_boneList;
+ }
+
+ /**
+ * Retrieves a Slot by name
+ * @param The name of the Bone to retrieve.
+ * @return A Slot instance or null if no Slot with that name exist.
+ * @see dragonBones.Slot
+ */
+ public function getSlot(slotName:String):Slot
{
- if(name)
+ var i:int = _slotList.length;
+ while(i --)
{
- for each(var bone:Bone in _boneDepthList)
+ if(_slotList[i].name == slotName)
{
- if(bone.name == name)
- {
- return bone;
- }
+ return _slotList[i];
}
}
return null;
}
/**
- * Gets the Bone assiociated with this DisplayObject.
+ * Gets the Slot associated with this DisplayObject.
* @param Instance type of this object varies from flash.display.DisplayObject to startling.display.DisplayObject and subclasses.
- * @return A bone instance.
- * @see dragonBones.Bone
+ * @return A Slot instance.
+ * @see dragonBones.Slot
*/
- public function getBoneByDisplay(display:Object):Bone
+ public function getSlotByDisplay(display:Object):Slot
{
if(display)
{
- for each(var bone:Bone in _boneDepthList)
+ var i:int = _slotList.length;
+ while(i --)
{
- if(bone.display == display)
+ if(_slotList[i].display == display)
{
- return bone;
+ return _slotList[i];
}
}
}
@@ -242,55 +269,99 @@ package dragonBones
}
/**
- * Get all Bone instance assiociated with this armature.
- * @return A Vector.<Bone> instance.
- * @see dragonBones.Bone
+ * Remove a Slot instance from this Armature instance.
+ * @param The Slot instance to remove.
+ * @see dragonBones.Slot
*/
- public function getBones():Vector.
+ public function removeSlot(slot:Slot):void
{
- return _boneDepthList.concat();
+ if(!slot)
+ {
+ throw new ArgumentError();
+ }
+
+ if(_slotList.indexOf(slot) >= 0)
+ {
+ slot.parent.removeChild(slot);
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
}
+
/**
- * Add a Bone instance to this Armature instance.
- * @param A Bone instance
- * @param (optional) The parent's name of this Bone instance.
+ * Remove a Slot instance from this Armature instance.
+ * @param The name of the Slot instance to remove.
+ * @see dragonBones.Slot
+ */
+ public function removeSlotByName(slotName:String):void
+ {
+ if(!slotName)
+ {
+ return;
+ }
+
+ var slot:Slot = getSlot(slotName);
+ if(slot)
+ {
+ removeSlot(slot);
+ }
+ }
+
+ /**
+ * Retrieves a Bone by name
+ * @param The name of the Bone to retrieve.
+ * @return A Bone instance or null if no Bone with that name exist.
* @see dragonBones.Bone
*/
- public function addBone(bone:Bone, parentName:String = null):void
+ public function getBone(boneName:String):Bone
{
- if (bone)
+ var i:int = _boneList.length;
+ while(i --)
{
- var boneParent:Bone = getBone(parentName);
- if (boneParent)
+ if(_boneList[i].name == boneName)
{
- boneParent.addChild(bone);
- }
- else
- {
- bone.removeFromParent();
- addToBones(bone, true);
+ return _boneList[i];
}
}
+ return null;
}
+
/**
- * Remove a Bone instance from this Armature instance.
- * @param A Bone instance
+ * Gets the Bone associated with this DisplayObject.
+ * @param Instance type of this object varies from flash.display.DisplayObject to startling.display.DisplayObject and subclasses.
+ * @return A Bone instance.
* @see dragonBones.Bone
*/
+ public function getBoneByDisplay(display:Object):Bone
+ {
+ var slot:Slot = getSlotByDisplay(display);
+ return slot?slot.parent:null;
+ }
+
+ /**
+ * Remove a Bone instance from this Armature instance.
+ * @param The Bone instance to remove.
+ * @see dragonBones.Bone
+ */
public function removeBone(bone:Bone):void
{
- if (bone)
+ if(!bone)
{
- if(bone.parent)
- {
- bone.removeFromParent();
- }
- else
- {
- removeFromBones(bone);
- }
+ throw new ArgumentError();
+ }
+
+ if(_boneList.indexOf(bone) >= 0)
+ {
+ bone.parent.removeChild(bone);
+ }
+ else
+ {
+ throw new ArgumentError();
}
}
+
/**
* Remove a Bone instance from this Armature instance.
* @param The name of the Bone instance to remove.
@@ -298,128 +369,205 @@ package dragonBones
*/
public function removeBoneByName(boneName:String):void
{
+ if(!boneName)
+ {
+ return;
+ }
+
var bone:Bone = getBone(boneName);
- removeBone(bone);
+ if(bone)
+ {
+ removeBone(bone);
+ }
}
+
+
/**
- * Update the animation using this method typically in an ENTERFRAME Event or with a Timer.
- * @param The amount of second to move the playhead ahead.
+ * Add a DBObject instance to this Armature instance.
+ * @param A DBObject instance
+ * @param (optional) The parent's name of this DBObject instance.
+ * @see dragonBones.core.DBObject
*/
- public function advanceTime(passedTime:Number):void
+ public function addChild(object:DBObject, parentName:String = null):void
{
- var i:int = _boneDepthList.length;
- while(i --)
+ if(!object)
{
- var bone:Bone = _boneDepthList[i];
- if(bone._isOnStage)
+ throw new ArgumentError();
+ }
+
+ if(parentName)
+ {
+ var boneParent:Bone = getBone(parentName);
+ if (boneParent)
{
- var childArmature:Armature = bone.childArmature;
- if(childArmature)
- {
- childArmature.advanceTime(passedTime);
- }
+ boneParent.addChild(object);
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+ else
+ {
+ if(object.parent)
+ {
+ object.parent.removeChild(object);
}
+ object.setArmature(this);
}
- animation.advanceTime(passedTime);
- update();
+ }
+
+ /**
+ * Add a Bone instance to this Armature instance.
+ * @param A Bone instance
+ * @param (optional) The parent's name of this Bone instance.
+ * @see dragonBones.Bone
+ */
+ public function addBone(bone:Bone, parentName:String = null):void
+ {
+ addChild(bone, parentName);
}
/**
* Update the z-order of the display.
*/
- public function updateBonesZ():void
+ public function updateSlotsZOrder():void
{
- _boneDepthList.sort(sortBoneZIndex);
- for each(var bone:Bone in _boneDepthList)
+ _slotList.fixed = false;
+ _slotList.sort(sortSlot);
+ _slotList.fixed = true;
+ var i:int = _slotList.length;
+ var slot:Slot;
+ while(i --)
{
- if(bone._isOnStage)
+ slot = _slotList[i];
+ if(slot._isDisplayOnStage)
{
- bone._displayBridge.addDisplay(_display);
+ slot._displayBridge.addDisplay(display);
}
}
- _bonesIndexChanged = false;
- if(hasEventListener(ArmatureEvent.Z_ORDER_UPDATED))
- {
- dispatchEvent(new ArmatureEvent(ArmatureEvent.Z_ORDER_UPDATED));
- }
+ _slotsZOrderChanged = false;
}
/** @private */
- dragonBones_internal function update():void
+ dragonBones_internal function addDBObject(object:DBObject):void
{
- var i:int = _rootBoneList.length;
- while(i --)
+ if(object is Slot)
{
- _rootBoneList[i].update();
+ var slot:Slot = object as Slot;
+ if(_slotList.indexOf(slot) < 0)
+ {
+ _slotList.fixed = false;
+ _slotList[_slotList.length] = slot;
+ _slotList.fixed = true;
+ }
}
-
- _colorTransformChange = false;
-
- if(_bonesIndexChanged)
+ else if(object is Bone)
{
- updateBonesZ();
+ var bone:Bone = object as Bone;
+ if(_boneList.indexOf(bone) < 0)
+ {
+ _boneList.fixed = false;
+ _boneList[_boneList.length] = bone;
+ sortBoneList();
+ _boneList.fixed = true;
+ }
}
}
/** @private */
- dragonBones_internal function addToBones(bone:Bone, _root:Boolean = false):void
+ dragonBones_internal function removeDBObject(object:DBObject):void
{
- var boneIndex:int = _boneDepthList.indexOf(bone);
- if(boneIndex < 0)
+ if(object is Slot)
{
- _boneDepthList.push(bone);
+ var slot:Slot = object as Slot;
+ var index:int = _slotList.indexOf(slot);
+ if(index >= 0)
+ {
+ _slotList.fixed = false;
+ _slotList.splice(index, 1);
+ _slotList.fixed = true;
+ }
}
-
- boneIndex = _rootBoneList.indexOf(bone);
- if(_root)
+ else if(object is Bone)
{
- if(boneIndex < 0)
+ var bone:Bone = object as Bone;
+ index = _boneList.indexOf(bone);
+ if(index >= 0)
{
- _rootBoneList.push(bone);
+ _boneList.fixed = false;
+ _boneList.splice(index, 1);
+ _boneList.fixed = true;
}
}
- else if(boneIndex >= 0)
+ }
+
+ /** @private */
+ dragonBones_internal function sortBoneList():void
+ {
+ var i:int = _boneList.length;
+ if(i == 0)
+ {
+ return;
+ }
+ _helpArray.length = 0;
+ var level:int;
+ var bone:Bone;
+ var boneParent:Bone;
+ while(i --)
{
- _rootBoneList.splice(boneIndex, 1);
+ level = 0;
+ bone = _boneList[i];
+ boneParent = bone;
+ while(boneParent)
+ {
+ level ++;
+ boneParent = boneParent.parent;
+ }
+ _helpArray[i] = {level:level, bone:bone};
}
- bone._armature = this;
- bone._displayBridge.addDisplay(_display, bone.global.z);
- for each(var child:Bone in bone._children)
+ _helpArray.sortOn("level", Array.NUMERIC|Array.DESCENDING);
+
+ i = _helpArray.length;
+ while(i --)
{
- addToBones(child);
+ _boneList[i] = _helpArray[i].bone;
}
- _bonesIndexChanged = true;
+ _helpArray.length = 0;
}
/** @private */
- dragonBones_internal function removeFromBones(bone:Bone):void
+ dragonBones_internal function arriveAtFrame(frame:Frame, timelineState:TimelineState, animationState:AnimationState, isCross:Boolean):void
{
- var boneIndex:int = _boneDepthList.indexOf(bone);
- if(boneIndex >= 0)
+ if(frame.event && this.hasEventListener(FrameEvent.ANIMATION_FRAME_EVENT))
{
- _boneDepthList.splice(boneIndex, 1);
+ var frameEvent:FrameEvent = new FrameEvent(FrameEvent.ANIMATION_FRAME_EVENT);
+ frameEvent.animationState = animationState;
+ frameEvent.frameLabel = frame.event;
+ this.dispatchEvent(frameEvent);
}
- boneIndex = _rootBoneList.indexOf(bone);
- if(boneIndex >= 0)
+ if(frame.sound && _soundManager.hasEventListener(SoundEvent.SOUND))
{
- _rootBoneList.splice(boneIndex, 1);
+ var soundEvent:SoundEvent = new SoundEvent(SoundEvent.SOUND);
+ soundEvent.armature = this;
+ soundEvent.animationState = animationState;
+ soundEvent.sound = frame.sound;
+ _soundManager.dispatchEvent(soundEvent);
}
- bone._armature = null;
- bone._displayBridge.removeDisplay();
- for each(var child:Bone in bone._children)
+ if(frame.action && animationState.isPlaying)
{
- removeFromBones(child);
+ animation.gotoAndPlay(frame.action);
}
- _bonesIndexChanged = true;
}
- private function sortBoneZIndex(bone1:Bone, bone2:Bone):int
+ private function sortSlot(slot1:Slot, slot2:Slot):int
{
- return bone1.global.z >= bone2.global.z?1: -1;
+ return slot1.zOrder < slot2.zOrder?1: -1;
}
+
}
}
\ No newline at end of file
diff --git a/src/dragonBones/Bone.as b/src/dragonBones/Bone.as
index ecbd321..26bafb2 100644
--- a/src/dragonBones/Bone.as
+++ b/src/dragonBones/Bone.as
@@ -1,477 +1,329 @@
package dragonBones
{
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0
- * @langversion 3.0
- * @version 2.0
- */
+ import dragonBones.animation.AnimationState;
+ import dragonBones.animation.TimelineState;
+ import dragonBones.core.DBObject;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.events.FrameEvent;
+ import dragonBones.events.SoundEvent;
+ import dragonBones.events.SoundEventManager;
+ import dragonBones.objects.Frame;
+ import dragonBones.objects.TransformFrame;
- import dragonBones.animation.Tween;
- import dragonBones.display.IDisplayBridge;
- import dragonBones.objects.BoneTransform;
- import dragonBones.utils.dragonBones_internal;
-
- import flash.events.EventDispatcher;
- import flash.geom.ColorTransform;
- import flash.geom.Matrix;
+ import flash.geom.Point;
use namespace dragonBones_internal;
-
- /**
- * A Bone instance represents a single joint in an Armature instance. An Armature instance can be made up of many Bone instances.
- * @example
- * Download the example files here:
- * This example retrieves the Bone instance assiociated with the character's head and apply to its Display property an 0.5 alpha.
- *
- * package
- * {
- * import dragonBones.Armature;
- * import dragonBones.factorys.BaseFactory;
- * import flash.display.Sprite;
- * import flash.events.Event;
- *
- * public class DragonAnimation extends Sprite
- * {
- * [Embed(source = "Dragon1.swf", mimeType = "application/octet-stream")]
- * private static const ResourcesData:Class;
- *
- * private var factory:BaseFactory;
- * private var armature:Armature;
- *
- * public function DragonAnimation()
- * {
- * factory = new BaseFactory();
- * factory.addEventListener(Event.COMPLETE, handleParseData);
- * factory.parseData(new ResourcesData(), 'Dragon');
- * }
- *
- * private function handleParseData(e:Event):void
- * {
- * armature = factory.buildArmature('Dragon');
- * addChild(armature.display as Sprite);
- * armature.animation.play();
- * var bone:Bone = armature.getBone("head");
- * bone.display.alpha = 0.5;//make the DisplayObject belonging to this bone semi transparent.
- * addEventListener(Event.ENTER_FRAME, updateAnimation);
- * }
- *
- * private function updateAnimation(e:Event):void
- * {
- * armature.advanceTime(1 / stage.frameRate);
- * }
- * }
- * }
- *
- * @see dragonBones.Bone
- * @see dragonBones.animation.Animation
- */
- public class Bone extends EventDispatcher
+
+ public class Bone extends DBObject
{
- /**
- * The name of this Bone instance's Armature instance.
- */
- public var name:String;
- /**
- * An object that can contain any user extra data.
- */
- public var userData:Object;
- /**
- * This Bone instance global Node instance.
- * @see dragonBones.objects.Node
- */
- public var global:BoneTransform;
- /**
- * This Bone instance origin Node Instance.
- * @see dragonBones.objects.Node
- */
- public var origin:BoneTransform;
- /**
- * This Bone instance Node Instance.
- * @see dragonBones.objects.Node
- */
- public var node:BoneTransform;
+ private static const _soundManager:SoundEventManager = SoundEventManager.getInstance();
+ //0/1/2
+ public var scaleMode:int;
/** @private */
- dragonBones_internal var _tween:Tween;
- /** @private */
- dragonBones_internal var _tweenNode:BoneTransform;
- /** @private */
- dragonBones_internal var _tweenColorTransform:ColorTransform;
- /** @private */
- dragonBones_internal var _visible:Boolean;
- /** @private */
- dragonBones_internal var _children:Vector.;
- /** @private */
- dragonBones_internal var _displayBridge:IDisplayBridge;
- /** @private */
- dragonBones_internal var _isOnStage:Boolean;
- /** @private */
- dragonBones_internal var _armature:Armature;
-
- private var _globalTransformMatrix:Matrix;
- private var _displayList:Array;
- private var _displayIndex:int;
- private var _parent:Bone;
-
- private var _colorTransformChange:Boolean;
- private var _colorTransform:ColorTransform;
- private var _boneVisible:Object;
-
- /**
- * @private
- */
- public function set visible(value:Object):void
- {
- if(value == null)
- {
- _boneVisible = value;
- }
- else
- {
- _boneVisible = Boolean(value);
- }
- }
-
- /**
- * Whether this Bone instance and its associated DisplayObject are visible or not (true/false/null). null means that the visible will be controled by animation data.
- *
- */
- public function get visible():Object
- {
- return _boneVisible;
- }
+ dragonBones_internal var _tweenPivot:Point;
- /**
- * @private
- */
- public function set colorTransform(value:ColorTransform):void
- {
- _colorTransform = value;
- _colorTransformChange = true;
- }
+ private var _children:Vector.;
+ private var _slot:Slot;
/**
- * The ColorTransform instance assiociated with this Bone instance. null means that the ColorTransform will be controled by animation data.
+ * The default Slot of this Bone instance.
*/
- public function get colorTransform():ColorTransform
+ public function get slot():Slot
{
- return _colorTransform;
+ return _slot;
}
/**
- * The armature this Bone instance belongs to.
- */
- public function get armature():Armature
- {
- return _armature;
- }
-
- /**
- * The sub-armature of this Bone instance.
+ * The sub-armature of default Slot of this Bone instance.
*/
public function get childArmature():Armature
{
- return _displayList[_displayIndex] as Armature;
- }
-
- /**
- * Indicates the Bone instance that directly contains this Bone instance if any.
- */
- public function get parent():Bone
- {
- return _parent;
+ return _slot?_slot.childArmature:null;
}
/**
- * The DisplayObject belonging to this Bone instance. Instance type of this object varies from flash.display.DisplayObject to startling.display.DisplayObject and subclasses.
+ * The DisplayObject of default Slot of this Bone instance.
*/
public function get display():Object
{
- return _displayBridge.display;
+ return _slot?_slot.display:null;
}
public function set display(value:Object):void
{
- if(_displayBridge.display == value)
+ if(_slot)
{
- return;
- }
- _displayList[_displayIndex] = value;
- if(value is Armature)
- {
- value = (value as Armature).display;
+ _slot.display = value;
}
- _displayBridge.display = value;
}
-
- /**
- * The DisplayObject list belonging to this Bone instance.
- */
- public function get displayList():Array
+ private var _displayController:String;
+ public function get displayController():String
+ {
+ return _displayController;
+ }
+ public function set displayController(value:String):void
{
- return _displayList;
+ _displayController = value;
}
- /** @private */
- dragonBones_internal function changeDisplay(displayIndex:int):void
+ /**
+ * @inheritDoc
+ */
+ override public function set visible(value:Boolean):void
{
- var childArmature:Armature = this.childArmature;
- if(displayIndex < 0)
+ if(this._visible != value)
{
- if(_isOnStage)
+ this._visible = value;
+ var i:int = _children.length;
+ while(i --)
{
- _isOnStage = false;
- //removeFromStage
- _displayBridge.removeDisplay();
-
- if(childArmature)
+ var slot:Slot = _children[i] as Slot;
+ if(slot)
{
- childArmature.animation.stop();
- childArmature.animation.clearMovement();
+ slot.updateVisible(this._visible);
}
}
}
- else
+ }
+
+ /** @private */
+ override dragonBones_internal function setArmature(value:Armature):void
+ {
+ super.setArmature(value);
+ var i:int = _children.length;
+ while(i --)
{
- if(!_isOnStage)
- {
- _isOnStage = true;
- //addToStage
- if(_armature)
- {
- _displayBridge.addDisplay(_armature.display, global.z);
- _armature._bonesIndexChanged = true;
- }
- }
- if(_displayIndex != displayIndex)
- {
- var length:uint = _displayList.length;
- if(displayIndex >= length && length > 0)
- {
- displayIndex = length - 1;
- }
- _displayIndex = displayIndex;
-
- //change
- display = _displayList[_displayIndex];
- }
-
- if(childArmature)
- {
- childArmature.animation.play();
- }
+ _children[i].setArmature(this._armature);
}
}
- /**
- * Creates a new Bone instance and attaches to it a IDisplayBridge instance.
- * @param dragonBones.display.IDisplayBridge
- */
- public function Bone(displayBrideg:IDisplayBridge)
+ public function Bone()
{
- origin = new BoneTransform();
- origin.scaleX = 1;
- origin.scaleY = 1;
- global = new BoneTransform();
- node = new BoneTransform();
- _displayBridge = displayBrideg;
- _children = new Vector.;
- _globalTransformMatrix = new Matrix();
- _displayList = [];
- _displayIndex = -1;
- _visible = true;
- _tweenNode = new BoneTransform();
- _tweenColorTransform = new ColorTransform();
- _tween = new Tween(this);
+ super();
+ _children = new Vector.(0, true);
+ _scaleType = 2;
+
+ _tweenPivot = new Point();
+
+ scaleMode = 1;
}
+
/**
- * Change all DisplayObject attached to this Bone instance.
- * @param displayList An array of valid DisplayObject to attach to this Bone.
+ * @inheritDoc
*/
- public function changeDisplayList(displayList:Array):void
+ override public function dispose():void
{
- var indexBackup:int = _displayIndex;
- var length:uint = displayList.length;
- _displayList.length = length;
- for(var i:int = 0;i < length;i ++)
+ if(!_children)
+ {
+ return;
+ }
+ super.dispose();
+
+ var i:int = _children.length;
+ while(i --)
{
- changeDisplay(i);
- display = displayList[i];
- }
- changeDisplay(indexBackup);
+ _children[i].dispose();
+ }
+ _children.fixed = false;
+ _children.length = 0;
+
+ _children = null;
+ _slot = null;
+ _tweenPivot = null;
}
- /**
- * Cleans up any resources used by this Bone instance.
- */
- public function dispose():void
+ public function contains(child:DBObject):Boolean
{
- for each(var _child:Bone in _children)
+ if(!child)
{
- _child.dispose();
- }
- _displayList.length = 0;
- _children.length = 0;
- _armature = null;
- _parent = null;
- userData = null;
- }
- /**
- * Returns true if the passed Bone Instance is a child of this Bone instance (deepLevel false) or true if the passed Bone instance is in the child hierarchy of this Bone instance (deepLevel true) false otherwise.
- * @param deepLevel Check against child heirarchy.
- * @return
- */
- public function contains(bone:Bone, deepLevel:Boolean = false):Boolean
- {
- if(deepLevel)
+ throw new ArgumentError();
+ }
+ if(child == this)
{
- var ancestor:Bone = this;
- while (ancestor != bone && ancestor != null)
- {
- ancestor = ancestor.parent;
- }
- if (ancestor == bone)
- {
- return true;
- }
return false;
- }
- return bone.parent == this;
+ }
+ var ancestor:DBObject = child;
+ while (!(ancestor == this || ancestor == null))
+ {
+ ancestor = ancestor.parent;
+ }
+ return ancestor == this;
}
- /** @private */
- public function addChild(child:Bone):void
+ public function addChild(child:DBObject):void
{
- if (_children.length > 0?(_children.indexOf(child) < 0):true)
+ if(!child)
{
- child.removeFromParent();
-
- _children.push(child);
- child.setParent(this);
-
- if (_armature)
- {
- _armature.addToBones(child);
- }
+ throw new ArgumentError();
+ }
+
+ var bone:Bone = child as Bone;
+ if(child == this || (bone && bone.contains(this)))
+ {
+ throw new ArgumentError("An Bone cannot be added as a child to itself or one of its children (or children's children, etc.)");
+ }
+
+ if(child.parent)
+ {
+ child.parent.removeChild(child);
+ }
+ _children.fixed = false;
+ _children[_children.length] = child;
+ _children.fixed = true;
+ child.setParent(this);
+ child.setArmature(this._armature);
+
+ if(!_slot && child is Slot)
+ {
+ _slot = child as Slot;
}
}
- /** @private */
- public function removeChild(child:Bone):void
+ public function removeChild(child:DBObject):void
{
+ if(!child)
+ {
+ throw new ArgumentError();
+ }
+
var index:int = _children.indexOf(child);
if (index >= 0)
{
- if (_armature)
+ _children.fixed = false;
+ _children.splice(index, 1);
+ _children.fixed = true;
+ child.setParent(null);
+ child.setArmature(null);
+
+ if(_slot && child == _slot)
{
- _armature.removeFromBones(child);
+ _slot = null;
}
- child.setParent(null);
- _children.splice(index, 1);
+
+ if(this._armature)
+ {
+ this._armature.removeDBObject(child);
+ }
+ }
+ else
+ {
+ throw new ArgumentError();
}
}
- /** @private */
- public function removeFromParent():void
+ /**
+ * Get all Slot instance associated with this bone.
+ * @return A Vector.<Slot> instance.
+ * @see dragonBones.Slot
+ */
+ public function getSlots():Vector.
{
- if(_parent)
+ var slotList:Vector. = new Vector.;
+ var i:int = _children.length;
+ while(i --)
{
- _parent.removeChild(this);
+ if(_children[i] is Slot)
+ {
+ slotList.unshift(_children[i]);
+ }
}
+ return slotList;
}
/** @private */
- dragonBones_internal function update():void
+ dragonBones_internal function arriveAtFrame(frame:Frame, timelineState:TimelineState, animationState:AnimationState, isCross:Boolean):void
{
- //transform
- if(_parent)
- {
- var x:Number = origin.x + node.x + _tweenNode.x;
- var y:Number = origin.y + node.y + _tweenNode.y;
- var parentMatrix:Matrix = _parent._globalTransformMatrix;
- _globalTransformMatrix.tx = global.x = parentMatrix.a * x + parentMatrix.c * y + parentMatrix.tx;
- _globalTransformMatrix.ty = global.y = parentMatrix.d * y + parentMatrix.b * x + parentMatrix.ty;
- global.skewX = _parent.global.skewX + origin.skewX + node.skewX + _tweenNode.skewX;
- global.skewY = _parent.global.skewY + origin.skewY + node.skewY + _tweenNode.skewY;
- }
- else
- {
- _globalTransformMatrix.tx = global.x = origin.x + node.x + _tweenNode.x;
- _globalTransformMatrix.ty = global.y = origin.y + node.y + _tweenNode.y;
- global.skewX = origin.skewX + node.skewX + _tweenNode.skewX;
- global.skewY = origin.skewY + node.skewY + _tweenNode.skewY;
- }
-
- //update global
- global.scaleX = origin.scaleX + node.scaleX + _tweenNode.scaleX;
- global.scaleY = origin.scaleY + node.scaleY + _tweenNode.scaleY;
- global.pivotX = origin.pivotX + node.pivotX + _tweenNode.pivotX;
- global.pivotY = origin.pivotY + node.pivotY + _tweenNode.pivotY;
- global.z = origin.z + node.z + _tweenNode.z;
-
- //Note: this formula of transform is defined by Flash pro
- _globalTransformMatrix.a = global.scaleX * Math.cos(global.skewY);
- _globalTransformMatrix.b = global.scaleX * Math.sin(global.skewY);
- _globalTransformMatrix.c = -global.scaleY * Math.sin(global.skewX);
- _globalTransformMatrix.d = global.scaleY * Math.cos(global.skewX);
-
- //update children
- if (_children.length > 0)
+ if(frame)
{
- var i:int = _children.length;
- while(i --)
+ var mixingType:int = animationState.getMixingTransform(name);
+ if(animationState.displayControl && (mixingType == 2 || mixingType == -1))
{
- _children[i].update();
+ if(
+ !_displayController || _displayController == animationState.name
+ )
+ {
+ var tansformFrame:TransformFrame = frame as TransformFrame;
+ if(_slot)
+ {
+ var displayIndex:int = tansformFrame.displayIndex;
+ if(displayIndex >= 0)
+ {
+ if(!isNaN(tansformFrame.zOrder) && tansformFrame.zOrder != _slot._tweenZorder)
+ {
+ _slot._tweenZorder = tansformFrame.zOrder;
+ this._armature._slotsZOrderChanged = true;
+ }
+ }
+ _slot.changeDisplay(displayIndex);
+ _slot.updateVisible(tansformFrame.visible);
+ }
+ }
}
- }
-
- var childArmature:Armature = this.childArmature;
- if(childArmature)
- {
- childArmature.update();
- }
-
- var currentDisplay:Object = _displayBridge.display;
- //update display
- if(currentDisplay)
- {
- //currentColorTransform
- var currentColorTransform:ColorTransform;
- if(_tween._differentColorTransform)
+ if(frame.event && this._armature.hasEventListener(FrameEvent.BONE_FRAME_EVENT))
{
- if(_colorTransform)
- {
- _tweenColorTransform.concat(_colorTransform);
- }
- if(_armature.colorTransform)
+ var frameEvent:FrameEvent = new FrameEvent(FrameEvent.BONE_FRAME_EVENT);
+ frameEvent.bone = this;
+ frameEvent.animationState = animationState;
+ frameEvent.frameLabel = frame.event;
+ this._armature.dispatchEvent(frameEvent);
+ }
+
+ if(frame.sound && _soundManager.hasEventListener(SoundEvent.SOUND))
+ {
+ var soundEvent:SoundEvent = new SoundEvent(SoundEvent.SOUND);
+ soundEvent.armature = this._armature;
+ soundEvent.animationState = animationState;
+ soundEvent.sound = frame.sound;
+ _soundManager.dispatchEvent(soundEvent);
+ }
+
+ if(frame.action)
+ {
+ var childArmature:Armature = this.childArmature;
+ if(childArmature)
{
- _tweenColorTransform.concat(_armature.colorTransform);
+ childArmature.animation.gotoAndPlay(frame.action);
}
- currentColorTransform = _tweenColorTransform;
}
- else if(_armature._colorTransformChange || _colorTransformChange)
+ }
+ else
+ {
+ if(_slot)
{
- currentColorTransform = _colorTransform || _armature.colorTransform;
- _colorTransformChange = false;
+ _slot.changeDisplay(-1);
}
- _displayBridge.update(_globalTransformMatrix, global, currentColorTransform, (_boneVisible != null)?_boneVisible:_visible);
}
}
- private function setParent(parent:Bone):void
+ /** @private */
+ dragonBones_internal function updateColor(
+ aOffset:Number,
+ rOffset:Number,
+ gOffset:Number,
+ bOffset:Number,
+ aMultiplier:Number,
+ rMultiplier:Number,
+ gMultiplier:Number,
+ bMultiplier:Number,
+ isColorChanged:Boolean
+ ):void
{
- if (parent && parent.contains(this, true))
+ if(isColorChanged || _isColorChanged)
{
- throw new ArgumentError("An Bone cannot be added as a child to itself or one of its children (or children's children, etc.)");
+ _slot._displayBridge.updateColor(
+ aOffset,
+ rOffset,
+ gOffset,
+ bOffset,
+ aMultiplier,
+ rMultiplier,
+ gMultiplier,
+ bMultiplier
+ );
}
- _parent = parent;
-
- if(_parent)
- {
- _isOnStage = _parent._isOnStage;
- }
+ _isColorChanged = isColorChanged;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/dragonBones/Slot.as b/src/dragonBones/Slot.as
new file mode 100644
index 0000000..31ebed1
--- /dev/null
+++ b/src/dragonBones/Slot.as
@@ -0,0 +1,326 @@
+package dragonBones
+{
+ import dragonBones.core.DBObject;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.display.IDisplayBridge;
+ import dragonBones.objects.DisplayData;
+
+ import flash.geom.Matrix;
+
+ use namespace dragonBones_internal;
+
+ public class Slot extends DBObject
+ {
+ /** @private */
+ dragonBones_internal var _dislayDataList:Vector.;
+ /** @private */
+ dragonBones_internal var _displayBridge:IDisplayBridge;
+ /** @private */
+ dragonBones_internal var _originZOrder:Number;
+ /** @private */
+ dragonBones_internal var _tweenZorder:Number;
+ /** @private */
+ dragonBones_internal var _isDisplayOnStage:Boolean;
+
+ private var _isHideDisplay:Boolean;
+ private var _offsetZOrder:Number;
+ private var _displayIndex:int;
+
+ public function get zOrder():Number
+ {
+ return _originZOrder + _tweenZorder + _offsetZOrder;
+ }
+
+ public function set zOrder(value:Number):void
+ {
+ if(zOrder != value)
+ {
+ _offsetZOrder = value - _originZOrder - _tweenZorder;
+ if(this._armature)
+ {
+ this._armature._slotsZOrderChanged = true;
+ }
+ }
+ }
+
+ /**
+ * The DisplayObject belonging to this Bone instance. Instance type of this object varies from flash.display.DisplayObject to startling.display.DisplayObject and subclasses.
+ */
+ public function get display():Object
+ {
+ var display:Object = _displayList[_displayIndex];
+ if(display is Armature)
+ {
+ return display.display;
+ }
+ return display;
+ }
+ public function set display(value:Object):void
+ {
+ _displayList[_displayIndex] = value;
+ setDisplay(value);
+ }
+
+ /**
+ * The sub-armature of this Slot instance.
+ */
+ public function get childArmature():Armature
+ {
+ return _displayList[_displayIndex] as Armature;
+ }
+ public function set childArmature(value:Armature):void
+ {
+ _displayList[_displayIndex] = value;
+ if(value)
+ {
+ setDisplay(value.display);
+ }
+ }
+
+ private var _displayList:Array;
+ /**
+ * The DisplayObject list belonging to this Slot instance.
+ */
+ public function get displayList():Array
+ {
+ return _displayList;
+ }
+ public function set displayList(value:Array):void
+ {
+ if(!value)
+ {
+ throw new ArgumentError();
+ }
+ var i:int = _displayList.length = value.length;
+ while(i --)
+ {
+ _displayList[i] = value[i];
+ }
+
+ if(_displayIndex >= 0)
+ {
+ _displayIndex = -1;
+ changeDisplay(_displayIndex);
+ }
+ }
+
+ private function setDisplay(display:Object):void
+ {
+ if(_displayBridge.display)
+ {
+ _displayBridge.display = display;
+ }
+ else
+ {
+ _displayBridge.display = display;
+ if(this._armature)
+ {
+ _displayBridge.addDisplay(this._armature.display);
+ this._armature._slotsZOrderChanged = true;
+ }
+ }
+
+ updateChildArmatureAnimation();
+
+ if(!_isHideDisplay && _displayBridge.display)
+ {
+ _isDisplayOnStage = true;
+ }
+ else
+ {
+ _isDisplayOnStage = false;
+ }
+ }
+
+ /** @private */
+ dragonBones_internal function changeDisplay(displayIndex:int):void
+ {
+ if(displayIndex < 0)
+ {
+ if(!_isHideDisplay)
+ {
+ _isHideDisplay = true;
+ _displayBridge.removeDisplay();
+ updateChildArmatureAnimation();
+ }
+ }
+ else
+ {
+ if(_isHideDisplay)
+ {
+ _isHideDisplay = false;
+ var changeShowState:Boolean = true;
+ if(this._armature)
+ {
+ _displayBridge.addDisplay(this._armature.display);
+ this._armature._slotsZOrderChanged = true;
+ }
+ }
+
+ var length:uint = _displayList.length;
+ if(displayIndex >= length && length > 0)
+ {
+ displayIndex = length - 1;
+ }
+ if(_displayIndex != displayIndex)
+ {
+ _displayIndex = displayIndex;
+
+ var content:Object = _displayList[_displayIndex];
+ if(content is Armature)
+ {
+ setDisplay((content as Armature).display);
+ }
+ else
+ {
+ setDisplay(content);
+ }
+
+ if(_dislayDataList && _displayIndex <= _dislayDataList.length)
+ {
+ this._origin.copy(_dislayDataList[_displayIndex].transform);
+ }
+ }
+ else if(changeShowState)
+ {
+ updateChildArmatureAnimation();
+ }
+ }
+
+ if(!_isHideDisplay && _displayBridge.display)
+ {
+ _isDisplayOnStage = true;
+ }
+ else
+ {
+ _isDisplayOnStage = false;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ override public function set visible(value:Boolean):void
+ {
+ if(value != this._visible)
+ {
+ this._visible = value;
+ updateVisible(this._visible);
+ }
+ }
+
+ /** @private */
+ override dragonBones_internal function setArmature(value:Armature):void
+ {
+ super.setArmature(value);
+ if(this._armature)
+ {
+ this._armature._slotsZOrderChanged = true;
+ _displayBridge.addDisplay(this._armature.display);
+ }
+ else
+ {
+ _displayBridge.removeDisplay();
+ }
+ }
+
+ public function Slot(displayBrideg:IDisplayBridge)
+ {
+ super();
+ _displayBridge = displayBrideg;
+ _displayList = [];
+ _displayIndex = -1;
+ _scaleType = 1;
+
+ _originZOrder = 0;
+ _tweenZorder = 0;
+ _offsetZOrder = 0;
+
+ _isDisplayOnStage = false;
+ _isHideDisplay = false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ override public function dispose():void
+ {
+ if(!_displayBridge)
+ {
+ return;
+ }
+ super.dispose();
+
+ _displayBridge.dispose();
+ _displayList.length = 0;
+
+ _displayBridge = null;
+ _displayList = null;
+ _dislayDataList = null;
+ }
+
+ /** @private */
+ override dragonBones_internal function update():void
+ {
+ super.update();
+
+ if(_isDisplayOnStage)
+ {
+ var pivotX:Number = _parent._tweenPivot.x;
+ var pivotY:Number = _parent._tweenPivot.y;
+ if(pivotX || pivotY)
+ {
+ var parentMatrix:Matrix = _parent._globalTransformMatrix;
+ this._globalTransformMatrix.tx += parentMatrix.a * pivotX + parentMatrix.c * pivotY;
+ this._globalTransformMatrix.ty += parentMatrix.b * pivotX + parentMatrix.d * pivotY;
+ }
+
+ _displayBridge.updateTransform(this._globalTransformMatrix, this._global);
+ }
+ }
+
+ /** @private */
+ dragonBones_internal function updateVisible(value:Boolean):void
+ {
+ _displayBridge.visible = this._parent.visible && this._visible && value;
+ }
+
+ private function updateChildArmatureAnimation():void
+ {
+ var childArmature:Armature = this.childArmature;
+
+ if(childArmature)
+ {
+ if(_isHideDisplay)
+ {
+ childArmature.animation.stop();
+ childArmature.animation._lastAnimationState = null;
+ }
+ else
+ {
+ if(
+ this._armature &&
+ this._armature.animation.lastAnimationState &&
+ childArmature.animation.hasAnimation(this._armature.animation.lastAnimationState.name)
+ )
+ {
+ childArmature.animation.gotoAndPlay(this._armature.animation.lastAnimationState.name);
+ }
+ else
+ {
+ childArmature.animation.play();
+ }
+ }
+ }
+ }
+
+ /**
+ * Change all DisplayObject attached to this Bone instance.
+ * @param displayList An array of valid DisplayObject to attach to this Bone.
+ */
+ public function changeDisplayList(displayList:Array):void
+ {
+ this.displayList = displayList;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/animation/Animation.as b/src/dragonBones/animation/Animation.as
index 0ad177c..9b6cfc6 100644
--- a/src/dragonBones/animation/Animation.as
+++ b/src/dragonBones/animation/Animation.as
@@ -1,22 +1,18 @@
package dragonBones.animation
{
/**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0
- * @langversion 3.0
- * @version 2.0
- */
+ * Copyright 2012-2013. DragonBones. All Rights Reserved.
+ * @playerversion Flash 10.0
+ * @langversion 3.0
+ * @version 2.0
+ */
import dragonBones.Armature;
import dragonBones.Bone;
- import dragonBones.events.AnimationEvent;
- import dragonBones.events.FrameEvent;
- import dragonBones.events.SoundEvent;
- import dragonBones.events.SoundEventManager;
+ import dragonBones.core.dragonBones_internal;
import dragonBones.objects.AnimationData;
- import dragonBones.objects.MovementBoneData;
- import dragonBones.objects.MovementData;
- import dragonBones.objects.MovementFrameData;
- import dragonBones.utils.dragonBones_internal;
+ import dragonBones.objects.DBTransform;
+
+ import flash.geom.Point;
use namespace dragonBones_internal;
@@ -28,21 +24,21 @@
* package
* {
* import dragonBones.Armature;
- * import dragonBones.factorys.BaseFactory;
+ * import dragonBones.factorys.NativeFactory;
* import flash.display.Sprite;
* import flash.events.Event;
- *
+ *
* public class DragonAnimation extends Sprite
* {
* [Embed(source = "Dragon1.swf", mimeType = "application/octet-stream")]
* private static const ResourcesData:Class;
*
- * private var factory:BaseFactory;
+ * private var factory:NativeFactory;
* private var armature:Armature;
*
* public function DragonAnimation()
* {
- * factory = new BaseFactory();
+ * factory = new NativeFactory();
* factory.addEventListener(Event.COMPLETE, handleParseData);
* factory.parseData(new ResourcesData(), 'Dragon');
* }
@@ -57,122 +53,123 @@
*
* private function updateAnimation(e:Event):void
* {
- * armature.advanceTime(1 / stage.frameRate);
+ * armature.advanceTime(stage.frameRate / 1000);
* }
* }
* }
*
- * @see dragonBones.Bone
* @see dragonBones.Armature
+ * @see dragonBones.animation.Animation
+ * @see dragonBones.animation.AnimationState
*/
- final public class Animation
- {/**
- * @private
- */
- internal static const SINGLE:int = 0;
- /**
- * @private
- */
- internal static const LIST_START:int = 1;
- /**
- * @private
- */
- internal static const LOOP_START:int = 2;
- /**
- * @private
- */
- internal static const LIST:int = 3;
- /**
- * @private
- */
- internal static const LOOP:int = 4;
- private static var _soundManager:SoundEventManager = SoundEventManager.getInstance();
+ public class Animation
+ {
+ public static const NONE:String = "none";
+ public static const SAME_LAYER:String = "sameLayer";
+ public static const SAME_GROUP:String = "sameGroup";
+ public static const SAME_LAYER_AND_GROUP:String = "sameLayerAndGroup";
+ public static const ALL:String = "all";
+
/**
* Whether animation tweening is enabled or not.
*/
- public var tweenEnabled:Boolean = true;
+ public var tweenEnabled:Boolean;
+
+ /** @private */
+ dragonBones_internal var _animationLayer:Vector.>;
- private var _playType:int;
- private var _duration:Number;
- private var _rawDuration:Number;
- private var _nextFrameDataTimeEdge:Number;
- private var _nextFrameDataID:int;
- private var _loop:int;
- private var _breakFrameWhile:Boolean;
private var _armature:Armature;
- private var _movementData:MovementData;
- private var _animationData:AnimationData;
+ private var _isPlaying:Boolean;
/**
- * The AnimationData assiociated with this Animation instance.
+ * An vector containing all AnimationData names the Animation can play.
* @see dragonBones.objects.AnimationData.
*/
- public function get animationData():AnimationData
+ public function get movementList():Vector.
{
- return _animationData;
+ return _animationList;
}
+
/**
- * @private
+ * The name of the last AnimationData played.
+ * @see dragonBones.objects.AnimationData.
*/
- public function set animationData(value:AnimationData):void
+ public function get movementID():String
{
- if (value)
- {
- stop();
- _animationData = value;
- }
+ return _lastAnimationState?_lastAnimationState.name:null;
}
- private var _currentTime:Number;
+ dragonBones_internal var _lastAnimationState:AnimationState;
/**
- * Get the current playhead time in seconds.
+ * The last AnimationData this Animation played.
+ * @see dragonBones.objects.AnimationData.
*/
- public function get currentTime():Number
+ public function get lastAnimationState():AnimationState
{
- return _currentTime;
+ return _lastAnimationState;
}
- private var _totalTime:Number;
+ private var _animationList:Vector.;
/**
- * Get the total elapsed time in second.
+ * An vector containing all AnimationData names the Animation can play.
+ * @see dragonBones.objects.AnimationData.
*/
- public function get totalTime():Number
+ public function get animationList():Vector.
{
- return _totalTime;
+ return _animationList;
}
- private var _isPlaying:Boolean;
-
- /**
- * Indicates whether the animation is playing or not.
- */
public function get isPlaying():Boolean
{
- if (_isPlaying)
+ return _isPlaying && !isComplete;
+ }
+
+ public function get isComplete():Boolean
+ {
+ if(_lastAnimationState)
{
- return _loop >= 0 || _currentTime < _totalTime;
+ if(!_lastAnimationState.isComplete)
+ {
+ return false;
+ }
+ var j:int = _animationLayer.length;
+ while(j --)
+ {
+ var animationStateList:Vector. = _animationLayer[j];
+ var i:int = animationStateList.length;
+ while(i --)
+ {
+ if(!animationStateList[i].isComplete)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
}
return false;
}
+ private var _animationDataList:Vector.;
/**
- * Indicates whether the animation has completed or not.
+ * The AnimationData list associated with this Animation instance.
+ * @see dragonBones.objects.AnimationData.
*/
- public function get isComplete():Boolean
+ public function get animationDataList():Vector.
{
- return _loop < 0 && _currentTime >= _totalTime;
+ return _animationDataList;
}
-
- /**
- * Indicates whether the animation is paused or not.
- */
- public function get isPause():Boolean
+ public function set animationDataList(value:Vector.):void
{
- return !_isPlaying;
+ _animationDataList = value;
+ _animationList.length = 0;
+ for each(var animationData:AnimationData in _animationDataList)
+ {
+ _animationList[_animationList.length] = animationData.name;
+ }
}
private var _timeScale:Number = 1;
-
/**
* The amount by which passed time should be scaled. Used to slow down or speed up animations. Defaults to 1.
*/
@@ -180,9 +177,6 @@
{
return _timeScale;
}
- /**
- * @private
- */
public function set timeScale(value:Number):void
{
if (value < 0)
@@ -190,153 +184,195 @@
value = 0;
}
_timeScale = value;
-
- for each (var bone:Bone in _armature._boneDepthList)
- {
- if (bone.childArmature)
- {
- bone.childArmature.animation.timeScale = _timeScale;
- }
- }
- }
-
- private var _movementID:String;
-
- /**
- * The name ID of the current MovementData.
- * @see dragonBones.objects.MovementData.
- */
- public function get movementID():String
- {
- return _movementID;
- }
-
- /**
- * An vector containing all MovementData names the animation can play.
- * @see dragonBones.objects.MovementData.
- */
- public function get movementList():Vector.
- {
- return _animationData ? _animationData.movementList : null;
}
/**
- * Creates a new Animation instance and attaches it to the passed Arnature.
+ * Creates a new Animation instance and attaches it to the passed Armature.
* @param An Armature to attach this Animation instance to.
*/
public function Animation(armature:Armature)
{
_armature = armature;
+ _animationLayer = new Vector.>;
+ _animationList = new Vector.;
+
+ tweenEnabled = true;
}
+
/**
* Qualifies all resources used by this Animation instance for garbage collection.
*/
public function dispose():void
{
+ if(!_armature)
+ {
+ return;
+ }
stop();
- _animationData = null;
- _movementData = null;
+ var i:int = _animationLayer.length;
+ while(i --)
+ {
+ var animationStateList:Vector. = _animationLayer[i];
+ var j:int = animationStateList.length;
+ while(j --)
+ {
+ AnimationState.returnObject(animationStateList[j]);
+ }
+ animationStateList.length = 0;
+ }
+ _animationLayer.length = 0;
+ _animationList.length = 0;
+
_armature = null;
+ _animationLayer = null;
+ _animationDataList = null;
+ _animationList = null;
}
+
/**
- * Move the playhead to that MovementData id
- * @param The id of the MovementData to play.
- * @param A tween time to apply (> 0)
- * @param The duration in seconds of that MovementData.
- * @param Whether that MovementData should loop or play only once (true/false).
- * @see dragonBones.objects.MovementData.
+ * Move the playhead to that AnimationData
+ * @param animationName The name of the AnimationData to play.
+ * @param fadeInTime A fade time to apply (> 0)
+ * @param duration The duration of that AnimationData.
+ * @param loop Loop(0:loop forever, 1~+∞:loop times, -1~-∞:will fade animation after loop complete).
+ * @param layer The layer of the animation.
+ * @param fadeOutMode Fade out mode.
+ * @param displayControl Display control.
+ * @param pauseFadeOut Pause other animation playing.
+ * @param pauseFadeIn Pause this animation playing before fade in complete.
+ * @see dragonBones.objects.AnimationData.
+ * @see dragonBones.animation.AnimationState.
*/
- public function gotoAndPlay(movementID:String, tweenTime:Number = -1, duration:Number = -1, loop:* = null):void
+ public function gotoAndPlay(
+ animationName:String,
+ fadeInTime:Number = -1,
+ duration:Number = -1,
+ loop:Number = NaN,
+ layer:uint = 0,
+ group:String = null,
+ fadeOutMode:String = SAME_LAYER_AND_GROUP,
+ displayControl:Boolean = true,
+ pauseFadeOut:Boolean = true,
+ pauseFadeIn:Boolean = true
+ ):AnimationState
{
- if (!_animationData)
+ if (!_animationDataList)
{
- return;
+ return null;
}
- var movementData:MovementData = _animationData.getMovementData(movementID as String);
- if (!movementData)
+ var i:int = _animationDataList.length;
+ var animationData:AnimationData;
+ while(i --)
{
- return;
+ if(_animationDataList[i].name == animationName)
+ {
+ animationData = _animationDataList[i];
+ break;
+ }
+ }
+ if (!animationData)
+ {
+ return null;
}
- _movementData = movementData;
+
_isPlaying = true;
- _currentTime = 0;
- _breakFrameWhile = true;
- var exMovementID:String = _movementID;
- _movementID = movementID as String;
+ //
+ fadeInTime = fadeInTime < 0?(animationData.fadeInTime < 0?0.3:animationData.fadeInTime):fadeInTime;
- if (tweenTime >= 0)
- {
- _totalTime = tweenTime;
- }
- else if (tweenEnabled && exMovementID)
+ var durationScale:Number;
+ if(duration < 0)
{
- _totalTime = _movementData.durationTo;
+ durationScale = animationData.scale < 0?1:animationData.scale;
}
else
{
- _totalTime = 0;
+ durationScale = duration / animationData.duration;
}
- if (_totalTime < 0)
- {
- _totalTime = 0;
- }
+ loop = isNaN(loop)?animationData.loop:loop;
+ layer = addLayer(layer);
- _duration = duration >= 0 ? duration : _movementData.durationTween;
- if (_duration < 0)
+ //autoSync = autoSync && !pauseFadeOut && !pauseFadeIn;
+ var animationState:AnimationState;
+ var animationStateList:Vector.;
+ switch(fadeOutMode)
{
- _duration = 0;
+ case NONE:
+ break;
+ case SAME_LAYER:
+ animationStateList = _animationLayer[layer];
+ i = animationStateList.length;
+ while(i --)
+ {
+ animationState = animationStateList[i];
+ animationState.fadeOut(fadeInTime, pauseFadeOut);
+ }
+ break;
+ case SAME_GROUP:
+ j = _animationLayer.length;
+ while(j --)
+ {
+ animationStateList = _animationLayer[j];
+ i = animationStateList.length;
+ while(i --)
+ {
+ animationState = animationStateList[i];
+ if(animationState.group == group)
+ {
+ animationState.fadeOut(fadeInTime, pauseFadeOut);
+ }
+ }
+ }
+ break;
+ case ALL:
+ var j:int = _animationLayer.length;
+ while(j --)
+ {
+ animationStateList = _animationLayer[j];
+ i = animationStateList.length;
+ while(i --)
+ {
+ animationState = animationStateList[i];
+ animationState.fadeOut(fadeInTime, pauseFadeOut);
+ }
+ }
+ break;
+ case SAME_LAYER_AND_GROUP:
+ default:
+ animationStateList = _animationLayer[layer];
+ i = animationStateList.length;
+ while(i --)
+ {
+ animationState = animationStateList[i];
+ if(animationState.group == group)
+ {
+ animationState.fadeOut(fadeInTime, pauseFadeOut);
+ }
+ }
+ break;
}
- loop = Boolean(loop === null ? _movementData.loop : loop);
- _rawDuration = _movementData.duration;
+ _lastAnimationState = AnimationState.borrowObject();
+ _lastAnimationState.group = group;
+ _lastAnimationState.tweenEnabled = tweenEnabled;
+ _lastAnimationState.fadeIn(_armature, animationData, fadeInTime, 1 / durationScale, loop, layer, displayControl, pauseFadeIn);
- _loop = loop ? 0 : -1;
- if (_rawDuration == 0)
- {
- _playType = SINGLE;
- }
- else
- {
- _nextFrameDataTimeEdge = 0;
- _nextFrameDataID = 0;
- if (loop)
- {
- _playType = LOOP_START;
- }
- else
- {
- _playType = LIST_START;
- }
- }
-
- var tweenEasing:Number = _movementData.tweenEasing;
+ addState(_lastAnimationState);
- for each (var bone:Bone in _armature._boneDepthList)
+ var boneList:Vector. = _armature._boneList;
+ var bone:Bone;
+ i = boneList.length;
+ while(i --)
{
- var movementBoneData:MovementBoneData = _movementData.getMovementBoneData(bone.name);
- if (movementBoneData)
- {
- bone._tween.gotoAndPlay(movementBoneData, _rawDuration, loop, tweenEasing);
- if (bone.childArmature)
- {
- bone.childArmature.animation.gotoAndPlay(movementID);
- }
- }
- else
+ bone = boneList[i];
+ if(bone.childArmature)
{
- bone._tween.stop();
+ bone.childArmature.animation.gotoAndPlay(animationName, fadeInTime);
}
}
- if (_armature.hasEventListener(AnimationEvent.MOVEMENT_CHANGE))
- {
- var event:AnimationEvent = new AnimationEvent(AnimationEvent.MOVEMENT_CHANGE);
- event.exMovementID = exMovementID;
- event.movementID = _movementID;
- _armature.dispatchEvent(event);
- }
+ return _lastAnimationState;
}
/**
@@ -344,201 +380,233 @@
*/
public function play():void
{
- if (!_animationData)
+ if (!_animationDataList || _animationDataList.length == 0)
{
return;
}
-
- if (!_movementID)
+ if(!_lastAnimationState)
{
- if (movementList)
- {
- gotoAndPlay(movementList[0]);
- }
- return;
- }
-
- if (isComplete)
- {
- gotoAndPlay(_movementID);
+ gotoAndPlay(_animationDataList[0].name);
}
else if (!_isPlaying)
{
_isPlaying = true;
- for each(var bone:Bone in _armature._boneDepthList)
- {
- if (bone.childArmature)
- {
- bone.childArmature.animation.play();
- }
- }
+ }
+ else
+ {
+ gotoAndPlay(_lastAnimationState.name);
}
}
- /** @private */
- dragonBones_internal function clearMovement():void
+ public function stop():void
{
- _movementID = null;
+ _isPlaying = false;
}
/**
- * Stop the playhead.
+ * Returns the AnimationState named name.
+ * @return A AnimationState instance.
+ * @see dragonBones.animation.AnimationState.
*/
- public function stop():void
+ public function getState(name:String, layer:uint = 0):AnimationState
{
- _isPlaying = false;
+ var l:int = _animationLayer.length;
+ if(l == 0)
+ {
+ return null;
+ }
+ else if(layer >= l)
+ {
+ layer = l - 1;
+ }
- for each(var bone:Bone in _armature._boneDepthList)
+ var animationStateList:Vector. = _animationLayer[layer];
+ if(!animationStateList)
+ {
+ return null;
+ }
+ var i:int = animationStateList.length;
+ while(i --)
{
- if (bone.childArmature)
+ if(animationStateList[i].name == name)
{
- bone.childArmature.animation.stop();
+ return animationStateList[i];
}
}
+
+ return null;
}
- /** @private */
- dragonBones_internal function advanceTime(passedTime:Number):void
+ public function hasAnimation(animationName:String):Boolean
{
- if (_isPlaying && (_loop > 0 || _currentTime < _totalTime || _totalTime == 0))
+ var i:int = _animationDataList.length;
+ while(i --)
{
- var progress:Number;
- if (_totalTime > 0)
+ if(_animationDataList[i].name == animationName)
{
- _currentTime += passedTime * _timeScale;
- progress = _currentTime / _totalTime;
- }
- else
- {
- _currentTime = 1;
- _totalTime = 1;
- progress = 1;
+ return true;
}
+ }
+
+ return false;
+ }
+
+ public function advanceTime(passedTime:Number):void
+ {
+ if(!_isPlaying)
+ {
+ return;
+ }
+ passedTime *= _timeScale;
+
+ var l:int = _armature._boneList.length;
+ var i:int;
+ var j:int;
+ var k:int = l;
+ var bone:Bone;
+ var boneName:String;
+ var weigthLeft:Number;
+
+ var x:Number;
+ var y:Number;
+ var skewX:Number;
+ var skewY:Number;
+ var scaleX:Number;
+ var scaleY:Number;
+ var pivotX:Number;
+ var pivotY:Number;
+
+ var layerTotalWeight:Number;
+ var animationStateList:Vector.;
+ var animationState:AnimationState;
+ var timelineState:TimelineState;
+ var weight:Number;
+ var transform:DBTransform;
+ var pivot:Point;
+
+ l --;
+ while(k --)
+ {
+ bone = _armature._boneList[k];
+ boneName = bone.name;
+ weigthLeft = 1;
+
+ x = 0;
+ y = 0;
+ skewX = 0;
+ skewY = 0;
+ scaleX = 0;
+ scaleY = 0;
+ pivotX = 0;
+ pivotY = 0;
- var event:AnimationEvent;
- if (_playType == LOOP)
+ i = _animationLayer.length;
+ while(i --)
{
- var loop:int = progress;
- if (loop != _loop)
+ layerTotalWeight = 0;
+ animationStateList = _animationLayer[i];
+ j = animationStateList.length;
+ while(j --)
{
- _loop = loop;
- _nextFrameDataTimeEdge = 0;
- if (_armature.hasEventListener(AnimationEvent.LOOP_COMPLETE))
+ animationState = animationStateList[j];
+ if(k == l)
+ {
+ if(animationState.advanceTime(passedTime))
+ {
+ removeState(animationState);
+ continue;
+ }
+ }
+
+ timelineState = animationState._timelineStates[boneName];
+
+ if(timelineState)
{
- event = new AnimationEvent(AnimationEvent.LOOP_COMPLETE);
- event.movementID = _movementID;
+ weight = animationState._fadeWeight * animationState.weight * weigthLeft;
+ transform = timelineState.transform;
+ pivot = timelineState.pivot;
+ x += transform.x * weight;
+ y += transform.y * weight;
+ skewX += transform.skewX * weight;
+ skewY += transform.skewY * weight;
+ scaleX += transform.scaleX * weight;
+ scaleY += transform.scaleY * weight;
+ pivotX += pivot.x * weight;
+ pivotY += pivot.y * weight;
+
+ layerTotalWeight += weight;
}
}
- }
- else if (progress >= 1)
- {
- switch (_playType)
+
+ if(layerTotalWeight >= weigthLeft)
{
- case SINGLE:
- case LIST:
- progress = 1;
- if (_armature.hasEventListener(AnimationEvent.COMPLETE))
- {
- event = new AnimationEvent(AnimationEvent.COMPLETE);
- event.movementID = _movementID;
- }
- break;
- case LIST_START:
- progress = 0;
- _playType = LIST;
- _currentTime = 0;
- _totalTime = _duration;
- if (_armature.hasEventListener(AnimationEvent.START))
- {
- event = new AnimationEvent(AnimationEvent.START);
- event.movementID = _movementID;
- }
- break;
- case LOOP_START:
- progress = 0;
- _playType = LOOP;
- _currentTime = 0;
- _totalTime = _duration;
- if (_armature.hasEventListener(AnimationEvent.START))
- {
- event = new AnimationEvent(AnimationEvent.START);
- event.movementID = _movementID;
- }
- break;
+ break;
}
- }
-
- var i:int = _armature._boneDepthList.length;
- while(i --)
- {
- _armature._boneDepthList[i]._tween.advanceTime(progress, _playType);
- }
-
- if ((_playType == LIST || _playType == LOOP) && _movementData._movementFrameList.length > 0)
- {
- if (_loop > 0)
+ else
{
- progress -= _loop;
+ weigthLeft -= layerTotalWeight;
}
- updateFrameData(progress);
}
+ transform = bone._tween;
+ pivot = bone._tweenPivot;
- if (event)
- {
- _armature.dispatchEvent(event);
- }
+ transform.x = x;
+ transform.y = y;
+ transform.skewX = skewX;
+ transform.skewY = skewY;
+ transform.scaleX = scaleX;
+ transform.scaleY = scaleY;
+ pivot.x = pivotX;
+ pivot.y = pivotY;
}
}
- private function updateFrameData(progress:Number):void
+ /** @private */
+ /*dragonBones_internal function setStatesDisplayControl(animationState:AnimationState):void
{
- var playedTime:Number = _rawDuration * progress;
- if (playedTime >= _nextFrameDataTimeEdge)
+ var i:int = _animationLayer.length;
+ var animationStateList:Vector. = _animationLayer[i];
+ var j:int;
+ while(i --)
{
- _breakFrameWhile = false;
- var length:uint = _movementData._movementFrameList.length;
- do
+ animationStateList = _animationLayer[i];
+ j = animationStateList.length;
+ while(j --)
{
- var currentFrameDataID:int = _nextFrameDataID;
- var currentFrameData:MovementFrameData = _movementData._movementFrameList[currentFrameDataID];
- var frameDuration:Number = currentFrameData.duration;
- _nextFrameDataTimeEdge += frameDuration;
- if (++_nextFrameDataID >= length)
- {
- _nextFrameDataID = 0;
- }
- arriveFrameData(currentFrameData);
- if (_breakFrameWhile)
- {
- break;
- }
- } while (playedTime >= _nextFrameDataTimeEdge);
+ animationStateList[j].displayControl = animationStateList[j] == animationState;
+ }
}
- }
+ }*/
- private function arriveFrameData(movementFrameData:MovementFrameData):void
+ private function addLayer(layer:uint):uint
{
- //Tracer.reveal(movementFrameData)
- if (movementFrameData.event && _armature.hasEventListener(FrameEvent.MOVEMENT_FRAME_EVENT))
- {
- var frameEvent:FrameEvent = new FrameEvent(FrameEvent.MOVEMENT_FRAME_EVENT);
- frameEvent.movementID = _movementID;
- frameEvent.frameLabel = movementFrameData.event;
- _armature.dispatchEvent(frameEvent);
- }
- if (movementFrameData.sound && _soundManager.hasEventListener(SoundEvent.SOUND))
+ if(layer >= _animationLayer.length)
{
- var soundEvent:SoundEvent = new SoundEvent(SoundEvent.SOUND);
- soundEvent.movementID = _movementID;
- soundEvent.sound = movementFrameData.sound;
- soundEvent._armature = _armature;
- _soundManager.dispatchEvent(soundEvent);
+ layer = _animationLayer.length;
+ _animationLayer[layer] = new Vector.;
}
- if (movementFrameData.movement)
+ return layer;
+ }
+
+ private function addState(animationState:AnimationState):void
+ {
+ var animationStateList:Vector. = _animationLayer[animationState.layer];
+ animationStateList[animationStateList.length] = animationState;
+ }
+
+ private function removeState(animationState:AnimationState):void
+ {
+ var layer:int = animationState.layer;
+ var animationStateList:Vector. = _animationLayer[layer];
+ animationStateList.splice(animationStateList.indexOf(animationState), 1);
+
+ AnimationState.returnObject(animationState);
+
+ if(animationStateList.length == 0 && layer == _animationLayer.length - 1)
{
- gotoAndPlay(movementFrameData.movement);
+ _animationLayer.length --;
}
}
}
-
+
}
\ No newline at end of file
diff --git a/src/dragonBones/animation/AnimationState.as b/src/dragonBones/animation/AnimationState.as
new file mode 100644
index 0000000..fd2e436
--- /dev/null
+++ b/src/dragonBones/animation/AnimationState.as
@@ -0,0 +1,641 @@
+package dragonBones.animation
+{
+ import dragonBones.Armature;
+ import dragonBones.Bone;
+ import dragonBones.Slot;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.events.AnimationEvent;
+ import dragonBones.objects.AnimationData;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.Frame;
+ import dragonBones.objects.TransformTimeline;
+
+ use namespace dragonBones_internal;
+
+ final public class AnimationState
+ {
+ private static var _pool:Vector. = new Vector.;
+
+ /** @private */
+ dragonBones_internal static function borrowObject():AnimationState
+ {
+ if(_pool.length == 0)
+ {
+ return new AnimationState();
+ }
+ return _pool.pop();
+ }
+
+ /** @private */
+ dragonBones_internal static function returnObject(animationState:AnimationState):void
+ {
+ animationState.clear();
+
+ if(_pool.indexOf(animationState) < 0)
+ {
+ _pool[_pool.length] = animationState;
+ }
+ }
+
+ /** @private */
+ dragonBones_internal static function clear():void
+ {
+ var i:int = _pool.length;
+ while(i --)
+ {
+ _pool[i].clear();
+ }
+ _pool.length = 0;
+
+ TimelineState.clear();
+ }
+
+ public var enabled:Boolean;
+ public var tweenEnabled:Boolean;
+ public var blend:Boolean;
+ public var group:String;
+ public var weight:Number;
+
+ /** @private */
+ dragonBones_internal var _timelineStates:Object;
+ /** @private */
+ dragonBones_internal var _fadeWeight:Number;
+
+ private var _armature:Armature;
+ private var _currentFrame:Frame;
+ private var _mixingTransforms:Object;
+ private var _fadeState:int;
+ private var _fadeInTime:Number;
+ private var _fadeOutTime:Number;
+ private var _fadeOutBeginTime:Number;
+ private var _fadeOutWeight:Number;
+ private var _fadeIn:Boolean;
+ private var _fadeOut:Boolean;
+ private var _pauseBeforeFadeInComplete:Boolean;
+
+ private var _name:String;
+ public function get name():String
+ {
+ return _name;
+ }
+
+ private var _clip:AnimationData;
+ public function get clip():AnimationData
+ {
+ return _clip;
+ }
+
+ private var _loopCount:int;
+ public function get loopCount():int
+ {
+ return _loopCount;
+ }
+
+ private var _loop:int;
+ public function get loop():int
+ {
+ return _loop;
+ }
+
+ private var _layer:uint;
+ public function get layer():uint
+ {
+ return _layer;
+ }
+
+ private var _isPlaying:Boolean;
+ public function get isPlaying():Boolean
+ {
+ return _isPlaying && !_isComplete;
+ }
+
+ private var _isComplete:Boolean;
+ public function get isComplete():Boolean
+ {
+ return _isComplete;
+ }
+
+ public function get fadeInTime():Number
+ {
+ return _fadeInTime;
+ }
+
+ private var _totalTime:Number;
+ public function get totalTime():Number
+ {
+ return _totalTime;
+ }
+
+ private var _currentTime:Number;
+ public function get currentTime():Number
+ {
+ return _currentTime;
+ }
+ public function set currentTime(value:Number):void
+ {
+ if(value < 0 || isNaN(value))
+ {
+ value = 0;
+ }
+ //
+ _currentTime = value;
+ }
+
+ private var _timeScale:Number;
+ public function get timeScale():Number
+ {
+ return _timeScale;
+ }
+ public function set timeScale(value:Number):void
+ {
+ if(value < 0)
+ {
+ value = 0;
+ }
+ else if(isNaN(value))
+ {
+ value = 1;
+ }
+ else if(_timeScale == Infinity)
+ {
+ //*
+ _timeScale = 1;
+ }
+ _timeScale = value;
+ }
+
+ private var _displayControl:Boolean;
+ public function get displayControl():Boolean
+ {
+ return _displayControl;
+ }
+ public function set displayControl(value:Boolean):void
+ {
+ if(_displayControl != value)
+ {
+ _displayControl = value;
+ /*if(_displayControl)
+ {
+ _armature.animation.setStatesDisplayControl(this);
+ }*/
+ }
+ }
+
+ public function AnimationState()
+ {
+ _timelineStates = {};
+ }
+
+ /** @private */
+ dragonBones_internal function fadeIn(armature:Armature, clip:AnimationData, fadeInTime:Number, timeScale:Number, loop:int, layer:uint, displayControl:Boolean, pauseBeforeFadeInComplete:Boolean):void
+ {
+ _armature = armature;
+ _clip = clip;
+ _name = _clip.name;
+ _layer = layer;
+
+ _totalTime = _clip.duration;
+ if(Math.round(_clip.duration * _clip.frameRate) < 2 || timeScale == Infinity)
+ {
+ _timeScale = 1;
+ _currentTime = _totalTime;
+ if(_loop >= 0)
+ {
+ _loop = 1;
+ }
+ else
+ {
+ _loop = -1;
+ }
+ _pauseBeforeFadeInComplete = false;
+ }
+ else
+ {
+ _timeScale = timeScale;
+ _currentTime = 0;
+ _loop = loop;
+ _pauseBeforeFadeInComplete = pauseBeforeFadeInComplete;
+ }
+
+ _fadeInTime = fadeInTime * _timeScale;
+
+
+ _loopCount = -1;
+ _fadeState = 1;
+ _fadeOutBeginTime = 0;
+ _fadeOutWeight = NaN;
+ _fadeWeight = 0;
+ _displayControl = displayControl;
+ _isPlaying = true;
+ _isComplete = false;
+ _fadeIn = true;
+ _fadeOut = false;
+
+ weight = 1;
+ blend = true;
+ enabled = true;
+ tweenEnabled = true;
+
+ updateTimelineStates();
+ }
+
+ public function fadeOut(fadeOutTime:Number, pause:Boolean = false):void
+ {
+ if(!isNaN(_fadeOutWeight))
+ {
+ return;
+ }
+ _fadeState = -1;
+ _fadeOutWeight = _fadeWeight;
+ _fadeOutTime = fadeOutTime * _timeScale;
+ _fadeOutBeginTime = _currentTime;
+ _isPlaying = !pause;
+ _fadeOut = true;
+ _displayControl = false;
+
+ for each(var timelineState:TimelineState in _timelineStates)
+ {
+ timelineState.fadeOut();
+ }
+
+ enabled = true;
+ }
+
+ public function play():void
+ {
+ _isPlaying = true;
+ }
+
+ public function stop():void
+ {
+ _isPlaying = false;
+ }
+
+ public function getMixingTransform(timelineName:String):int
+ {
+ if(_mixingTransforms)
+ {
+ return int(_mixingTransforms[timelineName]);
+ }
+ return -1;
+ }
+
+ public function addMixingTransform(timelineName:String, type:int = 2, recursive:Boolean = true):void
+ {
+ if(_clip && _clip.getTimeline(timelineName))
+ {
+ if(!_mixingTransforms)
+ {
+ _mixingTransforms = {};
+ }
+ if(recursive)
+ {
+ var i:int = _armature._boneList.length;
+ var bone:Bone;
+ var currentBone:Bone;
+ while(i --)
+ {
+ bone = _armature._boneList[i];
+ if(bone.name == timelineName)
+ {
+ currentBone = bone;
+ }
+ if(currentBone && (currentBone == bone || currentBone.contains(bone)))
+ {
+ _mixingTransforms[bone.name] = type;
+ }
+ }
+ }
+ else
+ {
+ _mixingTransforms[timelineName] = type;
+ }
+
+ updateTimelineStates();
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+
+ public function removeMixingTransform(timelineName:String = null, recursive:Boolean = true):void
+ {
+ if(timelineName)
+ {
+ if(recursive)
+ {
+ var i:int = _armature._boneList.length;
+ var bone:Bone;
+ var currentBone:Bone;
+ while(i --)
+ {
+ bone = _armature._boneList[i];
+ if(bone.name == timelineName)
+ {
+ currentBone = bone;
+ }
+ if(currentBone && (currentBone == bone || currentBone.contains(bone)))
+ {
+ delete _mixingTransforms[bone.name];
+ }
+ }
+ }
+ else
+ {
+ delete _mixingTransforms[timelineName];
+ }
+
+ for each(timelineName in _mixingTransforms)
+ {
+ var hasMixing:Boolean = true;
+ break;
+ }
+ if(!hasMixing)
+ {
+ _mixingTransforms = null;
+ }
+ }
+ else
+ {
+ _mixingTransforms = null;
+ }
+
+ updateTimelineStates();
+ }
+
+ public function advanceTime(passedTime:Number):Boolean
+ {
+ if(!enabled)
+ {
+ return false;
+ }
+
+ if(_fadeIn)
+ {
+ _fadeIn = false;
+ if(_armature.hasEventListener(AnimationEvent.FADE_IN))
+ {
+ var event:AnimationEvent = new AnimationEvent(AnimationEvent.FADE_IN);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ event = null;
+ };
+ }
+
+ if(_fadeOut)
+ {
+ _fadeOut = false;
+ if(_armature.hasEventListener(AnimationEvent.FADE_OUT))
+ {
+ event = new AnimationEvent(AnimationEvent.FADE_OUT);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ event = null;
+ }
+ }
+
+ _currentTime += passedTime * _timeScale;
+
+ if(_isPlaying && !_isComplete)
+ {
+ if(_pauseBeforeFadeInComplete)
+ {
+ _pauseBeforeFadeInComplete = false;
+ _isPlaying = false;
+ var progress:Number = 0;
+ var currentLoopCount:int = progress;
+ }
+ else
+ {
+ progress = _currentTime / _totalTime;
+
+ //update loopCount
+ currentLoopCount = progress;
+ if(currentLoopCount != _loopCount)
+ {
+ if(_loopCount == -1)
+ {
+ if(_armature.hasEventListener(AnimationEvent.START))
+ {
+ event = new AnimationEvent(AnimationEvent.START);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ event = null;
+ }
+ }
+ _loopCount = currentLoopCount;
+ if(_loopCount)
+ {
+ if(_loop && _loopCount * _loopCount >= _loop * _loop - 1)
+ {
+ _isComplete = true;
+ _isPlaying = false;
+ progress = 1;
+ currentLoopCount = 0;
+ if(_armature.hasEventListener(AnimationEvent.COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.COMPLETE);
+ event.animationState = this;
+ }
+ }
+ else
+ {
+ if(_armature.hasEventListener(AnimationEvent.LOOP_COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.LOOP_COMPLETE);
+ event.animationState = this;
+ }
+ }
+ }
+ }
+ }
+
+
+ for each(var timeline:TimelineState in _timelineStates)
+ {
+ timeline.update(progress);
+ }
+
+ //
+ if(_clip.frameList.length > 0)
+ {
+ var playedTime:Number = _totalTime * (progress - currentLoopCount);
+ var isArrivedFrame:Boolean = false;
+ var frameIndex:int;
+ while(!_currentFrame || playedTime > _currentFrame.position + _currentFrame.duration || playedTime < _currentFrame.position)
+ {
+ if(isArrivedFrame)
+ {
+ _armature.arriveAtFrame(_currentFrame, null, this, true);
+ }
+ isArrivedFrame = true;
+ if(_currentFrame)
+ {
+ frameIndex = _clip.frameList.indexOf(_currentFrame);
+ frameIndex ++;
+ if(frameIndex >= _clip.frameList.length)
+ {
+ frameIndex = 0;
+ }
+ _currentFrame = _clip.frameList[frameIndex];
+ }
+ else
+ {
+ _currentFrame = _clip.frameList[0];
+ }
+ }
+
+ if(isArrivedFrame)
+ {
+ _armature.arriveAtFrame(_currentFrame, null, this, false);
+ }
+ }
+
+ if(event)
+ {
+ _armature.dispatchEvent(event);
+ }
+ }
+
+ //update weight and fadeState
+ if(_fadeState > 0)
+ {
+ if(_fadeInTime == 0)
+ {
+ _fadeWeight = 1;
+ _fadeState = 0;
+ _isPlaying = true;
+ if(_armature.hasEventListener(AnimationEvent.FADE_IN_COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.FADE_IN_COMPLETE);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ }
+ }
+ else
+ {
+ _fadeWeight = _currentTime / _fadeInTime;
+ if(_fadeWeight >= 1)
+ {
+ _fadeWeight = 1;
+ _fadeState = 0;
+ if(!_isPlaying)
+ {
+ _currentTime -= _fadeInTime;
+ }
+ _isPlaying = true;
+ if(_armature.hasEventListener(AnimationEvent.FADE_IN_COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.FADE_IN_COMPLETE);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ }
+ }
+ }
+ }
+ else if(_fadeState < 0)
+ {
+ if(_fadeOutTime == 0)
+ {
+ _fadeWeight = 0;
+ _fadeState = 0;
+ if(_armature.hasEventListener(AnimationEvent.FADE_OUT_COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.FADE_OUT_COMPLETE);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ }
+ return true;
+ }
+ else
+ {
+ _fadeWeight = (1 - (_currentTime - _fadeOutBeginTime) / _fadeOutTime) * _fadeOutWeight;
+ if(_fadeWeight <= 0)
+ {
+ _fadeWeight = 0;
+ _fadeState = 0;
+ if(_armature.hasEventListener(AnimationEvent.FADE_OUT_COMPLETE))
+ {
+ event = new AnimationEvent(AnimationEvent.FADE_OUT_COMPLETE);
+ event.animationState = this;
+ _armature.dispatchEvent(event);
+ }
+ return true;
+ }
+ }
+ }
+
+ if(_isComplete && _loop < 0)
+ {
+ fadeOut((_fadeOutWeight || _fadeInTime) / _timeScale, true);
+ }
+
+ return false;
+ }
+
+ private function updateTimelineStates():void
+ {
+ if(_mixingTransforms)
+ {
+ for(var timelineName:String in _timelineStates)
+ {
+ if(_mixingTransforms[timelineName] == null)
+ {
+ removeTimelineState(timelineName);
+ }
+ }
+
+ for(timelineName in _mixingTransforms)
+ {
+ if(!_timelineStates[timelineName])
+ {
+ addTimelineState(timelineName);
+ }
+ }
+ }
+ else
+ {
+ for(timelineName in _clip.timelines)
+ {
+ if(!_timelineStates[timelineName])
+ {
+ addTimelineState(timelineName);
+ }
+ }
+ }
+ }
+
+ private function addTimelineState(timelineName:String):void
+ {
+ var bone:Bone = _armature.getBone(timelineName);
+ if(bone)
+ {
+ var timelineState:TimelineState = TimelineState.borrowObject();
+ var timeline:TransformTimeline = _clip.getTimeline(timelineName);
+ timelineState.fadeIn(bone, this, timeline);
+ _timelineStates[timelineName] = timelineState;
+ }
+ }
+
+ private function removeTimelineState(timelineName:String):void
+ {
+ TimelineState.returnObject(_timelineStates[timelineName] as TimelineState);
+ delete _timelineStates[timelineName];
+ }
+
+ private function clear():void
+ {
+ _armature = null;
+ _currentFrame = null;
+ _clip = null;
+ _mixingTransforms = null;
+ enabled = false;
+
+ for(var timelineName:String in _timelineStates)
+ {
+ removeTimelineState(timelineName);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/animation/TimelineState.as b/src/dragonBones/animation/TimelineState.as
new file mode 100644
index 0000000..f3cfa3a
--- /dev/null
+++ b/src/dragonBones/animation/TimelineState.as
@@ -0,0 +1,535 @@
+package dragonBones.animation
+{
+ import dragonBones.Bone;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.TransformFrame;
+ import dragonBones.objects.TransformTimeline;
+ import dragonBones.utils.TransformUtil;
+
+ import flash.geom.ColorTransform;
+ import flash.geom.Point;
+
+ use namespace dragonBones_internal;
+
+ /** @private */
+ public final class TimelineState
+ {
+ private static const HALF_PI:Number = Math.PI * 0.5;
+ private static const DOUBLE_PI:Number = Math.PI * 2;
+
+ private static var _pool:Vector. = new Vector.;
+
+ /** @private */
+ dragonBones_internal static function borrowObject():TimelineState
+ {
+ if(_pool.length == 0)
+ {
+ return new TimelineState();
+ }
+ return _pool.pop();
+ }
+
+ /** @private */
+ dragonBones_internal static function returnObject(timeline:TimelineState):void
+ {
+ if(_pool.indexOf(timeline) < 0)
+ {
+ _pool[_pool.length] = timeline;
+ }
+
+ timeline.clear();
+ }
+
+ /** @private */
+ dragonBones_internal static function clear():void
+ {
+ var i:int = _pool.length;
+ while(i --)
+ {
+ _pool[i].clear();
+ }
+ _pool.length = 0;
+ }
+
+ public static function getEaseValue(value:Number, easing:Number):Number
+ {
+ if (easing > 1)
+ {
+ var valueEase:Number = 0.5 * (1 - Math.cos(value * Math.PI )) - value;
+ easing -= 1;
+ }
+ else if (easing > 0)
+ {
+ valueEase = Math.sin(value * HALF_PI) - value;
+ }
+ else if (easing < 0)
+ {
+ valueEase = 1 - Math.cos(value * HALF_PI) - value;
+ easing *= -1;
+ }
+ return valueEase * easing + value;
+ }
+
+ public var transform:DBTransform;
+ public var pivot:Point;
+
+ public var update:Function;
+
+ private var _animationState:AnimationState;
+ private var _bone:Bone;
+ private var _timeline:TransformTimeline;
+ private var _currentFrame:TransformFrame;
+ private var _currentFramePosition:Number;
+ private var _currentFrameDuration:Number;
+ private var _durationTransform:DBTransform;
+ private var _durationPivot:Point;
+ private var _durationColor:ColorTransform;
+ private var _originTransform:DBTransform;
+ private var _originPivot:Point;
+
+ private var _tweenEasing:Number;
+ private var _tweenTransform:Boolean;
+ private var _tweenColor:Boolean;
+
+ private var _totalTime:Number;
+
+ public function TimelineState()
+ {
+ transform = new DBTransform();
+ pivot = new Point();
+
+ //_originTransform = new DBTransform();
+
+ _durationTransform = new DBTransform();
+ _durationPivot = new Point();
+ _durationColor = new ColorTransform();
+ }
+
+ public function fadeIn(bone:Bone, animationState:AnimationState, timeline:TransformTimeline):void
+ {
+ _bone = bone;
+ _animationState = animationState;
+ _timeline = timeline;
+
+ _originTransform = _timeline.originTransform;
+ _originPivot = _timeline.originPivot;
+ //_originTransform.copy(_timeline.originTransform);
+
+ /*
+ var bLRX:Number = _bone.origin.skewX + _bone.offset.skewX + _bone._tween.skewX;
+ var bLRY:Number = _bone.origin.skewY + _bone.offset.skewY + _bone._tween.skewY;
+
+ _originTransform.skewX = bLRX + TransformUtils.formatRadian(_originTransform.skewX - bLRX);
+ _originTransform.skewY = bLRY + TransformUtils.formatRadian(_originTransform.skewY - bLRY);
+ */
+
+ _totalTime = _animationState.totalTime;
+
+ transform.x = 0;
+ transform.y = 0;
+ transform.scaleX = 0;
+ transform.scaleY = 0;
+ transform.skewX = 0;
+ transform.skewY = 0;
+ pivot.x = 0;
+ pivot.y = 0;
+
+ _durationTransform.x = 0;
+ _durationTransform.y = 0;
+ _durationTransform.scaleX = 0;
+ _durationTransform.scaleY = 0;
+ _durationTransform.skewX = 0;
+ _durationTransform.skewY = 0;
+ _durationPivot.x = 0;
+ _durationPivot.y = 0;
+
+ switch(_timeline.frameList.length)
+ {
+ case 0:
+ _bone.arriveAtFrame(null, this, _animationState, false);
+ update = updateNothing;
+ break;
+ case 1:
+ update = updateSingle;
+ break;
+ default:
+ update = updateList;
+ break;
+ }
+ }
+
+ public function fadeOut():void
+ {
+ transform.skewX = TransformUtil.formatRadian(transform.skewX);
+ transform.skewY = TransformUtil.formatRadian(transform.skewY);
+ //_originTransform.skewX = TransformUtil.formatRadian(_originTransform.skewX);
+ //_originTransform.skewY = TransformUtil.formatRadian(_originTransform.skewY);
+ }
+
+ private function updateNothing(progress:Number):void
+ {
+
+ }
+
+ private function updateSingle(progress:Number):void
+ {
+ update = updateNothing;
+
+ if(_animationState.blend)
+ {
+ transform.copy(_originTransform);
+
+ pivot.x = _originPivot.x;
+ pivot.y = _originPivot.y;
+ }
+ else
+ {
+ transform.x =
+ transform.y =
+ transform.skewX =
+ transform.skewY =
+ transform.scaleX =
+ transform.scaleY = 0;
+
+ pivot.x = 0;
+ pivot.y = 0;
+ }
+
+ _currentFrame = _timeline.frameList[0] as TransformFrame;
+
+ if(_currentFrame.color)
+ {
+ _bone.updateColor(
+ _currentFrame.color.alphaOffset,
+ _currentFrame.color.redOffset,
+ _currentFrame.color.greenOffset,
+ _currentFrame.color.blueOffset,
+ _currentFrame.color.alphaMultiplier,
+ _currentFrame.color.redMultiplier,
+ _currentFrame.color.greenMultiplier,
+ _currentFrame.color.blueMultiplier,
+ true
+ );
+ }
+ else
+ {
+ _bone.updateColor(0, 0, 0, 0, 1, 1, 1, 1, false);
+ }
+
+
+ _bone.arriveAtFrame(_currentFrame, this, _animationState, false);
+ }
+
+ private function updateList(progress:Number):void
+ {
+ if(_timeline.scale == 0)
+ {
+ progress = 1;
+ }
+ else
+ {
+ progress /= _timeline.scale;
+ }
+
+ if(progress == 1)
+ {
+ progress = 0.99999999;
+ }
+
+ progress += _timeline.offset;
+ var loopCount:int = progress;
+ progress -= loopCount;
+
+ //
+ var playedTime:Number = _totalTime * progress;
+ var isArrivedFrame:Boolean = false;
+ var frameIndex:int;
+ while (!_currentFrame || playedTime > _currentFramePosition + _currentFrameDuration || playedTime < _currentFramePosition)
+ {
+ if(isArrivedFrame)
+ {
+ _bone.arriveAtFrame(_currentFrame, this, _animationState, true);
+ }
+ isArrivedFrame = true;
+ if(_currentFrame)
+ {
+ frameIndex = _timeline.frameList.indexOf(_currentFrame) + 1;
+ if(frameIndex >= _timeline.frameList.length)
+ {
+ frameIndex = 0;
+ }
+ _currentFrame = _timeline.frameList[frameIndex] as TransformFrame;
+ }
+ else
+ {
+ frameIndex = 0;
+ _currentFrame = _timeline.frameList[0] as TransformFrame;
+ }
+ _currentFrameDuration = _currentFrame.duration;
+ _currentFramePosition = _currentFrame.position;
+ }
+
+ if(isArrivedFrame)
+ {
+ frameIndex ++;
+ if(frameIndex >= _timeline.frameList.length)
+ {
+ frameIndex = 0;
+ }
+ var nextFrame:TransformFrame = _timeline.frameList[frameIndex] as TransformFrame;
+
+ if(frameIndex == 0 && _animationState.loop && _animationState.loopCount >= Math.abs(_animationState.loop) - 1 && ((_currentFramePosition + _currentFrameDuration) / _totalTime + loopCount - _timeline.offset) * _timeline.scale > 0.999999)// >= 1
+ {
+ update = updateNothing;
+ _tweenEasing = NaN;
+ }
+ else if(nextFrame.displayIndex < 0 || !_animationState.tweenEnabled)
+ {
+ _tweenEasing = NaN;
+ }
+ else if(isNaN(_animationState.clip.tweenEasing))
+ {
+ _tweenEasing = _currentFrame.tweenEasing;
+ }
+ else
+ {
+ _tweenEasing = _animationState.clip.tweenEasing;
+ }
+
+ if(isNaN(_tweenEasing))
+ {
+ _tweenTransform = false;
+ _tweenColor = false;
+ }
+ else
+ {
+ _durationTransform.x = nextFrame.transform.x - _currentFrame.transform.x;
+ _durationTransform.y = nextFrame.transform.y - _currentFrame.transform.y;
+ _durationTransform.skewX = nextFrame.transform.skewX - _currentFrame.transform.skewX;
+ _durationTransform.skewY = nextFrame.transform.skewY - _currentFrame.transform.skewY;
+ _durationTransform.scaleX = nextFrame.transform.scaleX - _currentFrame.transform.scaleX;
+ _durationTransform.scaleY = nextFrame.transform.scaleY - _currentFrame.transform.scaleY;
+
+ if(frameIndex == 0)
+ {
+ _durationTransform.skewX = TransformUtil.formatRadian(_durationTransform.skewX);
+ _durationTransform.skewY = TransformUtil.formatRadian(_durationTransform.skewY);
+ }
+
+ _durationPivot.x = nextFrame.pivot.x - _currentFrame.pivot.x;
+ _durationPivot.y = nextFrame.pivot.y - _currentFrame.pivot.y;
+
+ if(
+ _durationTransform.x != 0 ||
+ _durationTransform.y != 0 ||
+ _durationTransform.skewX != 0 ||
+ _durationTransform.skewY != 0 ||
+ _durationTransform.scaleX != 0 ||
+ _durationTransform.scaleY != 0 ||
+ _durationPivot.x != 0 ||
+ _durationPivot.y != 0
+ )
+ {
+ _tweenTransform = true;
+ }
+ else
+ {
+ _tweenTransform = false;
+ }
+
+ if(_currentFrame.color && nextFrame.color)
+ {
+ _durationColor.alphaOffset = nextFrame.color.alphaOffset - _currentFrame.color.alphaOffset;
+ _durationColor.redOffset = nextFrame.color.redOffset - _currentFrame.color.redOffset;
+ _durationColor.greenOffset = nextFrame.color.greenOffset - _currentFrame.color.greenOffset;
+ _durationColor.blueOffset = nextFrame.color.blueOffset - _currentFrame.color.blueOffset;
+
+ _durationColor.alphaMultiplier = nextFrame.color.alphaMultiplier - _currentFrame.color.alphaMultiplier;
+ _durationColor.redMultiplier = nextFrame.color.redMultiplier - _currentFrame.color.redMultiplier;
+ _durationColor.greenMultiplier = nextFrame.color.greenMultiplier - _currentFrame.color.greenMultiplier;
+ _durationColor.blueMultiplier = nextFrame.color.blueMultiplier - _currentFrame.color.blueMultiplier;
+
+ if(
+ _durationColor.alphaOffset != 0 ||
+ _durationColor.redOffset != 0 ||
+ _durationColor.greenOffset != 0 ||
+ _durationColor.blueOffset != 0 ||
+ _durationColor.alphaMultiplier != 0 ||
+ _durationColor.redMultiplier != 0 ||
+ _durationColor.greenMultiplier != 0 ||
+ _durationColor.blueMultiplier != 0
+ )
+ {
+ _tweenColor = true;
+ }
+ else
+ {
+ _tweenColor = false;
+ }
+ }
+ else if(_currentFrame.color)
+ {
+ _tweenColor = true;
+ _durationColor.alphaOffset = -_currentFrame.color.alphaOffset;
+ _durationColor.redOffset = -_currentFrame.color.redOffset;
+ _durationColor.greenOffset = -_currentFrame.color.greenOffset;
+ _durationColor.blueOffset = -_currentFrame.color.blueOffset;
+
+ _durationColor.alphaMultiplier = 1 - _currentFrame.color.alphaMultiplier;
+ _durationColor.redMultiplier = 1 - _currentFrame.color.redMultiplier;
+ _durationColor.greenMultiplier = 1 - _currentFrame.color.greenMultiplier;
+ _durationColor.blueMultiplier = 1 - _currentFrame.color.blueMultiplier;
+ }
+ else if(nextFrame.color)
+ {
+ _tweenColor = true;
+ _durationColor.alphaOffset = nextFrame.color.alphaOffset;
+ _durationColor.redOffset = nextFrame.color.redOffset;
+ _durationColor.greenOffset = nextFrame.color.greenOffset;
+ _durationColor.blueOffset = nextFrame.color.blueOffset;
+
+ _durationColor.alphaMultiplier = nextFrame.color.alphaMultiplier - 1;
+ _durationColor.redMultiplier = nextFrame.color.redMultiplier - 1;
+ _durationColor.greenMultiplier = nextFrame.color.greenMultiplier - 1;
+ _durationColor.blueMultiplier = nextFrame.color.blueMultiplier - 1;
+ }
+ else
+ {
+ _tweenColor = false;
+ }
+ }
+
+ if(!_tweenTransform)
+ {
+ if(_animationState.blend)
+ {
+ transform.x = _originTransform.x + _currentFrame.transform.x;
+ transform.y = _originTransform.y + _currentFrame.transform.y;
+ transform.skewX = _originTransform.skewX + _currentFrame.transform.skewX;
+ transform.skewY = _originTransform.skewY + _currentFrame.transform.skewY;
+ transform.scaleX = _originTransform.scaleX + _currentFrame.transform.scaleX;
+ transform.scaleY = _originTransform.scaleY + _currentFrame.transform.scaleY;
+
+ pivot.x = _originPivot.x + _currentFrame.pivot.x;
+ pivot.y = _originPivot.y + _currentFrame.pivot.y;
+ }
+ else
+ {
+ transform.x = _currentFrame.transform.x;
+ transform.y = _currentFrame.transform.y;
+ transform.skewX = _currentFrame.transform.skewX;
+ transform.skewY = _currentFrame.transform.skewY;
+ transform.scaleX = _currentFrame.transform.scaleX;
+ transform.scaleY = _currentFrame.transform.scaleY;
+
+ pivot.x = _currentFrame.pivot.x;
+ pivot.y = _currentFrame.pivot.y;
+ }
+ }
+
+ if(!_tweenColor)
+ {
+ if(_currentFrame.color)
+ {
+ _bone.updateColor(
+ _currentFrame.color.alphaOffset,
+ _currentFrame.color.redOffset,
+ _currentFrame.color.greenOffset,
+ _currentFrame.color.blueOffset,
+ _currentFrame.color.alphaMultiplier,
+ _currentFrame.color.redMultiplier,
+ _currentFrame.color.greenMultiplier,
+ _currentFrame.color.blueMultiplier,
+ true
+ );
+ }
+ else if(_bone._isColorChanged)
+ {
+ _bone.updateColor(0, 0, 0, 0, 1, 1, 1, 1, false);
+ }
+ }
+ _bone.arriveAtFrame(_currentFrame, this, _animationState, false);
+ }
+
+ if(_tweenTransform)
+ {
+ progress = (playedTime - _currentFramePosition) / _currentFrameDuration;
+ if(_tweenEasing)
+ {
+ progress = getEaseValue(progress, _tweenEasing);
+ }
+ var currentTransform:DBTransform = _currentFrame.transform;
+ var currentPivot:Point = _currentFrame.pivot;
+ if(_animationState.blend)
+ {
+ transform.x = _originTransform.x + currentTransform.x + _durationTransform.x * progress;
+ transform.y = _originTransform.y + currentTransform.y + _durationTransform.y * progress;
+ transform.skewX = _originTransform.skewX + currentTransform.skewX + _durationTransform.skewX * progress;
+ transform.skewY = _originTransform.skewY + currentTransform.skewY + _durationTransform.skewY * progress;
+ transform.scaleX = _originTransform.scaleX + currentTransform.scaleX + _durationTransform.scaleX * progress;
+ transform.scaleY = _originTransform.scaleY + currentTransform.scaleY + _durationTransform.scaleY * progress;
+
+ pivot.x = _originPivot.x + currentPivot.x + _durationPivot.x * progress;
+ pivot.y = _originPivot.y + currentPivot.y + _durationPivot.y * progress;
+ }
+ else
+ {
+ transform.x = currentTransform.x + _durationTransform.x * progress;
+ transform.y = currentTransform.y + _durationTransform.y * progress;
+ transform.skewX = currentTransform.skewX + _durationTransform.skewX * progress;
+ transform.skewY = currentTransform.skewY + _durationTransform.skewY * progress;
+ transform.scaleX = currentTransform.scaleX + _durationTransform.scaleX * progress;
+ transform.scaleY = currentTransform.scaleY + _durationTransform.scaleY * progress;
+
+ pivot.x = currentPivot.x + _durationPivot.x * progress;
+ pivot.y = currentPivot.y + _durationPivot.y * progress;
+ }
+ }
+
+ if(_tweenColor)
+ {
+ if(_currentFrame.color)
+ {
+ _bone.updateColor(
+ _currentFrame.color.alphaOffset + _durationColor.alphaOffset * progress,
+ _currentFrame.color.redOffset + _durationColor.redOffset * progress,
+ _currentFrame.color.greenOffset + _durationColor.greenOffset * progress,
+ _currentFrame.color.blueOffset + _durationColor.blueOffset * progress,
+ _currentFrame.color.alphaMultiplier + _durationColor.alphaMultiplier * progress,
+ _currentFrame.color.redMultiplier + _durationColor.redMultiplier * progress,
+ _currentFrame.color.greenMultiplier + _durationColor.greenMultiplier * progress,
+ _currentFrame.color.blueMultiplier + _durationColor.blueMultiplier * progress,
+ true
+ );
+ }
+ else
+ {
+ _bone.updateColor(
+ _durationColor.alphaOffset * progress,
+ _durationColor.redOffset * progress,
+ _durationColor.greenOffset * progress,
+ _durationColor.blueOffset * progress,
+ 1 + _durationColor.alphaMultiplier * progress,
+ 1 + _durationColor.redMultiplier * progress,
+ 1 + _durationColor.greenMultiplier * progress,
+ 1 + _durationColor.blueMultiplier * progress,
+ false
+ );
+ }
+ }
+ }
+
+ private function clear():void
+ {
+ update = updateNothing;
+
+ _bone = null;
+ _animationState = null;
+ _timeline = null;
+ _currentFrame = null;
+ _originTransform = null;
+ _originPivot = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/animation/Tween.as b/src/dragonBones/animation/Tween.as
deleted file mode 100644
index 2841ce3..0000000
--- a/src/dragonBones/animation/Tween.as
+++ /dev/null
@@ -1,406 +0,0 @@
-package dragonBones.animation
-{
- import dragonBones.Armature;
- import dragonBones.Bone;
- import dragonBones.events.FrameEvent;
- import dragonBones.events.SoundEvent;
- import dragonBones.events.SoundEventManager;
- import dragonBones.objects.BoneTransform;
- import dragonBones.objects.FrameData;
- import dragonBones.objects.MovementBoneData;
- import dragonBones.utils.TransformUtils;
- import dragonBones.utils.dragonBones_internal;
-
- import flash.geom.ColorTransform;
-
- use namespace dragonBones_internal;
-
- /** @private */
- final public class Tween
- {
- private static const HALF_PI:Number = Math.PI * 0.5;
-
- private static var _soundManager:SoundEventManager = SoundEventManager.getInstance();
-
- //NaN: no tweens; -1: ease out; 0: linear; 1: ease in; 2: ease in&out
- public static function getEaseValue(value:Number, easing:Number):Number
- {
- var valueEase:Number = 0;
- if(isNaN(easing))
- {
- return valueEase;
- }
- else if (easing > 1)
- {
- valueEase = 0.5 * (1 - Math.cos(value * Math.PI )) - value;
- easing -= 1;
- }
- else if (easing > 0)
- {
- valueEase = Math.sin(value * HALF_PI) - value;
- }
- else if (easing < 0)
- {
- valueEase = 1 - Math.cos(value * HALF_PI) - value;
- easing *= -1;
- }
- return valueEase * easing + value;
- }
-
- private var _bone:Bone;
-
- private var _movementBoneData:MovementBoneData;
-
- private var _node:BoneTransform;
- private var _colorTransform:ColorTransform;
-
- private var _currentNode:BoneTransform;
- private var _currentColorTransform:ColorTransform;
-
- private var _offSetNode:BoneTransform;
- private var _offSetColorTransform:ColorTransform;
-
- private var _currentFrameData:FrameData;
- private var _tweenEasing:Number;
- private var _frameTweenEasing:Number;
-
- private var _isPause:Boolean;
- private var _rawDuration:Number;
- private var _nextFrameDataTimeEdge:Number;
- private var _frameDuration:Number;
- private var _nextFrameDataID:int;
- private var _loop:int;
-
- dragonBones_internal var _differentColorTransform:Boolean;
-
- /**
- * Creates a new Tween
- * @param bone
- */
- public function Tween(bone:Bone)
- {
- super();
-
- _bone = bone;
- _node = _bone._tweenNode;
- _colorTransform = _bone._tweenColorTransform;
-
- _currentNode = new BoneTransform();
- _currentColorTransform = new ColorTransform();
-
- _offSetNode = new BoneTransform();
- _offSetColorTransform = new ColorTransform();
- }
-
- /** @private */
- internal function gotoAndPlay(movementBoneData:MovementBoneData, rawDuration:Number, loop:Boolean, tweenEasing:Number):void
- {
- if(!movementBoneData)
- {
- return;
- }
- _movementBoneData = movementBoneData;
- var totalFrames:uint = _movementBoneData._frameList.length;
- if(totalFrames == 0)
- {
- _bone.changeDisplay(-1);
- stop();
- return;
- }
-
- _node.skewX %= Math.PI * 2;
- _node.skewY %= Math.PI * 2;
- _isPause = false;
- _currentFrameData = null;
- _loop = loop?0:-1;
-
- _nextFrameDataTimeEdge = 0;
- _nextFrameDataID = 0;
- _rawDuration = rawDuration;
- _tweenEasing = tweenEasing;
-
- var nextFrameData:FrameData;
- if (totalFrames == 1)
- {
- _frameTweenEasing = 1;
- _rawDuration = 0;
- nextFrameData = _movementBoneData._frameList[0];
- setOffset(_bone._isOnStage?_node:nextFrameData.node, _colorTransform, nextFrameData.node, nextFrameData.colorTransform);
- }
- else if (loop && _movementBoneData.delay != 0)
- {
- getLoopListNode();
- setOffset(_bone._isOnStage?_node:_offSetNode, _colorTransform, _offSetNode, _offSetColorTransform);
- //nextFrameData = _movementBoneData._frameList[0];
- }
- else
- {
- _frameTweenEasing = 1;
- nextFrameData = _movementBoneData._frameList[0];
- setOffset(_bone._isOnStage?_node:nextFrameData.node, _colorTransform, nextFrameData.node, nextFrameData.colorTransform);
- }
-
- if(nextFrameData)
- {
- updateBoneDisplayIndex(nextFrameData);
- }
- }
-
- private function getLoopListNode():void
- {
- var playedTime:Number = _rawDuration * _movementBoneData.delay;
- var length:int = _movementBoneData._frameList.length;
- var nextFrameDataID:int = 0;
- var nextFrameDataTimeEdge:Number = 0;
- do
- {
- var currentFrameDataID:int = nextFrameDataID;
- var frameDuration:Number = _movementBoneData._frameList[currentFrameDataID].duration;
- nextFrameDataTimeEdge += frameDuration;
- if (++ nextFrameDataID >= length)
- {
- nextFrameDataID = 0;
- }
- }
- while (playedTime >= nextFrameDataTimeEdge);
-
- var currentFrameData:FrameData = _movementBoneData._frameList[currentFrameDataID];
- var nextFrameData:FrameData = _movementBoneData._frameList[nextFrameDataID];
-
-
- if(nextFrameData.displayIndex >= 0 && _bone.armature.animation.tweenEnabled)
- {
- _frameTweenEasing = currentFrameData.tweenEasing;
- }
- else
- {
- _frameTweenEasing = NaN;
- }
-
- setOffset(currentFrameData.node, currentFrameData.colorTransform, nextFrameData.node, nextFrameData.colorTransform);
-
- var progress:Number = 1 - (nextFrameDataTimeEdge - playedTime) / frameDuration;
-
- var tweenEasing:Number = isNaN(_tweenEasing)?currentFrameData.tweenEasing:_tweenEasing;
- if (tweenEasing)
- {
- progress = getEaseValue(progress, tweenEasing);
- }
-
- TransformUtils.setOffSetNode(currentFrameData.node, nextFrameData.node, _offSetNode);
- TransformUtils.setTweenNode(_currentNode, _offSetNode, _offSetNode, progress);
-
- TransformUtils.setOffSetColorTransform(currentFrameData.colorTransform, nextFrameData.colorTransform, _offSetColorTransform);
- TransformUtils.setTweenColorTransform(_currentColorTransform, _offSetColorTransform, _offSetColorTransform, progress);
-
- }
-
- /** @private */
- internal function stop():void
- {
- _isPause = true;
- }
-
- /** @private */
- internal function advanceTime(progress:Number, playType:int):void
- {
- if(_isPause || !_movementBoneData)
- {
- return;
- }
-
- if(_rawDuration == 0)
- {
- playType = Animation.SINGLE;
- if(progress == 0)
- {
- progress = 1;
- }
- }
-
- if(playType == Animation.LOOP)
- {
- progress /= _movementBoneData.scale;
- progress += _movementBoneData.delay;
- var loop:int = progress;
- if(_loop != loop)
- {
- _nextFrameDataTimeEdge = 0;
- _nextFrameDataID = 0;
- _loop = loop;
- }
- progress -= loop;
- progress = updateFrameData(progress);
- }
- else if (playType == Animation.LIST)
- {
- progress = updateFrameData(progress, true);
- }
- else if (playType == Animation.SINGLE && progress == 1)
- {
- _currentFrameData = _movementBoneData._frameList[0];
- _isPause = true;
- }
- else
- {
- progress = Math.sin(progress * HALF_PI);
- }
-
-
- if (!isNaN(_frameTweenEasing) || _currentFrameData)
- {
- TransformUtils.setTweenNode(_currentNode, _offSetNode, _node, progress);
-
- if(_differentColorTransform)
- {
- TransformUtils.setTweenColorTransform(_currentColorTransform, _offSetColorTransform, _colorTransform, progress);
- }
- }
-
- if(_currentFrameData)
- {
- arriveFrameData(_currentFrameData);
- _currentFrameData = null;
- }
- }
-
- private function setOffset(currentNode:BoneTransform, currentColorTransform:ColorTransform, nextNode:BoneTransform, nextColorTransform:ColorTransform, tweenRotate:int = 0):void
- {
- _currentNode.copy(currentNode);
- TransformUtils.setOffSetNode(_currentNode, nextNode, _offSetNode, tweenRotate);
-
- _currentColorTransform.alphaOffset = currentColorTransform.alphaOffset;
- _currentColorTransform.redOffset = currentColorTransform.redOffset;
- _currentColorTransform.greenOffset = currentColorTransform.greenOffset;
- _currentColorTransform.blueOffset = currentColorTransform.blueOffset;
- _currentColorTransform.alphaMultiplier = currentColorTransform.alphaMultiplier;
- _currentColorTransform.redMultiplier = currentColorTransform.redMultiplier;
- _currentColorTransform.greenMultiplier = currentColorTransform.greenMultiplier;
- _currentColorTransform.blueMultiplier = currentColorTransform.blueMultiplier;
-
- TransformUtils.setOffSetColorTransform(_currentColorTransform, nextColorTransform, _offSetColorTransform);
-
- if(
- _offSetColorTransform.alphaOffset != 0 ||
- _offSetColorTransform.redOffset != 0 ||
- _offSetColorTransform.greenOffset != 0 ||
- _offSetColorTransform.blueOffset != 0 ||
- _offSetColorTransform.alphaMultiplier != 0 ||
- _offSetColorTransform.redMultiplier != 0 ||
- _offSetColorTransform.greenMultiplier != 0 ||
- _offSetColorTransform.blueMultiplier != 0
- )
- {
- _differentColorTransform = true;
- }
- else
- {
- _differentColorTransform = false;
- }
- }
-
- private function updateBoneDisplayIndex(frameData:FrameData):void
- {
- var displayIndex:int = frameData.displayIndex;
- if(displayIndex >= 0)
- {
- if(_node.z != frameData.node.z)
- {
- _node.z = frameData.node.z;
- if(_bone.armature)
- {
- _bone.armature._bonesIndexChanged = true;
- }
- }
- }
- _bone.changeDisplay(displayIndex);
- }
-
- private function arriveFrameData(frameData:FrameData):void
- {
- updateBoneDisplayIndex(frameData);
- _bone._visible = frameData.visible;
-
- if(frameData.event && _bone._armature.hasEventListener(FrameEvent.BONE_FRAME_EVENT))
- {
- var frameEvent:FrameEvent = new FrameEvent(FrameEvent.BONE_FRAME_EVENT, false, _bone);
- frameEvent.movementID = _bone._armature.animation.movementID;
- frameEvent.frameLabel = frameData.event;
- _bone._armature.dispatchEvent(frameEvent);
- }
- if(frameData.sound && _soundManager.hasEventListener(SoundEvent.SOUND))
- {
- var soundEvent:SoundEvent = new SoundEvent(SoundEvent.SOUND);
- soundEvent.movementID = _bone._armature.animation.movementID;
- soundEvent.sound = frameData.sound;
- soundEvent._armature = _bone._armature;
- soundEvent._bone = _bone;
- _soundManager.dispatchEvent(soundEvent);
- }
- if(frameData.movement)
- {
- var childArmature:Armature = _bone.childArmature;
- if(childArmature)
- {
- childArmature.animation.gotoAndPlay(frameData.movement);
- }
- }
- }
-
- private function updateFrameData(progress:Number, isList:Boolean= false):Number
- {
- var playedTime:Number = _rawDuration * progress;
- if (playedTime >= _nextFrameDataTimeEdge)
- {
- var length:int = _movementBoneData._frameList.length;
- do
- {
- var currentFrameDataID:int = _nextFrameDataID;
- _frameDuration = _movementBoneData._frameList[currentFrameDataID].duration;
- _nextFrameDataTimeEdge += _frameDuration;
- if (++ _nextFrameDataID >= length)
- {
- _nextFrameDataID = 0;
- }
- }
- while (playedTime >= _nextFrameDataTimeEdge);
-
- var currentFrameData:FrameData = _movementBoneData._frameList[currentFrameDataID];
- var nextFrameData:FrameData = _movementBoneData._frameList[_nextFrameDataID];
-
- if(nextFrameData.displayIndex >= 0 && _bone.armature.animation.tweenEnabled)
- {
- _frameTweenEasing = currentFrameData.tweenEasing;
- }
- else
- {
- _frameTweenEasing = NaN;
- }
-
- setOffset(currentFrameData.node, currentFrameData.colorTransform, nextFrameData.node, nextFrameData.colorTransform, nextFrameData.tweenRotate);
-
- _currentFrameData = currentFrameData;
-
- if(isList && _nextFrameDataID == 0)
- {
- _isPause = true;
- return 0;
- }
- }
-
- progress = 1 - (_nextFrameDataTimeEdge - playedTime) / _frameDuration;
-
- var tweenEasing:Number = isNaN(_tweenEasing)?_frameTweenEasing:_tweenEasing;
- if (isNaN(tweenEasing))
- {
- return 0;
- }
- else if(tweenEasing)
- {
- return getEaseValue(progress, tweenEasing);
- }
-
- return progress;
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/animation/WorldClock.as b/src/dragonBones/animation/WorldClock.as
index 01f08e0..a65f006 100644
--- a/src/dragonBones/animation/WorldClock.as
+++ b/src/dragonBones/animation/WorldClock.as
@@ -6,7 +6,8 @@
* @langversion 3.0
* @version 2.0
*/
- import dragonBones.Armature;
+ import dragonBones.Armature;
+
import flash.utils.getTimer;
/**
* A WorldClock instance lets you conveniently update many number of Armature instances at once. You can add/remove Armature instance and set a global timescale that will apply to all registered Armature instance animations.
@@ -48,7 +49,7 @@
*
* private function updateAnimation(e:Event):void
* {
- * WorldClock.clock.advanceTime(1 / stage.frameRate);
+ * WorldClock.clock.advanceTime(stage.frameRate / 1000);
* }
* }
* }
@@ -150,7 +151,7 @@
*/
public function advanceTime(passedTime:Number):void
{
- if (passedTime < 0)
+ if(passedTime < 0)
{
var currentTime:Number = getTimer() * 0.001;
passedTime = currentTime - _time;
@@ -160,33 +161,33 @@
passedTime *= _timeScale;
var length:int = animatableList.length;
- if (length == 0)
+ if(length == 0)
{
return;
}
var currentIndex:int = 0;
- for (var i:int = 0; i < length; i++)
+ for(var i:int = 0;i < length;i ++)
{
var animatable:IAnimatable = animatableList[i];
- if (animatable)
+ if(animatable)
{
- if (currentIndex != i)
+ if(currentIndex != i)
{
animatableList[currentIndex] = animatable;
animatableList[i] = null;
}
animatable.advanceTime(passedTime);
- currentIndex++;
+ currentIndex ++;
}
}
if (currentIndex != i)
{
length = animatableList.length;
- while (i < length)
+ while(i < length)
{
- animatableList[currentIndex++] = animatableList[i++];
+ animatableList[currentIndex ++] = animatableList[i ++];
}
animatableList.length = currentIndex;
}
diff --git a/src/dragonBones/core/DBObject.as b/src/dragonBones/core/DBObject.as
new file mode 100644
index 0000000..222829e
--- /dev/null
+++ b/src/dragonBones/core/DBObject.as
@@ -0,0 +1,207 @@
+package dragonBones.core
+{
+ import dragonBones.Armature;
+ import dragonBones.Bone;
+ import dragonBones.animation.AnimationState;
+ import dragonBones.animation.TimelineState;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.Frame;
+
+ import flash.events.EventDispatcher;
+ import flash.geom.Matrix;
+
+ use namespace dragonBones_internal;
+
+ public class DBObject extends EventDispatcher
+ {
+ /**
+ * The name of this DBObject instance's Armature instance.
+ */
+ public var name:String;
+
+ /**
+ * An object that can contain any user extra data.
+ */
+ public var userData:Object;
+
+ /**
+ *
+ */
+ public var fixedRotation:Boolean;
+
+ /** @private */
+ dragonBones_internal var _globalTransformMatrix:Matrix;
+ /** @private */
+ protected var _scaleType:int;
+ /** @private */
+ dragonBones_internal var _isColorChanged:Boolean;
+
+ /** @private */
+ protected var _global:DBTransform;
+ /**
+ * This DBObject instance global transform instance.
+ * @see dragonBones.objects.DBTransform
+ */
+ public function get global():DBTransform
+ {
+ return _global;
+ }
+
+ /** @private */
+ protected var _origin:DBTransform;
+ /**
+ * This DBObject instance origin transform instance.
+ * @see dragonBones.objects.DBTransform
+ */
+ public function get origin():DBTransform
+ {
+ return _origin;
+ }
+
+ /** @private */
+ protected var _offset:DBTransform;
+ /**
+ * This DBObject instance offset transform instance.
+ * @see dragonBones.objects.DBTransform
+ */
+ public function get offset():DBTransform
+ {
+ return _offset;
+ }
+ public function get node():DBTransform
+ {
+ return _offset;
+ }
+
+ /** @private */
+ dragonBones_internal var _tween:DBTransform;
+
+ /** @private */
+ protected var _visible:Boolean;
+ public function get visible():Boolean
+ {
+ return _visible;
+ }
+ public function set visible(value:Boolean):void
+ {
+ _visible = value;
+ }
+
+ /** @private */
+ protected var _parent:Bone;
+
+ /**
+ * Indicates the Bone instance that directly contains this DBObject instance if any.
+ */
+ public function get parent():Bone
+ {
+ return _parent;
+ }
+ /** @private */
+ dragonBones_internal function setParent(value:Bone):void
+ {
+ _parent = value;
+ }
+
+ /** @private */
+ protected var _armature:Armature;
+ /**
+ * The armature this DBObject instance belongs to.
+ */
+ public function get armature():Armature
+ {
+ return _armature;
+ }
+ /** @private */
+ dragonBones_internal function setArmature(value:Armature):void
+ {
+ if(_armature)
+ {
+ _armature.removeDBObject(this);
+ }
+ _armature = value;
+ if(_armature)
+ {
+ _armature.addDBObject(this);
+ }
+ }
+
+ public function DBObject()
+ {
+ super(this);
+
+ _global = new DBTransform();
+ _origin = new DBTransform();
+ _offset = new DBTransform();
+ _tween = new DBTransform();
+ _tween.scaleX = _tween.scaleY = 0;
+
+ _globalTransformMatrix = new Matrix();
+
+ _visible = true;
+ }
+
+ /**
+ * Cleans up any resources used by this DBObject instance.
+ */
+ public function dispose():void
+ {
+ userData = null;
+ _parent = null;
+ _armature = null;
+ _global = null;
+ _origin = null;
+ _offset = null;
+ _tween = null;
+ _globalTransformMatrix = null;
+ }
+
+ /** @private */
+ dragonBones_internal function update():void
+ {
+ _global.scaleX = (_origin.scaleX + _tween.scaleX) * _offset.scaleX;
+ _global.scaleY = (_origin.scaleY + _tween.scaleY) * _offset.scaleY;
+
+ if(_parent)
+ {
+ var x:Number = _origin.x + _offset.x + _tween.x;
+ var y:Number = _origin.y + _offset.y + _tween.y;
+ var parentMatrix:Matrix = _parent._globalTransformMatrix;
+
+ _globalTransformMatrix.tx = _global.x = parentMatrix.a * x + parentMatrix.c * y + parentMatrix.tx;
+ _globalTransformMatrix.ty = _global.y = parentMatrix.d * y + parentMatrix.b * x + parentMatrix.ty;
+
+ if(fixedRotation)
+ {
+ _global.skewX = _origin.skewX + _offset.skewX + _tween.skewX;
+ _global.skewY = _origin.skewY + _offset.skewY + _tween.skewY;
+ }
+ else
+ {
+ _global.skewX = _origin.skewX + _offset.skewX + _tween.skewX + _parent._global.skewX;
+ _global.skewY = _origin.skewY + _offset.skewY + _tween.skewY + _parent._global.skewY;
+ }
+
+ if(_parent.scaleMode >= _scaleType)
+ {
+ _global.scaleX *= _parent._global.scaleX;
+ _global.scaleY *= _parent._global.scaleY;
+ }
+ }
+ else
+ {
+ _globalTransformMatrix.tx = _global.x = _origin.x + _offset.x + _tween.x;
+ _globalTransformMatrix.ty = _global.y = _origin.y + _offset.y + _tween.y;
+
+ _global.skewX = _origin.skewX + _offset.skewX + _tween.skewX;
+ _global.skewY = _origin.skewY + _offset.skewY + _tween.skewY;
+ }
+
+ _globalTransformMatrix.a = _global.scaleX * Math.cos(_global.skewY);
+ _globalTransformMatrix.b = _global.scaleX * Math.sin(_global.skewY);
+ _globalTransformMatrix.c = -_global.scaleY * Math.sin(_global.skewX);
+ _globalTransformMatrix.d = _global.scaleY * Math.cos(_global.skewX);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/core/DragonBones.as b/src/dragonBones/core/DragonBones.as
new file mode 100644
index 0000000..16db641
--- /dev/null
+++ b/src/dragonBones/core/DragonBones.as
@@ -0,0 +1,13 @@
+package dragonBones.core
+{
+ public final class DragonBones
+ {
+ public static const DATA_VERSION:String = "2.3";
+ public static const VERSION:String = "2.3";
+ public static const VERSION_NUMBER:int = 2305;
+
+ public function DragonBones()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/utils/dragonBones_internal.as b/src/dragonBones/core/dragonBones_internal.as
similarity index 70%
rename from src/dragonBones/utils/dragonBones_internal.as
rename to src/dragonBones/core/dragonBones_internal.as
index e84002c..44d9c34 100644
--- a/src/dragonBones/utils/dragonBones_internal.as
+++ b/src/dragonBones/core/dragonBones_internal.as
@@ -1,4 +1,4 @@
-package dragonBones.utils
+package dragonBones.core
{
/** @private */
diff --git a/src/dragonBones/display/IDisplayBridge.as b/src/dragonBones/display/IDisplayBridge.as
index 88c7e04..952d8b5 100644
--- a/src/dragonBones/display/IDisplayBridge.as
+++ b/src/dragonBones/display/IDisplayBridge.as
@@ -7,35 +7,67 @@ package dragonBones.display
* @version 2.0
*/
- import dragonBones.objects.BoneTransform;
+ import dragonBones.objects.DBTransform;
+
import flash.geom.ColorTransform;
import flash.geom.Matrix;
/**
- * Provides an interface for display classes that can be used in this skeleton animation system.
+ * Provides an interface for display classes that can be used in this DragonBones animation system.
*
*/
public interface IDisplayBridge
{
+ function get visible():Boolean;
+ function set visible(value:Boolean):void;
+
/**
* Indicates the original display object relative to specific display engine.
*/
function get display():Object;
function set display(value:Object):void;
+
+ /**
+ * Cleans up resources used by this IDisplayBridge instance.
+ */
+ function dispose():void;
+
/**
* Updates the transform of the display object
* @param matrix
- * @param node
- * @param colorTransform
- * @param visible
+ * @param transform
+ */
+ function updateTransform(matrix:Matrix, transform:DBTransform):void;
+
+ /**
+ * Updates the color of the display object
+ * @param a
+ * @param r
+ * @param g
+ * @param b
+ * @param aM
+ * @param rM
+ * @param gM
+ * @param bM
*/
- function update(matrix:Matrix, node:BoneTransform, colorTransform:ColorTransform, visible:Boolean):void;
+ function updateColor(
+ aOffset:Number,
+ rOffset:Number,
+ gOffset:Number,
+ bOffset:Number,
+ aMultiplier:Number,
+ rMultiplier:Number,
+ gMultiplier:Number,
+ bMultiplier:Number
+ ):void;
+
/**
* Adds the original display object to another display object.
* @param container
* @param index
*/
function addDisplay(container:Object, index:int = -1):void;
+
/**
* remove the original display object from its parent.
*/
diff --git a/src/dragonBones/display/NativeDisplayBridge.as b/src/dragonBones/display/NativeDisplayBridge.as
index bf4de3c..2e7542f 100644
--- a/src/dragonBones/display/NativeDisplayBridge.as
+++ b/src/dragonBones/display/NativeDisplayBridge.as
@@ -8,7 +8,8 @@ package dragonBones.display
*/
- import dragonBones.objects.BoneTransform;
+ import dragonBones.objects.DBTransform;
+
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Shape;
@@ -21,10 +22,8 @@ package dragonBones.display
*/
public class NativeDisplayBridge implements IDisplayBridge
{
- /**
- * @private
- */
- protected var _display:DisplayObject;
+ private var _display:DisplayObject;
+ private var _colorTransform:ColorTransform;
/**
* @inheritDoc
@@ -33,9 +32,6 @@ package dragonBones.display
{
return _display;
}
- /**
- * @private
- */
public function set display(value:Object):void
{
if (_display == value)
@@ -55,6 +51,21 @@ package dragonBones.display
addDisplay(parent, index);
}
+ /**
+ * @inheritDoc
+ */
+ public function get visible():Boolean
+ {
+ return _display?_display.visible:false;
+ }
+ public function set visible(value:Boolean):void
+ {
+ if(_display)
+ {
+ _display.visible = value;
+ }
+ }
+
/**
* Creates a new NativeDisplayBridge instance.
*/
@@ -65,19 +76,49 @@ package dragonBones.display
/**
* @inheritDoc
*/
- public function update(matrix:Matrix, node:BoneTransform, colorTransform:ColorTransform, visible:Boolean):void
+ public function dispose():void
+ {
+ _display = null;
+ _colorTransform = null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function updateTransform(matrix:Matrix, transform:DBTransform):void
{
- var pivotX:Number = node.pivotX;
- var pivotY:Number = node.pivotY;
- matrix.tx -= matrix.a * pivotX + matrix.c * pivotY;
- matrix.ty -= matrix.b * pivotX + matrix.d * pivotY;
-
_display.transform.matrix = matrix;
- if (colorTransform)
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function updateColor(
+ aOffset:Number,
+ rOffset:Number,
+ gOffset:Number,
+ bOffset:Number,
+ aMultiplier:Number,
+ rMultiplier:Number,
+ gMultiplier:Number,
+ bMultiplier:Number
+ ):void
+ {
+ if(!_colorTransform)
{
- _display.transform.colorTransform = colorTransform;
+ _colorTransform = _display.transform.colorTransform;
}
- _display.visible = visible;
+ _colorTransform.alphaOffset = aOffset;
+ _colorTransform.redOffset = rOffset;
+ _colorTransform.greenOffset = gOffset;
+ _colorTransform.blueOffset = bOffset;
+
+ _colorTransform.alphaMultiplier = aMultiplier;
+ _colorTransform.redMultiplier = rMultiplier;
+ _colorTransform.greenMultiplier = gMultiplier;
+ _colorTransform.blueMultiplier = bMultiplier;
+
+ _display.transform.colorTransform = _colorTransform;
}
/**
diff --git a/src/dragonBones/display/StarlingDisplayBridge.as b/src/dragonBones/display/StarlingDisplayBridge.as
index fbd66b9..28cdab7 100644
--- a/src/dragonBones/display/StarlingDisplayBridge.as
+++ b/src/dragonBones/display/StarlingDisplayBridge.as
@@ -8,14 +8,16 @@
*/
- import dragonBones.objects.BoneTransform;
+ import dragonBones.objects.DBTransform;
+
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import starling.display.DisplayObject;
import starling.display.DisplayObjectContainer;
- import starling.display.Quad;
import starling.display.Image;
+ import starling.display.Quad;
+ import starling.textures.Texture;
/**
* The StarlingDisplayBridge class is an implementation of the IDisplayBridge interface for starling.display.DisplayObject.
@@ -23,10 +25,12 @@
*/
public class StarlingDisplayBridge implements IDisplayBridge
{
- /**
- * @private
- */
- protected var _display:Object;
+ private var _imageBackup:Image;
+ private var _textureBackup:Texture;
+ private var _pivotXBackup:Number;
+ private var _pivotYBackup:Number;
+
+ private var _display:Object;
/**
* @inheritDoc
*/
@@ -34,34 +38,36 @@
{
return _display;
}
- /**
- * @private
- */
public function set display(value:Object):void
{
- if (_display == value)
- {
- return;
- }
-
- //Thanks Jian
- //bug replace image.texture will lost displayList[0].texture
- /*if (_display is Image && value is Image)
+ if (_display is Image && value is Image)
{
var from:Image = _display as Image;
var to:Image = value as Image;
if (from.texture == to.texture)
{
+ if(from == _imageBackup)
+ {
+ from.texture = _textureBackup;
+ from.pivotX = _pivotXBackup;
+ from.pivotY = _pivotYBackup;
+ from.readjustSize();
+ }
return;
}
-
+
from.texture = to.texture;
//update pivot
from.pivotX = to.pivotX;
from.pivotY = to.pivotY;
from.readjustSize();
return;
- }*/
+ }
+
+ if (_display == value)
+ {
+ return;
+ }
if (_display)
{
@@ -72,10 +78,29 @@
}
removeDisplay();
}
+ else if(value is Image && !_imageBackup)
+ {
+ _imageBackup = value as Image;
+ _textureBackup = _imageBackup.texture;
+ _pivotXBackup = _imageBackup.pivotX;
+ _pivotYBackup = _imageBackup.pivotY;
+ }
_display = value;
addDisplay(parent, index);
}
+ public function get visible():Boolean
+ {
+ return _display?_display.visible:false;
+ }
+ public function set visible(value:Boolean):void
+ {
+ if(_display)
+ {
+ _display.visible = value;
+ }
+ }
+
/**
* Creates a new StarlingDisplayBridge instance.
*/
@@ -86,29 +111,51 @@
/**
* @inheritDoc
*/
- public function update(matrix:Matrix, node:BoneTransform, colorTransform:ColorTransform, visible:Boolean):void
+ public function dispose():void
{
- var pivotX:Number = node.pivotX + _display.pivotX;
- var pivotY:Number = node.pivotY + _display.pivotY;
+ _display = null;
+ _imageBackup = null;
+ _textureBackup = null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function updateTransform(matrix:Matrix, transform:DBTransform):void
+ {
+ var pivotX:Number = _display.pivotX;
+ var pivotY:Number = _display.pivotY;
matrix.tx -= matrix.a * pivotX + matrix.c * pivotY;
matrix.ty -= matrix.b * pivotX + matrix.d * pivotY;
-
//if(updateStarlingDisplay)
//{
- //_display.transformationMatrix = matrix;
+ // _display.transformationMatrix = matrix;
//}
//else
//{
- _display.transformationMatrix.copyFrom(matrix);
+ _display.transformationMatrix.copyFrom(matrix);
//}
-
- if (colorTransform && _display is Quad)
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function updateColor(
+ aOffset:Number,
+ rOffset:Number,
+ gOffset:Number,
+ bOffset:Number,
+ aMultiplier:Number,
+ rMultiplier:Number,
+ gMultiplier:Number,
+ bMultiplier:Number
+ ):void
+ {
+ if (_display is Quad)
{
- (_display as Quad).alpha = colorTransform.alphaMultiplier;
- (_display as Quad).color = (uint(colorTransform.redMultiplier * 0xff) << 16) + (uint(colorTransform.greenMultiplier * 0xff) << 8) + uint(colorTransform.blueMultiplier * 0xff);
+ (_display as Quad).alpha = aMultiplier;
+ (_display as Quad).color = (uint(rMultiplier * 0xff) << 16) + (uint(gMultiplier * 0xff) << 8) + uint(bMultiplier * 0xff);
}
- //
- _display.visible = visible;
}
/**
@@ -140,4 +187,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/dragonBones/errors/UnknownDataError.as b/src/dragonBones/errors/UnknownDataError.as
deleted file mode 100644
index 7333ff6..0000000
--- a/src/dragonBones/errors/UnknownDataError.as
+++ /dev/null
@@ -1,20 +0,0 @@
-package dragonBones.errors
-{
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0, Flash 10
- * @langversion 3.0
- * @version 2.0
- */
-
- /**
- * Thrown when dragonBones encounters an unknow error.
- */
- public final class UnknownDataError extends Error
- {
- public function UnknownDataError(message:* = "", id:* = 0)
- {
- super(message, id);
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/events/AnimationEvent.as b/src/dragonBones/events/AnimationEvent.as
index 7d8a1d0..110d969 100644
--- a/src/dragonBones/events/AnimationEvent.as
+++ b/src/dragonBones/events/AnimationEvent.as
@@ -7,6 +7,7 @@
* @version 2.0
*/
import dragonBones.Armature;
+ import dragonBones.animation.AnimationState;
import flash.events.Event;
@@ -19,9 +20,22 @@
public class AnimationEvent extends Event
{
/**
- * Dispatched when the movement of animation is changed.
+ * Dispatched when the playback of an animation fade in.
*/
- public static const MOVEMENT_CHANGE:String = "movementChange";
+ public static function get MOVEMENT_CHANGE():String
+ {
+ return FADE_IN;
+ }
+
+ /**
+ * Dispatched when the playback of an animation fade in.
+ */
+ public static const FADE_IN:String = "fadeIn";
+
+ /**
+ * Dispatched when the playback of an animation fade out.
+ */
+ public static const FADE_OUT:String = "fadeOut";
/**
* Dispatched when the playback of an animation starts.
@@ -29,22 +43,29 @@
public static const START:String = "start";
/**
- * Dispatched when the playback of a movement stops.
+ * Dispatched when the playback of a animation stops.
*/
public static const COMPLETE:String = "complete";
/**
- * Dispatched when the playback of a movement completes a loop.
+ * Dispatched when the playback of a animation completes a loop.
*/
public static const LOOP_COMPLETE:String = "loopComplete";
+
+ /**
+ * Dispatched when the playback of an animation fade in complete.
+ */
+ public static const FADE_IN_COMPLETE:String = "fadeInComplete";
+
/**
- * The preceding MovementData id.
+ * Dispatched when the playback of an animation fade out complete.
*/
- public var exMovementID:String;
+ public static const FADE_OUT_COMPLETE:String = "fadeOutComplete";
+
/**
- * The current MovementData id.
+ * The animationState instance.
*/
- public var movementID:String;
+ public var animationState:AnimationState;
/**
* The armature that is the taget of this event.
@@ -54,6 +75,11 @@
return target as Armature;
}
+ public function get movementID():String
+ {
+ return animationState.name;
+ }
+
/**
* Creates a new AnimationEvent instance.
* @param type
@@ -71,8 +97,7 @@
override public function clone():Event
{
var event:AnimationEvent = new AnimationEvent(type, cancelable);
- event.exMovementID = exMovementID;
- event.movementID = movementID;
+ event.animationState = animationState;
return event;
}
}
diff --git a/src/dragonBones/events/ArmatureEvent.as b/src/dragonBones/events/ArmatureEvent.as
index aab0024..7578fe5 100644
--- a/src/dragonBones/events/ArmatureEvent.as
+++ b/src/dragonBones/events/ArmatureEvent.as
@@ -7,7 +7,7 @@ package dragonBones.events
* @version 2.0
*/
import flash.events.Event;
-/**
+ /**
* The ArmatureEvent provides and defines all events dispatched directly by an Armature instance.
*
*
@@ -16,15 +16,16 @@ package dragonBones.events
public class ArmatureEvent extends Event
{
- /**
- * Dispatched after a successful z order update.
- */
+ /**
+ * Dispatched after a successful z order update.
+ */
public static const Z_ORDER_UPDATED:String = "zOrderUpdated";
public function ArmatureEvent(type:String)
{
super(type, false, false);
}
+
/**
* @private
* @return
diff --git a/src/dragonBones/events/FrameEvent.as b/src/dragonBones/events/FrameEvent.as
index 78a7706..d2bec61 100644
--- a/src/dragonBones/events/FrameEvent.as
+++ b/src/dragonBones/events/FrameEvent.as
@@ -8,6 +8,8 @@ package dragonBones.events
*/
import dragonBones.Armature;
import dragonBones.Bone;
+ import dragonBones.animation.AnimationState;
+ import dragonBones.core.DBObject;
import flash.events.Event;
@@ -19,23 +21,28 @@ package dragonBones.events
*/
public class FrameEvent extends Event
{
+ public static function get MOVEMENT_FRAME_EVENT():String
+ {
+ return ANIMATION_FRAME_EVENT;
+ }
+
/**
* Dispatched when the animation of the armatrue enter a frame.
*/
- public static const MOVEMENT_FRAME_EVENT:String = "movementFrameEvent";
- /**
- * Dispatched when a bone of the armature enter a frame.
- */
- public static const BONE_FRAME_EVENT:String = "boneFrameEvent";
+ public static const ANIMATION_FRAME_EVENT:String = "animationFrameEvent";
+
/**
- * The id of the MovementData instance.
+ *
*/
- public var movementID:String;
+ public static const BONE_FRAME_EVENT:String ="boneFrameEvent";
+
/**
* The entered frame label.
*/
public var frameLabel:String;
+ public var bone:Bone;
+
/**
* The armature that is the target of this event.
*/
@@ -44,26 +51,19 @@ package dragonBones.events
return target as Armature;
}
- /** @private */
- private var _bone:Bone;
-
/**
- * The bone that is the target of this event.
+ * The animationState instance.
*/
- public function get bone():Bone
- {
- return _bone;
- }
+ public var animationState:AnimationState;
/**
* Creates a new FrameEvent instance.
* @param type
* @param cancelable
*/
- public function FrameEvent(type:String, cancelable:Boolean = false, bone:Bone = null)
+ public function FrameEvent(type:String, cancelable:Boolean = false)
{
super(type, false, cancelable);
- _bone = bone;
}
/**
@@ -74,9 +74,9 @@ package dragonBones.events
override public function clone():Event
{
var event:FrameEvent = new FrameEvent(type, cancelable);
- event.movementID = movementID;
+ event.animationState = animationState;
+ event.bone = bone;
event.frameLabel = frameLabel;
- event._bone = _bone;
return event;
}
}
diff --git a/src/dragonBones/events/SoundEvent.as b/src/dragonBones/events/SoundEvent.as
index 518e719..9a6cba8 100644
--- a/src/dragonBones/events/SoundEvent.as
+++ b/src/dragonBones/events/SoundEvent.as
@@ -7,12 +7,10 @@ package dragonBones.events
* @version 2.0
*/
import dragonBones.Armature;
- import dragonBones.Bone;
- import dragonBones.utils.dragonBones_internal;
+ import dragonBones.animation.AnimationState;
import flash.events.Event;
-
- use namespace dragonBones_internal;
+
/**
* The SoundEvent provides and defines all sound related events dispatched during an animation.
*
@@ -26,32 +24,14 @@ package dragonBones.events
*/
public static const SOUND:String = "sound";
- public var movementID:String;
-
- public var sound:String;
- public var soundEffect:String;
-
- /** @private */
- dragonBones_internal var _armature:Armature;
-
/**
* The armature that is the target of this event.
*/
- public function get armature():Armature
- {
- return _armature;
- }
+ public var armature:Armature;
- /** @private */
- dragonBones_internal var _bone:Bone;
+ public var animationState:AnimationState;
- /**
- * The bone that is the target of this event.
- */
- public function get bone():Bone
- {
- return _bone;
- }
+ public var sound:String;
/**
* Creates a new SoundEvent instance.
@@ -69,11 +49,9 @@ package dragonBones.events
override public function clone():Event
{
var event:SoundEvent = new SoundEvent(type, cancelable);
- event.movementID = movementID;
+ event.armature = armature;
+ event.animationState = animationState;
event.sound = sound;
- event.soundEffect = soundEffect;
- event._armature = _armature;
- event._bone = _bone;
return event;
}
}
diff --git a/src/dragonBones/factorys/BaseFactory.as b/src/dragonBones/factorys/BaseFactory.as
index 35e3021..b7c3a37 100644
--- a/src/dragonBones/factorys/BaseFactory.as
+++ b/src/dragonBones/factorys/BaseFactory.as
@@ -1,37 +1,31 @@
package dragonBones.factorys
{
-
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0, Flash 10
- * @langversion 3.0
- * @version 2.0
- */
-
import dragonBones.Armature;
import dragonBones.Bone;
- import dragonBones.display.NativeDisplayBridge;
+ import dragonBones.Slot;
+ import dragonBones.core.dragonBones_internal;
import dragonBones.objects.AnimationData;
import dragonBones.objects.ArmatureData;
import dragonBones.objects.BoneData;
+ import dragonBones.objects.DataParser;
import dragonBones.objects.DecompressedData;
import dragonBones.objects.DisplayData;
import dragonBones.objects.SkeletonData;
- import dragonBones.objects.XMLDataParser;
+ import dragonBones.objects.SkinData;
+ import dragonBones.objects.SlotData;
import dragonBones.textures.ITextureAtlas;
- import dragonBones.textures.NativeTextureAtlas;
- import dragonBones.textures.SubTextureData;
import dragonBones.utils.BytesType;
- import dragonBones.utils.dragonBones_internal;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.MovieClip;
- import flash.display.Shape;
import flash.display.Sprite;
+ import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Matrix;
+ import flash.geom.Point;
+ import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
@@ -40,54 +34,33 @@ package dragonBones.factorys
/** Dispatched after a sucessful call to parseData(). */
[Event(name="complete", type="flash.events.Event")]
- /**
- * A BaseFactory instance manages the set of armature resources for the tranditional Flash DisplayList. It parses the raw data (ByteArray), stores the armature resources and creates armature instances.
- * Create an instance of the BaseFactory class that way:
- *
- * import flash.events.Event;
- * import dragonBones.factorys.BaseFactory;
- *
- * [Embed(source = "../assets/Dragon1.swf", mimeType = "application/octet-stream")]
- * private static const ResourcesData:Class;
- * var factory:BaseFactory = new BaseFactory();
- * factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
- * factory.parseData(new ResourcesData());
- *
- * @see dragonBones.Armature
- */
public class BaseFactory extends EventDispatcher
{
- private static var _loaderContext:LoaderContext = new LoaderContext(false);
/** @private */
- protected static var _helpMatirx:Matrix = new Matrix();
+ protected static const _helpMatirx:Matrix = new Matrix();
+ private static const _loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
+
/** @private */
- protected var _skeletonDataDic:Object;
+ protected var _dataDic:Object;
/** @private */
protected var _textureAtlasDic:Object;
/** @private */
protected var _textureAtlasLoadingDic:Object;
/** @private */
- protected var _currentSkeletonData:SkeletonData;
- /** @private */
- protected var _currentTextureAtlas:Object;
- /** @private */
- protected var _currentSkeletonName:String;
+ protected var _currentDataName:String;
/** @private */
protected var _currentTextureAtlasName:String;
- /**
- * Create a Basefactory instance.
- *
- * @example
- *
- * import dragonBones.factorys.BaseFactory;
- * var factory:BaseFactory = new BaseFactory();
- *
- */
- public function BaseFactory()
+ public function BaseFactory(self:BaseFactory)
{
- super();
- _skeletonDataDic = {};
+ super(this);
+
+ if(self != this)
+ {
+ throw new IllegalOperationError("Abstract class can not be instantiated!");
+ }
+
+ _dataDic = {};
_textureAtlasDic = {};
_textureAtlasLoadingDic = {};
_loaderContext.allowCodeImport = true;
@@ -100,65 +73,77 @@ package dragonBones.factorys
* import flash.events.Event;
* import dragonBones.factorys.BaseFactory;
*
- * [Embed(source = "../assets/Dragon1.swf", mimeType = "application/octet-stream")]
+ * [Embed(source = "../assets/Dragon1.swf", mimeType = "application/octet-stream")]
* private static const ResourcesData:Class;
* var factory:BaseFactory = new BaseFactory();
* factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
* factory.parseData(new ResourcesData());
*
- * @param ByteArray. Represents the raw data for the whole skeleton system.
+ * @param ByteArray. Represents the raw data for the whole DragonBones system.
* @param String. (optional) The SkeletonData instance name.
* @return A SkeletonData instance.
*/
- public function parseData(bytes:ByteArray, skeletonName:String = null):SkeletonData
+ public function parseData(bytes:ByteArray, dataName:String = null):SkeletonData
{
- var decompressedData:DecompressedData = XMLDataParser.decompressData(bytes);
- var skeletonData:SkeletonData = XMLDataParser.parseSkeletonData(decompressedData.skeletonXML);
- skeletonName = skeletonName || skeletonData.name;
- addSkeletonData(skeletonData, skeletonName);
+ if(!bytes)
+ {
+ throw new ArgumentError();
+ }
+ var decompressedData:DecompressedData = DataParser.decompressData(bytes);
+
+ var data:SkeletonData = DataParser.parseData(decompressedData.dragonBonesData);
+
+ dataName = dataName || data.name;
+ addSkeletonData(data, dataName);
var loader:Loader = new Loader();
- loader.name = skeletonName;
- _textureAtlasLoadingDic[skeletonName] = decompressedData.textureAtlasXML;
+ loader.name = dataName;
+ _textureAtlasLoadingDic[dataName] = decompressedData.textureAtlasData;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
- loader.loadBytes(decompressedData.textureBytes, _loaderContext);
+ loader.loadBytes(decompressedData.textureBytes, _loaderContext);
decompressedData.dispose();
- return skeletonData;
+ return data;
}
+
/**
* Returns a SkeletonData instance.
* @example
*
- * var skeleton:SkeletonData = factory.getSkeletonData('dragon');
+ * var data:SkeletonData = factory.getSkeletonData('dragon');
*
* @param The name of an existing SkeletonData instance.
* @return A SkeletonData instance with given name (if exist).
*/
public function getSkeletonData(name:String):SkeletonData
{
- return _skeletonDataDic[name];
+ return _dataDic[name];
}
/**
* Add a SkeletonData instance to this BaseFactory instance.
* @example
*
- * factory.addSkeletonData(skeletondata, 'dragon');
+ * factory.addSkeletonData(data, 'dragon');
*
- * @param A skeletonData instance.
+ * @param A SkeletonData instance.
* @param (optional) A name for this SkeletonData instance.
*/
- public function addSkeletonData(skeletonData:SkeletonData, name:String = null):void
+ public function addSkeletonData(data:SkeletonData, name:String = null):void
{
- name = name || skeletonData.name;
+ if(!data)
+ {
+ throw new ArgumentError();
+ }
+ name = name || data.name;
if(!name)
{
throw new ArgumentError("Unnamed data!");
}
- if(skeletonData)
+ if(_dataDic[name])
{
- _skeletonDataDic[name] = skeletonData;
+
}
+ _dataDic[name] = data;
}
/**
@@ -171,7 +156,7 @@ package dragonBones.factorys
*/
public function removeSkeletonData(name:String):void
{
- delete _skeletonDataDic[name];
+ delete _dataDic[name];
}
/**
@@ -199,19 +184,23 @@ package dragonBones.factorys
*/
public function addTextureAtlas(textureAtlas:Object, name:String = null):void
{
+ if(!textureAtlas)
+ {
+ throw new ArgumentError();
+ }
if(!name && textureAtlas is ITextureAtlas)
{
name = textureAtlas.name;
}
-
if(!name)
{
throw new ArgumentError("Unnamed data!");
}
- if(textureAtlas)
+ if(_textureAtlasDic[name])
{
- _textureAtlasDic[name] = textureAtlas;
+
}
+ _textureAtlasDic[name] = textureAtlas;
}
/**
@@ -227,112 +216,173 @@ package dragonBones.factorys
delete _textureAtlasDic[name];
}
-
-
- /**
- * Cleans up resources used by this BaseFactory instance.
+ /**
+ * Cleans up resources used by this BaseFactory instance.
* @example
*
* factory.dispose();
*
- * @param (optional) Destroy all internal references.
- */
+ * @param (optional) Destroy all internal references.
+ */
public function dispose(disposeData:Boolean = true):void
{
if(disposeData)
{
- for each(var skeletonData:SkeletonData in _skeletonDataDic)
+ for each(var data:SkeletonData in _dataDic)
{
- skeletonData.dispose();
+ data.dispose();
}
for each(var textureAtlas:Object in _textureAtlasDic)
{
textureAtlas.dispose();
}
}
- _skeletonDataDic = {};
- _textureAtlasDic = {};
- _textureAtlasLoadingDic = {};
- _currentSkeletonData = null;
- _currentTextureAtlas = null;
- _currentSkeletonName = null;
+ _dataDic = null
+ _textureAtlasDic = null;
+ _textureAtlasLoadingDic = null;
+ _currentDataName = null;
_currentTextureAtlasName = null;
}
- /**
- * Build and returns a new Armature instance.
+ /**
+ * Build and returns a new Armature instance.
* @example
*
* var armature:Armature = factory.buildArmature('dragon');
*
- * @param The name of this Armature instance.
- * @param The name of this animation.
- * @param The name of this skeleton.
- * @param The name of this textureAtlas.
- * @return A Armature instance.
- */
- public function buildArmature(armatureName:String, animationName:String = null, skeletonName:String = null, textureAtlasName:String = null):Armature
+ * @param armatureName The name of this Armature instance.
+ * @param The name of this animation.
+ * @param The name of this SkeletonData.
+ * @param The name of this textureAtlas.
+ * @param The name of this skin.
+ * @return A Armature instance.
+ */
+ public function buildArmature(armatureName:String, animationName:String = null, skeletonName:String = null, textureAtlasName:String = null, skinName:String = null):Armature
{
- animationName = animationName || armatureName;
- var skeletonData:SkeletonData;
- var armatureData:ArmatureData;
if(skeletonName)
{
- skeletonData = _skeletonDataDic[skeletonName];
- if(skeletonData)
+ var data:SkeletonData = _dataDic[skeletonName];
+ if(data)
{
- armatureData = skeletonData.getArmatureData(armatureName);
+ var armatureData:ArmatureData = data.getArmatureData(armatureName);
}
}
else
{
- for (skeletonName in _skeletonDataDic)
+ for (skeletonName in _dataDic)
{
- skeletonData = _skeletonDataDic[skeletonName];
- armatureData = skeletonData.getArmatureData(armatureName);
+ data = _dataDic[skeletonName];
+ armatureData = data.getArmatureData(armatureName);
if(armatureData)
{
break;
}
}
}
+
if(!armatureData)
{
return null;
}
- _currentSkeletonName = skeletonName;
- _currentSkeletonData = skeletonData;
+
+ _currentDataName = skeletonName;
_currentTextureAtlasName = textureAtlasName || skeletonName;
- _currentTextureAtlas = _textureAtlasDic[_currentTextureAtlasName];
- var animationData:AnimationData = _currentSkeletonData.getAnimationData(animationName);
- if(!animationData)
+
+ var armature:Armature = generateArmature();
+ armature.name = armatureName;
+ var bone:Bone;
+ for each(var boneData:BoneData in armatureData.boneDataList)
+ {
+ bone = new Bone();
+ bone.name = boneData.name;
+ bone.origin.copy(boneData.transform);
+ if(armatureData.getBoneData(boneData.parent))
+ {
+ armature.addBone(bone, boneData.parent);
+ }
+ else
+ {
+ armature.addBone(bone);
+ }
+ }
+
+ if(animationName && animationName != armatureName)
{
- for (skeletonName in _skeletonDataDic)
+ var animationArmatureData:ArmatureData = data.getArmatureData(animationName);
+ if(!animationArmatureData)
{
- skeletonData = _skeletonDataDic[skeletonName];
- animationData = skeletonData.getAnimationData(animationName);
- if(animationData)
+ for (skeletonName in _dataDic)
{
- break;
+ data = _dataDic[skeletonName];
+ animationArmatureData = data.getArmatureData(animationName);
+ if(animationArmatureData)
+ {
+ break;
+ }
}
}
- }
- var armature:Armature = generateArmature();
- armature.name = armatureName;
- armature.animation.animationData = animationData;
- var boneNames:Vector. = armatureData.boneNames;
- for each(var boneName:String in boneNames)
+ }
+
+ if(animationArmatureData)
+ {
+ armature.animation.animationDataList = animationArmatureData.animationDataList;
+ }
+ else
{
- var boneData:BoneData = armatureData.getBoneData(boneName);
- if(boneData)
+ armature.animation.animationDataList = armatureData.animationDataList;
+ }
+
+ var skinData:SkinData = armatureData.getSkinData(skinName);
+ if(!skinData)
+ {
+ throw new ArgumentError();
+ }
+
+ var slot:Slot;
+ var displayData:DisplayData;
+ var childArmature:Armature;
+ var i:int;
+ var helpArray:Array = [];
+ for each(var slotData:SlotData in skinData.slotDataList)
+ {
+ bone = armature.getBone(slotData.parent);
+ if(!bone)
{
- var bone:Bone = buildBone(boneData);
- bone.name = boneName;
- armature.addBone(bone, boneData.parent);
+ continue;
}
+ slot = generateSlot();
+ slot.name = slotData.name;
+ slot._originZOrder = slotData.zOrder;
+ slot._dislayDataList = slotData.displayDataList;
+
+ helpArray.length = 0;
+ i = slotData.displayDataList.length;
+ while(i --)
+ {
+ displayData = slotData.displayDataList[i];
+
+ switch(displayData.type)
+ {
+ case DisplayData.ARMATURE:
+ childArmature = buildArmature(displayData.name, null, _currentDataName, _currentTextureAtlasName);
+ if(childArmature)
+ {
+ helpArray[i] = childArmature;
+ }
+ break;
+ case DisplayData.IMAGE:
+ default:
+ helpArray[i] = generateDisplay(_textureAtlasDic[_currentTextureAtlasName], displayData.name, displayData.pivot.x, displayData.pivot.y);
+ break;
+
+ }
+ }
+ slot.displayList = helpArray;
+ slot.changeDisplay(0);
+ bone.addChild(slot);
}
- armature._bonesIndexChanged = true;
- armature.update();
+ armature._slotsZOrderChanged = true;
+ armature.advanceTime(0);
return armature;
}
@@ -350,12 +400,11 @@ package dragonBones.factorys
*/
public function getTextureDisplay(textureName:String, textureAtlasName:String = null, pivotX:Number = NaN, pivotY:Number = NaN):Object
{
- var textureAtlas:Object;
if(textureAtlasName)
{
- textureAtlas = _textureAtlasDic[textureAtlasName];
+ var textureAtlas:Object = _textureAtlasDic[textureAtlasName];
}
- else
+ if(!textureAtlas && !textureAtlasName)
{
for (textureAtlasName in _textureAtlasDic)
{
@@ -371,50 +420,23 @@ package dragonBones.factorys
{
if(isNaN(pivotX) || isNaN(pivotY))
{
- var skeletonData:SkeletonData = _skeletonDataDic[textureAtlasName];
- if(skeletonData)
+ var data:SkeletonData = _dataDic[textureAtlasName];
+ if(data)
{
- var displayData:DisplayData = skeletonData.getDisplayData(textureName);
- if(displayData)
+ var pivot:Point = data.getSubTexturePivot(textureName);
+ if(pivot)
{
- pivotX = pivotX || displayData.pivotX;
- pivotY = pivotY || displayData.pivotY;
+ pivotX = pivot.x;
+ pivotY = pivot.y;
}
}
}
- return generateTextureDisplay(textureAtlas, textureName, pivotX, pivotY);
+ return generateDisplay(textureAtlas, textureName, pivotX, pivotY);
}
return null;
}
- /** @private */
- protected function buildBone(boneData:BoneData):Bone
- {
- var bone:Bone = generateBone();
- bone.origin.copy(boneData.node);
-
- var displayData:DisplayData;
- for(var i:int = boneData._displayNames.length - 1;i >= 0;i --)
- {
- var displayName:String = boneData._displayNames[i];
- displayData = _currentSkeletonData.getDisplayData(displayName);
- bone.changeDisplay(i);
- if (displayData.isArmature)
- {
- var childArmature:Armature = buildArmature(displayName, null, _currentSkeletonName, _currentTextureAtlasName);
- if(childArmature)
- {
- childArmature.animation.play();
- bone.display = childArmature;
- }
- }
- else
- {
- bone.display = generateTextureDisplay(_currentTextureAtlas, displayName, displayData.pivotX, displayData.pivotY);
- }
- }
- return bone;
- }
+
/** @private */
protected function loaderCompleteHandler(e:Event):void
{
@@ -423,10 +445,10 @@ package dragonBones.factorys
var content:Object = e.target.content;
loader.unloadAndStop();
- var skeletonName:String = loader.name;
- var textureAtlasXML:XML = _textureAtlasLoadingDic[skeletonName];
- delete _textureAtlasLoadingDic[skeletonName];
- if(skeletonName && textureAtlasXML)
+ var name:String = loader.name;
+ var textureAtlasRawData:Object = _textureAtlasLoadingDic[name];
+ delete _textureAtlasLoadingDic[name];
+ if(name && textureAtlasRawData)
{
if (content is Bitmap)
{
@@ -441,88 +463,56 @@ package dragonBones.factorys
//
}
- var textureAtlas:Object = generateTextureAtlas(content, textureAtlasXML);
- addTextureAtlas(textureAtlas, skeletonName);
+ var textureAtlas:Object = generateTextureAtlas(content, textureAtlasRawData);
+ addTextureAtlas(textureAtlas, name);
- skeletonName = null;
- for(skeletonName in _textureAtlasLoadingDic)
+ name = null;
+ for(name in _textureAtlasLoadingDic)
{
break;
}
//
- if(!skeletonName && hasEventListener(Event.COMPLETE))
+ if(!name && this.hasEventListener(Event.COMPLETE))
{
- dispatchEvent(new Event(Event.COMPLETE));
+ this.dispatchEvent(new Event(Event.COMPLETE));
}
}
}
+
/** @private */
- protected function generateTextureAtlas(content:Object, textureAtlasXML:XML):Object
+ protected function generateTextureAtlas(content:Object, textureAtlasRawData:Object):ITextureAtlas
{
- var textureAtlas:NativeTextureAtlas = new NativeTextureAtlas(content, textureAtlasXML);
- return textureAtlas;
+ return null;
}
- /** @private */
+
+ /**
+ * Generates an Armature instance.
+ * @return Armature An Armature instance.
+ */
protected function generateArmature():Armature
{
- var display:Sprite = new Sprite();
- var armature:Armature = new Armature(display);
- return armature;
+ return null;
}
- /** @private */
- protected function generateBone():Bone
+
+ /**
+ * Generates an Slot instance.
+ * @return Slot An Slot instance.
+ */
+ protected function generateSlot():Slot
{
- var bone:Bone = new Bone(new NativeDisplayBridge());
- return bone;
+ return null;
}
- protected function generateTextureDisplay(textureAtlas:Object, fullName:String, pivotX:Number, pivotY:Number):Object
+ /**
+ * Generates a DisplayObject
+ * @param textureAtlas The TextureAtlas.
+ * @param fullName A qualified name.
+ * @param pivotX A pivot x based value.
+ * @param pivotY A pivot y based value.
+ * @return
+ */
+ protected function generateDisplay(textureAtlas:Object, fullName:String, pivotX:Number, pivotY:Number):Object
{
- var nativeTextureAtlas:NativeTextureAtlas = textureAtlas as NativeTextureAtlas;
- if(nativeTextureAtlas){
- var movieClip:MovieClip = nativeTextureAtlas.movieClip;
- if (movieClip && movieClip.totalFrames >= 3)
- {
- movieClip.gotoAndStop(movieClip.totalFrames);
- movieClip.gotoAndStop(fullName);
- if (movieClip.numChildren > 0)
- {
- try
- {
- var displaySWF:Object = movieClip.getChildAt(0);
- displaySWF.x = 0;
- displaySWF.y = 0;
- return displaySWF;
- }
- catch(e:Error)
- {
- throw "Can not get the movie clip, please make sure the version of the resource compatible with app version!";
- }
- }
- }
- else if(nativeTextureAtlas.bitmapData)
- {
- var subTextureData:SubTextureData = nativeTextureAtlas.getRegion(fullName) as SubTextureData;
- if (subTextureData)
- {
- var displayShape:Shape = new Shape();
- //1.4
- pivotX = pivotX || subTextureData.pivotX;
- pivotY = pivotY || subTextureData.pivotY;
- _helpMatirx.a = 1;
- _helpMatirx.b = 0;
- _helpMatirx.c = 0;
- _helpMatirx.d = 1;
- _helpMatirx.scale(nativeTextureAtlas.scale, nativeTextureAtlas.scale);
- _helpMatirx.tx = -subTextureData.x - pivotX;
- _helpMatirx.ty = -subTextureData.y - pivotY;
-
- displayShape.graphics.beginBitmapFill(nativeTextureAtlas.bitmapData, _helpMatirx, false, true);
- displayShape.graphics.drawRect(-pivotX, -pivotY, subTextureData.width, subTextureData.height);
- return displayShape;
- }
- }
- }
return null;
}
}
diff --git a/src/dragonBones/factorys/NativeFactory.as b/src/dragonBones/factorys/NativeFactory.as
new file mode 100644
index 0000000..6d27dbb
--- /dev/null
+++ b/src/dragonBones/factorys/NativeFactory.as
@@ -0,0 +1,106 @@
+package dragonBones.factorys
+{
+ import dragonBones.Armature;
+ import dragonBones.Slot;
+ import dragonBones.display.NativeDisplayBridge;
+ import dragonBones.textures.ITextureAtlas;
+ import dragonBones.textures.NativeTextureAtlas;
+
+ import flash.display.MovieClip;
+ import flash.display.Shape;
+ import flash.display.Sprite;
+ import flash.geom.Rectangle;
+
+ /**
+ * Copyright 2012-2013. DragonBones. All Rights Reserved.
+ * @playerversion Flash 10.0, Flash 10
+ * @langversion 3.0
+ * @version 2.0
+ */
+
+ public class NativeFactory extends BaseFactory
+ {
+ public var fillBitmapSmooth:Boolean;
+
+ public function NativeFactory()
+ {
+ super(this);
+ }
+
+ /** @private */
+ override protected function generateTextureAtlas(content:Object, textureAtlasRawData:Object):ITextureAtlas
+ {
+ var textureAtlas:NativeTextureAtlas = new NativeTextureAtlas(content, textureAtlasRawData, 1, false);
+ return textureAtlas;
+ }
+
+ /** @private */
+ override protected function generateArmature():Armature
+ {
+ var display:Sprite = new Sprite();
+ var armature:Armature = new Armature(display);
+ return armature;
+ }
+
+ /** @private */
+ override protected function generateSlot():Slot
+ {
+ var slot:Slot = new Slot(new NativeDisplayBridge());
+ return slot;
+ }
+
+ /** @private */
+ override protected function generateDisplay(textureAtlas:Object, fullName:String, pivotX:Number, pivotY:Number):Object
+ {
+ var nativeTextureAtlas:NativeTextureAtlas = textureAtlas as NativeTextureAtlas;
+ if(nativeTextureAtlas)
+ {
+ var movieClip:MovieClip = nativeTextureAtlas.movieClip;
+ if (movieClip && movieClip.totalFrames >= 3)
+ {
+ movieClip.gotoAndStop(movieClip.totalFrames);
+ movieClip.gotoAndStop(fullName);
+ if (movieClip.numChildren > 0)
+ {
+ try
+ {
+ var displaySWF:Object = movieClip.getChildAt(0);
+ displaySWF.x = 0;
+ displaySWF.y = 0;
+ return displaySWF;
+ }
+ catch(e:Error)
+ {
+ throw new Error("Can not get the movie clip, please make sure the version of the resource compatible with app version!");
+ }
+ }
+ }
+ else if(nativeTextureAtlas.bitmapData)
+ {
+ var subTextureData:Rectangle = nativeTextureAtlas.getRegion(fullName);
+ if (subTextureData)
+ {
+ var displayShape:Shape = new Shape();
+ _helpMatirx.a = 1;
+ _helpMatirx.b = 0;
+ _helpMatirx.c = 0;
+ _helpMatirx.d = 1;
+ _helpMatirx.scale(nativeTextureAtlas.scale, nativeTextureAtlas.scale);
+ _helpMatirx.tx = -pivotX - subTextureData.x;
+ _helpMatirx.ty = -pivotY - subTextureData.y;
+
+ displayShape.graphics.beginBitmapFill(nativeTextureAtlas.bitmapData, _helpMatirx, false, fillBitmapSmooth);
+ displayShape.graphics.drawRect(-pivotX, -pivotY, subTextureData.width, subTextureData.height);
+
+ return displayShape;
+ }
+ }
+ else
+ {
+ throw new Error();
+ }
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/factorys/StarlingFactory.as b/src/dragonBones/factorys/StarlingFactory.as
index d1f059e..3c30eb3 100644
--- a/src/dragonBones/factorys/StarlingFactory.as
+++ b/src/dragonBones/factorys/StarlingFactory.as
@@ -8,26 +8,26 @@
*/
import dragonBones.Armature;
import dragonBones.Bone;
+ import dragonBones.Slot;
+ import dragonBones.core.dragonBones_internal;
import dragonBones.display.StarlingDisplayBridge;
import dragonBones.textures.ITextureAtlas;
import dragonBones.textures.StarlingTextureAtlas;
- import dragonBones.textures.SubTextureData;
- import dragonBones.utils.ConstValues;
- import dragonBones.utils.dragonBones_internal;
+
import flash.display.BitmapData;
import flash.display.MovieClip;
- import flash.geom.Rectangle;
- import flash.utils.ByteArray;
+
import starling.core.Starling;
import starling.display.Image;
import starling.display.Sprite;
import starling.textures.SubTexture;
import starling.textures.Texture;
- import starling.textures.TextureAtlas;
+ import starling.textures.TextureAtlas;
+
use namespace dragonBones_internal;
/**
- * A object managing the set of armature resources for Starling engine. It parses the raw data, stores the armature resources and creates armature instrances.
+ * A object managing the set of armature resources for Starling engine. It parses the raw data, stores the armature resources and creates armature instances.
* @see dragonBones.Armature
*/
@@ -66,60 +66,12 @@
*/
public function StarlingFactory()
{
- super();
+ super(this);
scaleForTexture = 1;
}
- /**
- * Generates an Armature instance.
- * @return Armature An Armature instance.
- */
- override protected function generateArmature():Armature
- {
- var armature:Armature = new Armature(new Sprite());
- return armature;
- }
- /**
- * Generates a Bone instance.
- * @return Bone A Bone instance.
- */
- override protected function generateBone():Bone
- {
- var bone:Bone = new Bone(new StarlingDisplayBridge());
- return bone;
- }
- /**
- * Generates a starling DisplayObject
- * @param textureAtlas The TextureAtlas.
- * @param fullName A qualified name.
- * @param pivotX A pivot x based value.
- * @param pivotY A pivot y based value.
- * @return
- */
- override protected function generateTextureDisplay(textureAtlas:Object, fullName:String, pivotX:Number, pivotY:Number):Object
- {
- var starlingTextureAtlas:StarlingTextureAtlas = textureAtlas as StarlingTextureAtlas;
- if (starlingTextureAtlas)
- {
- //1.4
- var subTextureData:SubTextureData = starlingTextureAtlas.getRegion(fullName) as SubTextureData;
- if (subTextureData)
- {
- pivotX = pivotX || subTextureData.pivotX;
- pivotY = pivotY || subTextureData.pivotY;
- }
- }
- var subTexture:SubTexture = (textureAtlas as TextureAtlas).getTexture(fullName) as SubTexture;
- if (subTexture)
- {
- var image:Image = new Image(subTexture);
- image.pivotX = pivotX;
- image.pivotY = pivotY;
- return image;
- }
- return null;
- }
- override protected function generateTextureAtlas(content:Object, textureAtlasXML:XML):Object
+ /** @private */
+ override protected function generateTextureAtlas(content:Object, textureAtlasRawData:Object):ITextureAtlas
{
var texture:Texture;
var bitmapData:BitmapData;
@@ -130,8 +82,9 @@
}
else if (content is MovieClip)
{
- var width:int = int(textureAtlasXML.attribute(ConstValues.A_WIDTH)) * scaleForTexture;
- var height:int = int(textureAtlasXML.attribute(ConstValues.A_HEIGHT)) * scaleForTexture;
+ var width:int = getNearest2N(content.width) * scaleForTexture;
+ var height:int = getNearest2N(content.height) * scaleForTexture;
+
_helpMatirx.a = 1;
_helpMatirx.b = 0;
_helpMatirx.c = 0;
@@ -148,9 +101,9 @@
}
else
{
- //
+ throw new Error();
}
- var textureAtlas:StarlingTextureAtlas = new StarlingTextureAtlas(texture, textureAtlasXML);
+ var textureAtlas:StarlingTextureAtlas = new StarlingTextureAtlas(texture, textureAtlasRawData, false);
if (Starling.handleLostContext)
{
textureAtlas._bitmapData = bitmapData;
@@ -161,5 +114,38 @@
}
return textureAtlas;
}
+
+ /** @private */
+ override protected function generateArmature():Armature
+ {
+ var armature:Armature = new Armature(new Sprite());
+ return armature;
+ }
+
+ /** @private */
+ override protected function generateSlot():Slot
+ {
+ var slot:Slot = new Slot(new StarlingDisplayBridge());
+ return slot;
+ }
+
+ /** @private */
+ override protected function generateDisplay(textureAtlas:Object, fullName:String, pivotX:Number, pivotY:Number):Object
+ {
+ var subTexture:SubTexture = (textureAtlas as TextureAtlas).getTexture(fullName) as SubTexture;
+ if (subTexture)
+ {
+ var image:Image = new Image(subTexture);
+ image.pivotX = pivotX;
+ image.pivotY = pivotY;
+ return image;
+ }
+ return null;
+ }
+
+ private function getNearest2N(_n:uint):uint
+ {
+ return _n & _n - 1?1 << _n.toString(2).length:_n;
+ }
}
}
\ No newline at end of file
diff --git a/src/dragonBones/objects/AnimationData.as b/src/dragonBones/objects/AnimationData.as
index f5a53d3..381f7f0 100644
--- a/src/dragonBones/objects/AnimationData.as
+++ b/src/dragonBones/objects/AnimationData.as
@@ -1,39 +1,67 @@
package dragonBones.objects
{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
-
- /** @private */
- public class AnimationData
+ final public class AnimationData extends Timeline
{
- dragonBones_internal var _movementDataList:DataList;
+ public var frameRate:uint;
+ public var name:String;
+ public var loop:int;
+ public var tweenEasing:Number;
- public function get movementList():Vector.
+ private var _timelines:Object;
+ public function get timelines():Object
{
- return _movementDataList.dataNames.concat();
+ return _timelines;
+ }
+
+ private var _fadeTime:Number;
+ public function get fadeInTime():Number
+ {
+ return _fadeTime;
+ }
+ public function set fadeInTime(value:Number):void
+ {
+ if(isNaN(value))
+ {
+ value = 0;
+ }
+ _fadeTime = value;
}
public function AnimationData()
{
- _movementDataList = new DataList();
+ super();
+ loop = 0;
+ tweenEasing = NaN;
+
+ _timelines = {};
+
+ _fadeTime = 0;
}
- public function dispose():void
+ override public function dispose():void
{
- for each(var movementName:String in _movementDataList.dataNames)
+ super.dispose();
+
+ for(var timelineName:String in _timelines)
{
- var movementData:MovementData = _movementDataList.getData(movementName) as MovementData;
- movementData.dispose();
+ (_timelines[timelineName] as TransformTimeline).dispose();
}
-
- _movementDataList.dispose();
+ _timelines = null;
+ }
+
+ public function getTimeline(timelineName:String):TransformTimeline
+ {
+ return _timelines[timelineName] as TransformTimeline;
}
- public function getMovementData(name:String):MovementData
+ public function addTimeline(timeline:TransformTimeline, timelineName:String):void
{
- return _movementDataList.getData(name) as MovementData;
+ if(!timeline)
+ {
+ throw new ArgumentError();
+ }
+
+ _timelines[timelineName] = timeline;
}
}
-
}
\ No newline at end of file
diff --git a/src/dragonBones/objects/ArmatureData.as b/src/dragonBones/objects/ArmatureData.as
index d2b77c5..316258f 100644
--- a/src/dragonBones/objects/ArmatureData.as
+++ b/src/dragonBones/objects/ArmatureData.as
@@ -1,70 +1,187 @@
package dragonBones.objects
{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
-
- /** @private */
- public class ArmatureData
+ final public class ArmatureData
{
- dragonBones_internal var _boneDataList:DataList;
+ public var name:String;
- public function get boneNames():Vector.
+ private var _boneDataList:Vector.;
+ public function get boneDataList():Vector.
{
- return _boneDataList.dataNames.concat();
+ return _boneDataList;
+ }
+
+ private var _skinDataList:Vector.;
+ public function get skinDataList():Vector.
+ {
+ return _skinDataList;
+ }
+
+ private var _animationDataList:Vector.;
+ public function get animationDataList():Vector.
+ {
+ return _animationDataList;
}
public function ArmatureData()
{
- _boneDataList = new DataList();
+ _boneDataList = new Vector.(0, true);
+ _skinDataList = new Vector.(0, true);
+ _animationDataList = new Vector.(0, true);
}
public function dispose():void
{
- for each(var boneName:String in _boneDataList.dataNames)
+ var i:int = _boneDataList.length;
+ while(i --)
+ {
+ _boneDataList[i].dispose();
+ }
+ i = _skinDataList.length;
+ while(i --)
+ {
+ _skinDataList[i].dispose();
+ }
+ i = _animationDataList.length;
+ while(i --)
+ {
+ _animationDataList[i].dispose();
+ }
+ _boneDataList.fixed = false;
+ _boneDataList.length = 0;
+ _skinDataList.fixed = false;
+ _skinDataList.length = 0;
+ _animationDataList.fixed = false;
+ _animationDataList.length = 0;
+ _boneDataList = null;
+ _skinDataList = null;
+ _animationDataList = null;
+ }
+
+ public function getBoneData(boneName:String):BoneData
+ {
+ var i:int = _boneDataList.length;
+ while(i --)
+ {
+ if(_boneDataList[i].name == boneName)
+ {
+ return _boneDataList[i];
+ }
+ }
+ return null;
+ }
+
+ public function getSkinData(skinName:String):SkinData
+ {
+ if(!skinName)
+ {
+ return _skinDataList[0];
+ }
+ var i:int = _skinDataList.length;
+ while(i --)
{
- var boneData:BoneData = _boneDataList.getData(boneName) as BoneData;
- boneData.dispose();
+ if(_skinDataList[i].name == skinName)
+ {
+ return _skinDataList[i];
+ }
}
- _boneDataList.dispose();
+ return null;
}
- public function getBoneData(name:String):BoneData
+ public function getAnimationData(animationName:String):AnimationData
{
- return _boneDataList.getData(name) as BoneData;
+ var i:int = _animationDataList.length;
+ while(i --)
+ {
+ if(_animationDataList[i].name == animationName)
+ {
+ return _animationDataList[i];
+ }
+ }
+ return null;
}
- public function updateBoneList():void
+ public function addBoneData(boneData:BoneData):void
{
- var boneNames:Vector. = _boneDataList.dataNames;
+ if(!boneData)
+ {
+ throw new ArgumentError();
+ }
- var sortList:Array = [];
- for each(var boneName:String in boneNames)
+ if (_boneDataList.indexOf(boneData) < 0)
{
- var boneData:BoneData = _boneDataList.getData(boneName) as BoneData;
- var levelValue:int = boneData.node.z;
+ _boneDataList.fixed = false;
+ _boneDataList[_boneDataList.length] = boneData;
+ _boneDataList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+
+ public function addSkinData(skinData:SkinData):void
+ {
+ if(!skinData)
+ {
+ throw new ArgumentError();
+ }
+
+ if(_skinDataList.indexOf(skinData) < 0)
+ {
+ _skinDataList.fixed = false;
+ _skinDataList[_skinDataList.length] = skinData;
+ _skinDataList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+
+ public function addAnimationData(animationData:AnimationData):void
+ {
+ if(!animationData)
+ {
+ throw new ArgumentError();
+ }
+
+ if(_animationDataList.indexOf(animationData) < 0)
+ {
+ _animationDataList.fixed = false;
+ _animationDataList[_animationDataList.length] = animationData;
+ _animationDataList.fixed = true;
+ }
+ }
+
+ public function sortBoneDataList():void
+ {
+ var i:int = _boneDataList.length;
+ if(i == 0)
+ {
+ return;
+ }
+
+ var helpArray:Array = [];
+ while(i --)
+ {
+ var boneData:BoneData = _boneDataList[i];
var level:int = 0;
- while(boneData)
+ var parentData:BoneData = boneData;
+ while(parentData && parentData.parent)
{
level ++;
- levelValue += 1000 * level;
- boneData = getBoneData(boneData.parent);
+ parentData = getBoneData(parentData.parent);
}
- sortList.push({level:levelValue, boneName:boneName});
+ helpArray[i] = {level:level, boneData:boneData};
}
- var length:int = sortList.length;
- if(length > 0)
+ helpArray.sortOn("level", Array.NUMERIC);
+
+ i = helpArray.length;
+ while(i --)
{
- sortList.sortOn("level", Array.NUMERIC);
- boneNames.length = 0;
- var i:int = 0;
- while(i < length)
- {
- boneNames[i] = sortList[i].boneName;
- i ++;
- }
+ _boneDataList[i] = helpArray[i].boneData;
}
}
}
diff --git a/src/dragonBones/objects/BoneData.as b/src/dragonBones/objects/BoneData.as
index 5fa3538..49c90c1 100644
--- a/src/dragonBones/objects/BoneData.as
+++ b/src/dragonBones/objects/BoneData.as
@@ -1,32 +1,27 @@
package dragonBones.objects
{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
-
- /** @private */
+ import flash.geom.Point;
+
final public class BoneData
{
- dragonBones_internal var _displayNames:Vector.;
+ public var name:String;
+ public var parent:String;
+ public var length:Number;
- dragonBones_internal var _parent:String;
-
- public function get parent():String
- {
- return _parent;
- }
-
- public var node:BoneTransform;
+ public var global:DBTransform;
+ public var transform:DBTransform;
public function BoneData()
{
- _displayNames = new Vector.;
- node = new BoneTransform();
+ length = 0;
+ global = new DBTransform();
+ transform = new DBTransform();
}
public function dispose():void
{
- _displayNames.length = 0;
+ global = null;
+ transform = null;
}
}
}
\ No newline at end of file
diff --git a/src/dragonBones/objects/BoneTransform.as b/src/dragonBones/objects/BoneTransform.as
deleted file mode 100644
index 515c45f..0000000
--- a/src/dragonBones/objects/BoneTransform.as
+++ /dev/null
@@ -1,169 +0,0 @@
-package dragonBones.objects
-{
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0
- * @langversion 3.0
- * @version 2.0
- */
-
- /**
- * The BoneTransform class provides transformation properties and methods for Bone instances.
- * @example
- * Download the example files here:
- * This example gets the BoneTransform of the head bone and adjust the x and y registration by 60 pixels.
- *
- * package
- * {
- * import dragonBones.Armature;
- * import dragonBones.factorys.BaseFactory;
- * import flash.display.Sprite;
- * import flash.events.Event;
- *
- * public class DragonAnimation extends Sprite
- * {
- * [Embed(source = "Dragon1.swf", mimeType = "application/octet-stream")]
- * private static const ResourcesData:Class;
- *
- * private var factory:BaseFactory;
- * private var armature:Armature;
- *
- * public function DragonAnimation()
- * {
- * factory = new BaseFactory();
- * factory.addEventListener(Event.COMPLETE, handleParseData);
- * factory.parseData(new ResourcesData(), 'Dragon');
- * }
- *
- * private function handleParseData(e:Event):void
- * {
- * armature = factory.buildArmature('Dragon');
- * addChild(armature.display as Sprite);
- * armature.animation.play();
- * var bone:Bone = armature.getBone("head");
- * bone.origin.pivotX = 60;//origin BoneTransform
- * bone.origin.pivotY = 60;//origin BoneTransform
- * addEventListener(Event.ENTER_FRAME, updateAnimation);
- * }
- *
- * private function updateAnimation(e:Event):void
- * {
- * armature.advanceTime(1 / stage.frameRate);
- * }
- * }
- * }
- *
- * @see dragonBones.Bone
- * @see dragonBones.animation.Animation
- */
- public class BoneTransform
- {
- /**
- * Position on the x axis.
- */
- public var x:Number;
- /**
- * Position on the y axis.
- */
- public var y:Number;
- /**
- * Scale on the x axis.
- */
- public var scaleX:Number;
- /**
- * Scale on the y axis.
- */
- public var scaleY:Number;
- /**
- * Skew on the x axis.
- */
- public var skewX:Number;
- /**
- * skew on the y axis.
- */
- public var skewY:Number;
- /**
- * pivot point on the x axis (registration)
- */
- public var pivotX:Number;
- /**
- * pivot point on the y axis (registration)
- */
- public var pivotY:Number;
- /**
- * Z order.
- */
- public var z:Number;
-
- /**
- * The rotation of that BoneTransform instance.
- */
- public function get rotation():Number
- {
- return skewX;
- }
- /**
- * @private
- */
- public function set rotation(value:Number):void
- {
- skewX = skewY = value;
- }
- /**
- * Creat a new BoneTransform instance.
- */
- public function BoneTransform()
- {
- setValues();
- }
- /**
- * Sets all properties at once.
- * @param x The x position.
- * @param y The y position.
- * @param skewX The skew value on x axis.
- * @param skewY The skew value on y axis.
- * @param scaleX The scale on x axis.
- * @param scaleY The scale on y axis.
- * @param pivotX The pivot value on x axis (registration)
- * @param pivotY The pivot valule on y axis (registration)
- * @param z The z order.
- */
- public function setValues(x:Number = 0, y:Number = 0, skewX:Number = 0, skewY:Number = 0, scaleX:Number = 0, scaleY:Number = 0, pivotX:Number = 0, pivotY:Number = 0, z:int = 0):void
- {
- this.x = x || 0;
- this.y = y || 0;
- this.skewX = skewX || 0;
- this.skewY = skewY || 0;
- this.scaleX = scaleX || 0;
- this.scaleY = scaleY || 0;
- this.pivotX = pivotX || 0;
- this.pivotY = pivotY || 0;
- this.z = z;
- }
- /**
- * Copy all properties from this BoneTransform instance to the passed BoneTransform instance.
- * @param node
- */
- public function copy(node:BoneTransform):void
- {
- x = node.x;
- y = node.y;
- scaleX = node.scaleX;
- scaleY = node.scaleY;
- skewX = node.skewX;
- skewY = node.skewY;
- pivotX = node.pivotX;
- pivotY = node.pivotY;
- z = node.z;
- }
- /**
- * Get a string representing all BoneTransform property values.
- * @return String All property values in a formatted string.
- */
- public function toString():String
- {
- var string:String = "x:" + x + " y:" + y + " skewX:" + skewX + " skewY:" + skewY + " scaleX:" + scaleX + " scaleY:" + scaleY;
- return string;
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/DBTransform.as b/src/dragonBones/objects/DBTransform.as
new file mode 100644
index 0000000..d7d1583
--- /dev/null
+++ b/src/dragonBones/objects/DBTransform.as
@@ -0,0 +1,81 @@
+package dragonBones.objects
+{
+ /**
+ * Copyright 2012-2013. DragonBones. All Rights Reserved.
+ * @playerversion Flash 10.0
+ * @langversion 3.0
+ * @version 2.0
+ */
+ public class DBTransform
+ {
+ /**
+ * Position on the x axis.
+ */
+ public var x:Number;
+ /**
+ * Position on the y axis.
+ */
+ public var y:Number;
+ /**
+ * Skew on the x axis.
+ */
+ public var skewX:Number;
+ /**
+ * skew on the y axis.
+ */
+ public var skewY:Number;
+ /**
+ * Scale on the x axis.
+ */
+ public var scaleX:Number;
+ /**
+ * Scale on the y axis.
+ */
+ public var scaleY:Number;
+ /**
+ * The rotation of that DBTransform instance.
+ */
+ public function get rotation():Number
+ {
+ return skewX;
+ }
+ public function set rotation(value:Number):void
+ {
+ skewX = skewY = value;
+ }
+ /**
+ * Creat a new DBTransform instance.
+ */
+ public function DBTransform()
+ {
+ x = 0;
+ y = 0;
+ skewX = 0;
+ skewY = 0;
+ scaleX = 1
+ scaleY = 1;
+ }
+ /**
+ * Copy all properties from this DBTransform instance to the passed DBTransform instance.
+ * @param node
+ */
+ public function copy(transform:DBTransform):void
+ {
+ x = transform.x;
+ y = transform.y;
+ skewX = transform.skewX;
+ skewY = transform.skewY;
+ scaleX = transform.scaleX;
+ scaleY = transform.scaleY;
+ }
+ /**
+ * Get a string representing all DBTransform property values.
+ * @return String All property values in a formatted string.
+ */
+ public function toString():String
+ {
+ var string:String = "x:" + x + " y:" + y + " skewX:" + skewX + " skewY:" + skewY + " scaleX:" + scaleX + " scaleY:" + scaleY;
+ return string;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/DataList.as b/src/dragonBones/objects/DataList.as
deleted file mode 100644
index 81d26cc..0000000
--- a/src/dragonBones/objects/DataList.as
+++ /dev/null
@@ -1,67 +0,0 @@
-package dragonBones.objects
-{
- internal final class DataList
- {
- private var _dataDic:Object;
- public var dataNames:Vector.;
-
- public function DataList()
- {
- _dataDic = {};
- dataNames = new Vector.;
- }
-
- public function dispose():void
- {
- _dataDic = {};
- dataNames.length = 0;
- }
-
- public function getData(dataName:String):Object
- {
- return _dataDic[dataName];
- }
-
- public function getDataAt(index:int):Object
- {
- return _dataDic[dataNames[index]];
- }
-
- public function addData(data:Object, dataName:String):void
- {
- if(data && dataName)
- {
- _dataDic[dataName] = data;
- if(dataNames.indexOf(dataName) < 0)
- {
- dataNames.push(dataName);
- }
- }
- }
-
- public function removeData(data:Object):void
- {
- if(data)
- {
- for(var dataName:String in _dataDic)
- {
- if(_dataDic[dataName] == data)
- {
- removeDataByName(dataName);
- return;
- }
- }
- }
- }
-
- public function removeDataByName(dataName:String):void
- {
- var data:Object = _dataDic[dataName];
- if(data)
- {
- delete _dataDic[dataName];
- dataNames.splice(dataNames.indexOf(dataName), 1);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/DataParser.as b/src/dragonBones/objects/DataParser.as
new file mode 100644
index 0000000..83bb4b9
--- /dev/null
+++ b/src/dragonBones/objects/DataParser.as
@@ -0,0 +1,140 @@
+package dragonBones.objects
+{
+ import dragonBones.objects.ObjectDataParser;
+ import dragonBones.objects.SkeletonData;
+ import dragonBones.objects.XMLDataParser;
+ import dragonBones.utils.BytesType;
+ import dragonBones.utils.checkBytesTailisXML;
+
+ import flash.utils.ByteArray;
+
+ public final class DataParser
+ {
+ /**
+ * Compress all data into a ByteArray for serialization.
+ * @param The DragonBones data.
+ * @param The TextureAtlas data.
+ * @param The ByteArray representing the map.
+ * @return ByteArray. A DragonBones compatible ByteArray.
+ */
+ public static function compressData(dragonBonesData:Object, textureAtlasData:Object, textureDataBytes:ByteArray):ByteArray
+ {
+ var retult:ByteArray = new ByteArray();
+ retult.writeBytes(textureDataBytes);
+
+ var dataBytes:ByteArray = new ByteArray();
+ dataBytes.writeObject(textureAtlasData);
+ dataBytes.compress();
+
+ retult.position = retult.length;
+ retult.writeBytes(dataBytes);
+ retult.writeInt(dataBytes.length);
+
+ dataBytes.length = 0;
+ dataBytes.writeObject(dragonBonesData);
+ dataBytes.compress();
+
+ retult.position = retult.length;
+ retult.writeBytes(dataBytes);
+ retult.writeInt(dataBytes.length);
+
+ return retult;
+ }
+
+ /**
+ * Decompress a compatible DragonBones data.
+ * @param compressedByteArray The ByteArray to decompress.
+ * @return A DecompressedData instance.
+ */
+ public static function decompressData(bytes:ByteArray):DecompressedData
+ {
+ var dataType:String = BytesType.getType(bytes);
+ switch (dataType)
+ {
+ case BytesType.SWF:
+ case BytesType.PNG:
+ case BytesType.JPG:
+ case BytesType.ATF:
+ try
+ {
+ bytes.position = bytes.length - 4;
+ var strSize:int = bytes.readInt();
+ var position:uint = bytes.length - 4 - strSize;
+
+ var dataBytes:ByteArray = new ByteArray();
+ dataBytes.writeBytes(bytes, position, strSize);
+ dataBytes.uncompress();
+ bytes.length = position;
+
+ var dragonBonesData:Object;
+ if(checkBytesTailisXML(dataBytes))
+ {
+ dragonBonesData = XML(dataBytes.readUTFBytes(dataBytes.length));
+ }
+ else
+ {
+ dragonBonesData = dataBytes.readObject();
+ }
+
+ bytes.position = bytes.length - 4;
+ strSize = bytes.readInt();
+ position = bytes.length - 4 - strSize;
+
+ dataBytes.length = 0;
+ dataBytes.writeBytes(bytes, position, strSize);
+ dataBytes.uncompress();
+ bytes.length = position;
+
+ var textureAtlasData:Object;
+ if(checkBytesTailisXML(dataBytes))
+ {
+ textureAtlasData = XML(dataBytes.readUTFBytes(dataBytes.length));
+ }
+ else
+ {
+ textureAtlasData = dataBytes.readObject();
+ }
+ }
+ catch (e:Error)
+ {
+ throw new Error("Data error!");
+ }
+
+ var decompressedData:DecompressedData = new DecompressedData(dragonBonesData, textureAtlasData, bytes);
+ decompressedData.textureBytesDataType = dataType;
+ return decompressedData;
+ case BytesType.ZIP:
+ throw new Error("Can not decompress zip!");
+ default:
+ throw new Error("Nonsupport data!");
+ }
+ return null;
+ }
+
+ public static function parseTextureAtlas(rawData:Object, scale:Number = 1):Object
+ {
+ if(rawData is XML)
+ {
+ return XMLDataParser.parseTextureAtlasData(rawData as XML, scale);
+ }
+ else
+ {
+ return ObjectDataParser.parseTextureAtlasData(rawData, scale);
+ }
+ return null;
+ }
+
+ public static function parseData(rawData:Object):SkeletonData
+ {
+ if(rawData is XML)
+ {
+ return XMLDataParser.parseSkeletonData(rawData as XML);
+ }
+ else
+ {
+ return ObjectDataParser.parseSkeletonData(rawData);
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/DecompressedData.as b/src/dragonBones/objects/DecompressedData.as
index 02c43b4..3b72d79 100644
--- a/src/dragonBones/objects/DecompressedData.as
+++ b/src/dragonBones/objects/DecompressedData.as
@@ -8,20 +8,21 @@ package dragonBones.objects
*/
import flash.utils.ByteArray;
/**
- * The DecompressedData is a convenient class for storing animation related data (skeleton, atlas, object).
+ * The DecompressedData is a convenient class for storing animation related data (data, atlas, object).
*
* @see dragonBones.Armature
*/
public final class DecompressedData
{
+ public var textureBytesDataType:String;
/**
- * A xml for Skeleton data.
+ * A xml for DragonBones data.
*/
- public var skeletonXML:XML;
+ public var dragonBonesData:Object;
/**
* A xml for atlas data.
*/
- public var textureAtlasXML:XML;
+ public var textureAtlasData:Object;
/**
* The non parsed data map.
*/
@@ -29,21 +30,21 @@ package dragonBones.objects
/**
* Creates a new DecompressedData instance.
- * @param skeletonXML A xml for Skeleton data.
+ * @param xml A xml for DragonBones data.
* @param textureAtlasXML A xml for atlas data.
* @param textureBytes The non parsed data map.
*/
- public function DecompressedData(skeletonXML:XML, textureAtlasXML:XML, textureBytes:ByteArray)
+ public function DecompressedData(dragonBonesData:Object, textureAtlasData:Object, textureBytes:ByteArray)
{
- this.skeletonXML = skeletonXML;
- this.textureAtlasXML = textureAtlasXML;
+ this.dragonBonesData = dragonBonesData;
+ this.textureAtlasData = textureAtlasData;
this.textureBytes = textureBytes;
}
public function dispose():void
{
- skeletonXML = null;
- textureAtlasXML = null;
+ dragonBonesData = null;
+ textureAtlasData = null;
textureBytes = null;
}
}
diff --git a/src/dragonBones/objects/DisplayData.as b/src/dragonBones/objects/DisplayData.as
index 6c45f8c..1a6b152 100644
--- a/src/dragonBones/objects/DisplayData.as
+++ b/src/dragonBones/objects/DisplayData.as
@@ -1,26 +1,27 @@
package dragonBones.objects
{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
+ import flash.geom.Point;
/** @private */
- public class DisplayData
+ final public class DisplayData
{
- public var pivotX:Number;
- public var pivotY:Number;
+ public static const ARMATURE:String = "armature";
+ public static const IMAGE:String = "image";
- dragonBones_internal var _isArmature:Boolean;
+ public var name:String;
+ public var type:String;
+ public var transform:DBTransform;
+ public var pivot:Point;
- public function get isArmature():Boolean
+ public function DisplayData()
{
- return _isArmature;
+ transform = new DBTransform();
}
- public function DisplayData()
+ public function dispose():void
{
- pivotX = 0;
- pivotY = 0;
+ transform = null;
+ pivot = null;
}
}
}
\ No newline at end of file
diff --git a/src/dragonBones/objects/Frame.as b/src/dragonBones/objects/Frame.as
new file mode 100644
index 0000000..e4709ab
--- /dev/null
+++ b/src/dragonBones/objects/Frame.as
@@ -0,0 +1,23 @@
+package dragonBones.objects
+{
+ /** @private */
+ public class Frame
+ {
+ public var position:Number;
+ public var duration:Number;
+
+ public var action:String;
+ public var event:String;
+ public var sound:String;
+
+ public function Frame()
+ {
+ position = 0;
+ duration = 0;
+ }
+
+ public function dispose():void
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/FrameData.as b/src/dragonBones/objects/FrameData.as
deleted file mode 100644
index 2e738a9..0000000
--- a/src/dragonBones/objects/FrameData.as
+++ /dev/null
@@ -1,30 +0,0 @@
-package dragonBones.objects
-{
- import flash.geom.ColorTransform;
-
- /** @private */
- final public class FrameData
- {
- public var duration:Number;
- public var tweenEasing:Number;
- public var tweenRotate:int;
- public var displayIndex:int;
- public var movement:String;
- public var visible:Boolean;
- public var event:String;
- public var sound:String;
- public var soundEffect:String;
- public var node:BoneTransform;
- public var colorTransform:ColorTransform;
-
- public function FrameData()
- {
- duration = 0;
- //NaN: no tweens; -1: ease out; 0: linear; 1: ease in; 2: ease in&out
- tweenEasing = 0;
- node = new BoneTransform();
- colorTransform = new ColorTransform();
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/MovementBoneData.as b/src/dragonBones/objects/MovementBoneData.as
deleted file mode 100644
index 943f0e4..0000000
--- a/src/dragonBones/objects/MovementBoneData.as
+++ /dev/null
@@ -1,42 +0,0 @@
-package dragonBones.objects
-{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
-
- /** @private */
- public class MovementBoneData
- {
- dragonBones_internal static const HIDE_DATA:MovementBoneData = new MovementBoneData();
-
- dragonBones_internal var _frameList:Vector.;
-
- public var scale:Number;
- public var delay:Number;
-
- public function MovementBoneData()
- {
- scale = 1;
- delay = 0;
-
- _frameList = new Vector.;
- }
-
- public function dispose():void
- {
- _frameList.length = 0;
- }
-
- public function setValues(scale:Number = 1, delay:Number = 0):void
- {
- this.scale = scale > 0?scale:1;
- this.delay = (delay || 0) % 1;
- if (this.delay > 0)
- {
- this.delay -= 1;
- }
- this.delay *= -1;
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/MovementData.as b/src/dragonBones/objects/MovementData.as
deleted file mode 100644
index bf75c43..0000000
--- a/src/dragonBones/objects/MovementData.as
+++ /dev/null
@@ -1,47 +0,0 @@
-package dragonBones.objects
-{
- import dragonBones.utils.dragonBones_internal;
-
- use namespace dragonBones_internal;
-
- /** @private */
- public class MovementData
- {
- dragonBones_internal var _movementBoneDataList:DataList;
- dragonBones_internal var _movementFrameList:Vector.;
-
- public var duration:Number;
- public var durationTo:Number;
- public var durationTween:Number;
- public var loop:Boolean;
- public var tweenEasing:Number;
-
- public function MovementData()
- {
- duration = 0;
- durationTo = 0;
- durationTween = 0;
-
- _movementBoneDataList = new DataList();
- _movementFrameList = new Vector.;
- }
-
- public function dispose():void
- {
- for each(var movementBoneName:String in _movementBoneDataList.dataNames)
- {
- var movementBoneData:MovementBoneData = _movementBoneDataList.getData(movementBoneName) as MovementBoneData;
- movementBoneData.dispose();
- }
-
- _movementBoneDataList.dispose();
- _movementFrameList.length = 0;
- }
-
- public function getMovementBoneData(name:String):MovementBoneData
- {
- return _movementBoneDataList.getData(name) as MovementBoneData;
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/MovementFrameData.as b/src/dragonBones/objects/MovementFrameData.as
deleted file mode 100644
index 3ce0100..0000000
--- a/src/dragonBones/objects/MovementFrameData.as
+++ /dev/null
@@ -1,24 +0,0 @@
-package dragonBones.objects
-{
- /** @private */
- public class MovementFrameData
- {
- public var duration:Number;
- public var movement:String;
- public var event:String;
- public var sound:String;
- public var soundEffect:String;
-
- public function MovementFrameData()
- {
- }
-
- public function setValues(duration:Number, movement:String, event:String, sound:String):void
- {
- this.duration = duration;
- this.movement = movement;
- this.event = event;
- this.sound = sound;
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/objects/ObjectDataParser.as b/src/dragonBones/objects/ObjectDataParser.as
new file mode 100644
index 0000000..ece2cd0
--- /dev/null
+++ b/src/dragonBones/objects/ObjectDataParser.as
@@ -0,0 +1,285 @@
+package dragonBones.objects
+{
+ import dragonBones.core.DragonBones;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.AnimationData;
+ import dragonBones.objects.ArmatureData;
+ import dragonBones.objects.BoneData;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.DisplayData;
+ import dragonBones.objects.Frame;
+ import dragonBones.objects.SkeletonData;
+ import dragonBones.objects.SkinData;
+ import dragonBones.objects.SlotData;
+ import dragonBones.objects.Timeline;
+ import dragonBones.objects.TransformFrame;
+ import dragonBones.objects.TransformTimeline;
+ import dragonBones.utils.ConstValues;
+ import dragonBones.utils.DBDataUtil;
+
+ import flash.geom.ColorTransform;
+ import flash.geom.Point;
+ import flash.geom.Rectangle;
+
+ use namespace dragonBones_internal;
+
+ public final class ObjectDataParser
+ {
+ public static function parseTextureAtlasData(rawData:Object, scale:Number = 1):Object
+ {
+ var textureAtlasData:Object = {};
+ textureAtlasData.__name = rawData[ConstValues.A_NAME];
+ for each (var subTextureObject:Object in rawData[ConstValues.SUB_TEXTURE])
+ {
+ var subTextureName:String = subTextureObject[ConstValues.A_NAME];
+ var subTextureData:Rectangle = new Rectangle();
+ subTextureData.x = int(subTextureObject[ConstValues.A_X]) / scale;
+ subTextureData.y = int(subTextureObject[ConstValues.A_Y]) / scale;
+ subTextureData.width = int(subTextureObject[ConstValues.A_WIDTH]) / scale;
+ subTextureData.height = int(subTextureObject[ConstValues.A_HEIGHT]) / scale;
+ textureAtlasData[subTextureName] = subTextureData;
+ }
+
+ return textureAtlasData;
+ }
+
+ public static function parseSkeletonData(rawData:Object):SkeletonData
+ {
+ if(!rawData)
+ {
+ throw new ArgumentError();
+ }
+
+ var version:String = rawData[ConstValues.A_VERSION];
+ switch (version)
+ {
+ case DragonBones.DATA_VERSION:
+ break;
+ default:
+ throw new Error("Nonsupport version!");
+ }
+
+ var frameRate:uint = int(rawData[ConstValues.A_FRAME_RATE]);
+
+ var data:SkeletonData = new SkeletonData();
+ data.name = rawData[ConstValues.A_NAME];
+
+ for each(var armatureObject:Object in rawData[ConstValues.ARMATURE])
+ {
+ data.addArmatureData(parseArmatureData(armatureObject, data, frameRate));
+ }
+
+ return data;
+ }
+
+ private static function parseArmatureData(armatureObject:Object, data:SkeletonData, frameRate:uint):ArmatureData
+ {
+ var armatureData:ArmatureData = new ArmatureData();
+ armatureData.name = armatureObject[ConstValues.A_NAME];
+
+ for each(var boneObject:Object in armatureObject[ConstValues.BONE])
+ {
+ armatureData.addBoneData(parseBoneData(boneObject));
+ }
+
+ for each(var skinObject:Object in armatureObject[ConstValues.SKIN])
+ {
+ armatureData.addSkinData(parseSkinData(skinObject, data));
+ }
+
+ DBDataUtil.transformArmatureData(armatureData);
+ armatureData.sortBoneDataList();
+
+ for each(var animationObject:Object in armatureObject[ConstValues.ANIMATION])
+ {
+ armatureData.addAnimationData(parseAnimationData(animationObject, armatureData, frameRate));
+ }
+
+ return armatureData;
+ }
+
+ private static function parseBoneData(boneObject:Object):BoneData
+ {
+ var boneData:BoneData = new BoneData();
+ boneData.name = boneObject[ConstValues.A_NAME];
+ boneData.parent = boneObject[ConstValues.A_PARENT];
+ boneData.length = Number(boneObject[ConstValues.A_LENGTH]) || 0;
+
+ parseTransform(boneObject[ConstValues.TRANSFORM], boneData.global);
+ boneData.transform.copy(boneData.global);
+
+ return boneData;
+ }
+
+ private static function parseSkinData(skinObject:Object, data:SkeletonData):SkinData
+ {
+ var skinData:SkinData = new SkinData();
+ skinData.name = skinObject[ConstValues.A_NAME];
+
+ for each(var slotObject:Object in skinObject[ConstValues.SLOT])
+ {
+ skinData.addSlotData(parseSlotData(slotObject, data));
+ }
+
+ return skinData;
+ }
+
+ private static function parseSlotData(slotObject:Object, data:SkeletonData):SlotData
+ {
+ var slotData:SlotData = new SlotData();
+ slotData.name = slotObject[ConstValues.A_NAME];
+ slotData.parent = slotObject[ConstValues.A_PARENT];
+ slotData.zOrder = Number(slotObject[ConstValues.A_Z_ORDER]);
+ for each(var displayObject:Object in slotObject[ConstValues.DISPLAY])
+ {
+ slotData.addDisplayData(parseDisplayData(displayObject, data));
+ }
+
+ return slotData;
+ }
+
+ private static function parseDisplayData(displayObject:Object, data:SkeletonData):DisplayData
+ {
+ var displayData:DisplayData = new DisplayData();
+ displayData.name = displayObject[ConstValues.A_NAME];
+ displayData.type = displayObject[ConstValues.A_TYPE];
+
+ displayData.pivot = data.addSubTexturePivot(
+ 0,
+ 0,
+ displayData.name
+ );
+
+ parseTransform(displayObject[ConstValues.TRANSFORM], displayData.transform, displayData.pivot);
+
+ return displayData;
+ }
+
+ private static function parseAnimationData(animationObject:Object, armatureData:ArmatureData, frameRate:uint):AnimationData
+ {
+ var animationData:AnimationData = new AnimationData();
+ animationData.name = animationObject[ConstValues.A_NAME];
+ animationData.frameRate = frameRate;
+ animationData.loop = int(animationObject[ConstValues.A_LOOP]);
+ animationData.fadeInTime = Number(animationObject[ConstValues.A_FADE_IN_TIME]);
+ animationData.duration = Number(animationObject[ConstValues.A_DURATION]) / frameRate;
+ animationData.scale = Number(animationObject[ConstValues.A_SCALE]);
+ animationData.tweenEasing = Number(animationObject[ConstValues.A_TWEEN_EASING]);
+
+ parseTimeline(animationObject, animationData, parseMainFrame, frameRate);
+
+ var timeline:TransformTimeline;
+ var timelineName:String;
+ for each(var timelineObject:Object in animationObject[ConstValues.TIMELINE])
+ {
+ timeline = parseTransformTimeline(timelineObject, animationData.duration, frameRate);
+ timelineName = timelineObject[ConstValues.A_NAME];
+ animationData.addTimeline(timeline, timelineName);
+ }
+
+ DBDataUtil.addHideTimeline(animationData, armatureData);
+ DBDataUtil.transformAnimationData(animationData, armatureData);
+
+ return animationData;
+ }
+
+ private static function parseTimeline(timelineObject:Object, timeline:Timeline, frameParser:Function, frameRate:uint):void
+ {
+ var position:Number = 0;
+ var frame:Frame;
+ for each(var frameObject:Object in timelineObject[ConstValues.FRAME])
+ {
+ frame = frameParser(frameObject, frameRate);
+ frame.position = position;
+ timeline.addFrame(frame);
+ position += frame.duration;
+ }
+ if(frame)
+ {
+ frame.duration = timeline.duration - frame.position;
+ }
+ }
+
+ private static function parseTransformTimeline(timelineObject:Object, duration:Number, frameRate:uint):TransformTimeline
+ {
+ var timeline:TransformTimeline = new TransformTimeline();
+ timeline.duration = duration;
+
+ parseTimeline(timelineObject, timeline, parseTransformFrame, frameRate);
+
+ timeline.scale = Number(timelineObject[ConstValues.A_SCALE]);
+ timeline.offset = Number(timelineObject[ConstValues.A_OFFSET]);
+
+ return timeline;
+ }
+
+ private static function parseFrame(frameObject:Object, frame:Frame, frameRate:uint):void
+ {
+ frame.duration = Number(frameObject[ConstValues.A_DURATION]) / frameRate;
+ frame.action = frameObject[ConstValues.A_ACTION];
+ frame.event = frameObject[ConstValues.A_EVENT];
+ frame.sound = frameObject[ConstValues.A_SOUND];
+ }
+
+ private static function parseMainFrame(frameObject:Object, frameRate:uint):Frame
+ {
+ var frame:Frame = new Frame();
+ parseFrame(frameObject, frame, frameRate);
+ return frame;
+ }
+
+ private static function parseTransformFrame(frameObject:Object, frameRate:uint):TransformFrame
+ {
+ var frame:TransformFrame = new TransformFrame();
+ parseFrame(frameObject, frame, frameRate);
+
+ frame.visible = uint(frameObject[ConstValues.A_HIDE]) != 1;
+ frame.tweenEasing = Number(frameObject[ConstValues.A_TWEEN_EASING]);
+ frame.tweenRotate = Number(frameObject[ConstValues.A_TWEEN_ROTATE]);
+ frame.displayIndex = Number(frameObject[ConstValues.A_DISPLAY_INDEX]);
+ //
+ frame.zOrder = Number(frameObject[ConstValues.A_Z_ORDER]);
+
+ parseTransform(frameObject[ConstValues.TRANSFORM], frame.global, frame.pivot);
+ frame.transform.copy(frame.global);
+
+ var colorTransformObject:Object = frameObject[ConstValues.COLOR_TRANSFORM];
+ if(colorTransformObject)
+ {
+ frame.color = new ColorTransform();
+ frame.color.alphaOffset = Number(colorTransformObject[ConstValues.A_ALPHA_OFFSET]);
+ frame.color.redOffset = Number(colorTransformObject[ConstValues.A_RED_OFFSET]);
+ frame.color.greenOffset = Number(colorTransformObject[ConstValues.A_GREEN_OFFSET]);
+ frame.color.blueOffset = Number(colorTransformObject[ConstValues.A_BLUE_OFFSET]);
+
+ frame.color.alphaMultiplier = Number(colorTransformObject[ConstValues.A_ALPHA_MULTIPLIER]) * 0.01;
+ frame.color.redMultiplier = Number(colorTransformObject[ConstValues.A_RED_MULTIPLIER]) * 0.01;
+ frame.color.greenMultiplier = Number(colorTransformObject[ConstValues.A_GREEN_MULTIPLIER]) * 0.01;
+ frame.color.blueMultiplier = Number(colorTransformObject[ConstValues.A_BLUE_MULTIPLIER]) * 0.01;
+ }
+
+ return frame;
+ }
+
+ private static function parseTransform(transformObject:Object, transform:DBTransform, pivot:Point = null):void
+ {
+ if(transformObject)
+ {
+ if(transform)
+ {
+ transform.x = Number(transformObject[ConstValues.A_X]);
+ transform.y = Number(transformObject[ConstValues.A_Y]);
+ transform.skewX = Number(transformObject[ConstValues.A_SKEW_X]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.skewY = Number(transformObject[ConstValues.A_SKEW_Y]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.scaleX = Number(transformObject[ConstValues.A_SCALE_X]);
+ transform.scaleY = Number(transformObject[ConstValues.A_SCALE_Y]);
+ }
+ if(pivot)
+ {
+ pivot.x = Number(transformObject[ConstValues.A_PIVOT_X]);
+ pivot.y = Number(transformObject[ConstValues.A_PIVOT_Y]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/SkeletonData.as b/src/dragonBones/objects/SkeletonData.as
index 5c00d07..00bcfca 100644
--- a/src/dragonBones/objects/SkeletonData.as
+++ b/src/dragonBones/objects/SkeletonData.as
@@ -1,140 +1,140 @@
-package dragonBones.objects
+package dragonBones.objects
{
- /**
- * Copyright 2012-2013. DragonBones. All Rights Reserved.
- * @playerversion Flash 10.0, Flash 10
- * @langversion 3.0
- * @version 2.0
- */
- import dragonBones.utils.dragonBones_internal;
- use namespace dragonBones_internal;
-
+ import flash.geom.Point;
-
- /**
- * A SkeletonData instance holds all data related to an Armature instance.
- * @example
- * Download the example files here:
- * This example parse the 'Dragon1.swf' data and stores its SkeletonData into the local variable named skeleton.
- *
- * package
- * {
- * import dragonBones.Armature;
- * import dragonBones.factorys.BaseFactory;
- * import flash.display.Sprite;
- * import flash.events.Event;
- * import dragonBones.objects.SkeletonData;
- *
- * public class DragonAnimation extends Sprite
- * {
- * [Embed(source = "Dragon1.swf", mimeType = "application/octet-stream")]
- * private static const ResourcesData:Class;
- *
- * private var factory:BaseFactory;
- * private var armature:Armature;
- *
- * public function DragonAnimation()
- * {
- * factory = new BaseFactory();
- * factory.addEventListener(Event.COMPLETE, handleParseData);
- * var skeleton:SkeletonData = factory.parseData(new ResourcesData(), 'Dragon');
- * }
- * }
- * }
- *
- * @see dragonBones.Bone
- * @see dragonBones.animation.Animation
- */
public class SkeletonData
{
- dragonBones_internal var _armatureDataList:DataList;
- dragonBones_internal var _animationDataList:DataList;
- dragonBones_internal var _displayDataList:DataList;
- dragonBones_internal var _name:String;
- /**
- * the name of this Skeletondata instance.
- */
- public function get name():String
- {
- return _name;
- }
+ public var name:String;
+
+ private var _subTexturePivots:Object;
- dragonBones_internal var _frameRate:uint;
- /**
- * The frameRate of this Skeltondata instance.
- */
- public function get frameRate():uint
- {
- return _frameRate;
- }
- /**
- * All Armature instance names belonging to this Skeletondata instance.
- */
public function get armatureNames():Vector.
{
- return _armatureDataList.dataNames.concat();
+ var nameList:Vector. = new Vector.;
+ for each(var armatureData:ArmatureData in _armatureDataList)
+ {
+ nameList[nameList.length] = armatureData.name;
+ }
+ return nameList;
}
- /**
- * All Animation instance names belonging to this Skeletondata instance.
- */
- public function get animationNames():Vector.
+
+ private var _armatureDataList:Vector.;
+ public function get armatureDataList():Vector.
{
- return _animationDataList.dataNames.concat();
+ return _armatureDataList;
}
- /**
- * Creates a new SkeletonData instance.
- */
+
public function SkeletonData()
{
- _armatureDataList = new DataList();
- _animationDataList = new DataList();
- _displayDataList = new DataList();
+ _armatureDataList = new Vector.(0, true);
+ _subTexturePivots = {};
}
- /**
- * Clean up all resources used by this SkeletonData instance.
- */
+
public function dispose():void
{
- for each (var armatureName:String in _armatureDataList.dataNames)
+ for each(var armatureData:ArmatureData in _armatureDataList)
{
- var armatureData:ArmatureData = _armatureDataList.getData(armatureName) as ArmatureData;
armatureData.dispose();
}
- for each (var animationName:String in _animationDataList.dataNames)
+ _armatureDataList.fixed = false;
+ _armatureDataList.length = 0;
+
+ _armatureDataList = null;
+ _subTexturePivots = null;
+ }
+
+ public function getArmatureData(armatureName:String):ArmatureData
+ {
+ var i:int = _armatureDataList.length;
+ while(i --)
{
- var animationData:AnimationData = _animationDataList.getData(animationName) as AnimationData;
- animationData.dispose();
+ if(_armatureDataList[i].name == armatureName)
+ {
+ return _armatureDataList[i];
+ }
}
- _armatureDataList.dispose();
- _animationDataList.dispose();
- _displayDataList.dispose();
+
+ return null;
}
- /**
- * Get the ArmatureData instance with this name.
- * @param name The name of the ArmatureData instance to retreive.
- * @return ArmatureData The ArmatureData instance by that name.
- */
- public function getArmatureData(name:String):ArmatureData
+
+ public function addArmatureData(armatureData:ArmatureData):void
{
- return _armatureDataList.getData(name) as ArmatureData;
+ if(!armatureData)
+ {
+ throw new ArgumentError();
+ }
+
+ if(_armatureDataList.indexOf(armatureData) < 0)
+ {
+ _armatureDataList.fixed = false;
+ _armatureDataList[_armatureDataList.length] = armatureData;
+ _armatureDataList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
}
- /**
- * Get the AnimationData instance with this name.
- * @param name The name of the AnimationData instance to retreive.
- * @return AnimationData The AnimationData instance by that name.
- */
- public function getAnimationData(name:String):AnimationData
+
+ public function removeArmatureData(armatureData:ArmatureData):void
{
- return _animationDataList.getData(name) as AnimationData;
+ var index:int = _armatureDataList.indexOf(armatureData);
+ if(index >= 0)
+ {
+ _armatureDataList.fixed = false;
+ _armatureDataList.splice(index, 1);
+ _armatureDataList.fixed = true;
+ }
}
- /**
- * Get the DisplayData instance with this name.
- * @param name The name of the DisplayData instance to retreive.
- * @return AnimationData The DisplayData instance by that name.
- */
- public function getDisplayData(name:String):DisplayData
+
+ public function removeArmatureDataByName(armatureName:String):void
{
- return _displayDataList.getData(name) as DisplayData;
+ var i:int = _armatureDataList.length;
+ while(i --)
+ {
+ if(_armatureDataList[i].name == armatureName)
+ {
+ _armatureDataList.fixed = false;
+ _armatureDataList.splice(i, 1);
+ _armatureDataList.fixed = true;
+ }
+ }
+ }
+
+ public function getSubTexturePivot(subTextureName:String):Point
+ {
+ return _subTexturePivots[subTextureName];
+ }
+
+ public function addSubTexturePivot(x:Number, y:Number, subTextureName:String):Point
+ {
+ var point:Point = _subTexturePivots[subTextureName];
+ if(point)
+ {
+ point.x = x;
+ point.y = y;
+ }
+ else
+ {
+ _subTexturePivots[subTextureName] = point = new Point(x, y);
+ }
+
+ return point;
+ }
+
+ public function removeSubTexturePivot(subTextureName:String):void
+ {
+ if(subTextureName)
+ {
+ delete _subTexturePivots[subTextureName];
+ }
+ else
+ {
+ for(subTextureName in _subTexturePivots)
+ {
+ delete _subTexturePivots[subTextureName];
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/src/dragonBones/objects/SkinData.as b/src/dragonBones/objects/SkinData.as
new file mode 100644
index 0000000..e29766b
--- /dev/null
+++ b/src/dragonBones/objects/SkinData.as
@@ -0,0 +1,63 @@
+package dragonBones.objects
+{
+ /** @private */
+ final public class SkinData
+ {
+ public var name:String;
+
+ private var _slotDataList:Vector.;
+ public function get slotDataList():Vector.
+ {
+ return _slotDataList;
+ }
+
+ public function SkinData()
+ {
+ _slotDataList = new Vector.(0, true);
+ }
+
+ public function dispose():void
+ {
+ var i:int = _slotDataList.length;
+ while(i --)
+ {
+ _slotDataList[i].dispose();
+ }
+ _slotDataList.fixed = false;
+ _slotDataList.length = 0;
+ _slotDataList = null;
+ }
+
+ public function getSlotData(slotName:String):SlotData
+ {
+ var i:int = _slotDataList.length;
+ while(i --)
+ {
+ if(_slotDataList[i].name == slotName)
+ {
+ return _slotDataList[i];
+ }
+ }
+ return null;
+ }
+
+ public function addSlotData(slotData:SlotData):void
+ {
+ if(!slotData)
+ {
+ throw new ArgumentError();
+ }
+
+ if (_slotDataList.indexOf(slotData) < 0)
+ {
+ _slotDataList.fixed = false;
+ _slotDataList[_slotDataList.length] = slotData;
+ _slotDataList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/SlotData.as b/src/dragonBones/objects/SlotData.as
new file mode 100644
index 0000000..fa16ed8
--- /dev/null
+++ b/src/dragonBones/objects/SlotData.as
@@ -0,0 +1,66 @@
+package dragonBones.objects
+{
+ /** @private */
+ public final class SlotData
+ {
+ public var name:String;
+ public var parent:String;
+ public var zOrder:Number;
+
+ private var _displayDataList:Vector.;
+ public function get displayDataList():Vector.
+ {
+ return _displayDataList;
+ }
+
+ public function SlotData()
+ {
+ _displayDataList = new Vector.(0, true);
+ zOrder = 0;
+ }
+
+ public function dispose():void
+ {
+ var i:int = _displayDataList.length;
+ while(i --)
+ {
+ _displayDataList[i].dispose();
+ }
+ _displayDataList.fixed = false;
+ _displayDataList.length = 0;
+ _displayDataList = null;
+ }
+
+ public function addDisplayData(displayData:DisplayData):void
+ {
+ if(!displayData)
+ {
+ throw new ArgumentError();
+ }
+ if (_displayDataList.indexOf(displayData) < 0)
+ {
+ _displayDataList.fixed = false;
+ _displayDataList[_displayDataList.length] = displayData;
+ _displayDataList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+
+ public function getDisplayData(displayName:String):DisplayData
+ {
+ var i:int = _displayDataList.length;
+ while(i --)
+ {
+ if(_displayDataList[i].name == displayName)
+ {
+ return _displayDataList[i];
+ }
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/Timeline.as b/src/dragonBones/objects/Timeline.as
new file mode 100644
index 0000000..7efb7f0
--- /dev/null
+++ b/src/dragonBones/objects/Timeline.as
@@ -0,0 +1,70 @@
+package dragonBones.objects
+{
+ public class Timeline
+ {
+ private var _frameList:Vector.;
+ public function get frameList():Vector.
+ {
+ return _frameList;
+ }
+
+ private var _duration:Number;
+ public function get duration():Number
+ {
+ return _duration;
+ }
+ public function set duration(value:Number):void
+ {
+ _duration = value >= 0?value:0;
+ }
+
+ private var _scale:Number;
+ public function get scale():Number
+ {
+ return _scale;
+ }
+ public function set scale(value:Number):void
+ {
+ _scale = value >= 0?value:1;
+ }
+
+ public function Timeline()
+ {
+ _frameList = new Vector.(0, true);
+ _duration = 0;
+ _scale = 1;
+ }
+
+ public function dispose():void
+ {
+ var i:int = _frameList.length;
+ while(i --)
+ {
+ _frameList[i].dispose();
+ }
+ _frameList.fixed = false;
+ _frameList.length = 0;
+ _frameList = null;
+ }
+
+ public function addFrame(frame:Frame):void
+ {
+ if(!frame)
+ {
+ throw new ArgumentError();
+ }
+
+ if(_frameList.indexOf(frame) < 0)
+ {
+ _frameList.fixed = false;
+ _frameList[_frameList.length] = frame;
+ _frameList.fixed = true;
+ }
+ else
+ {
+ throw new ArgumentError();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/TransformFrame.as b/src/dragonBones/objects/TransformFrame.as
new file mode 100644
index 0000000..4b84527
--- /dev/null
+++ b/src/dragonBones/objects/TransformFrame.as
@@ -0,0 +1,47 @@
+package dragonBones.objects
+{
+ import flash.geom.ColorTransform;
+ import flash.geom.Point;
+
+ /** @private */
+ final public class TransformFrame extends Frame
+ {
+ public var tweenEasing:Number;
+ public var tweenRotate:int;
+ public var displayIndex:int;
+ public var visible:Boolean;
+ public var zOrder:Number;
+
+ public var global:DBTransform;
+ public var transform:DBTransform;
+ public var pivot:Point;
+ public var color:ColorTransform;
+
+
+ public function TransformFrame()
+ {
+ super();
+
+ tweenEasing = 0;
+ tweenRotate = 0;
+ displayIndex = 0;
+ visible = true;
+ zOrder = NaN;
+
+ global = new DBTransform();
+ transform = new DBTransform();
+ pivot = new Point();
+ }
+
+ override public function dispose():void
+ {
+ super.dispose();
+ global = null;
+ transform = null;
+ //SkeletonData pivots
+ pivot = null;
+ color = null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/TransformTimeline.as b/src/dragonBones/objects/TransformTimeline.as
new file mode 100644
index 0000000..57eca8e
--- /dev/null
+++ b/src/dragonBones/objects/TransformTimeline.as
@@ -0,0 +1,48 @@
+package dragonBones.objects
+{
+ import flash.geom.Point;
+
+ public final class TransformTimeline extends Timeline
+ {
+ public static const HIDE_TIMELINE:TransformTimeline = new TransformTimeline();
+
+ public var transformed:Boolean;
+
+ public var originTransform:DBTransform;
+ public var originPivot:Point;
+
+ private var _offset:Number;
+ public function get offset():Number
+ {
+ return _offset;
+ }
+ public function set offset(value:Number):void
+ {
+ _offset = (value || 0) % 1;
+ if(_offset < 0)
+ {
+ _offset += 1;
+ }
+ }
+
+ public function TransformTimeline()
+ {
+ super();
+
+ originTransform = new DBTransform();
+ originPivot = new Point();
+ _offset = 0;
+ }
+
+ override public function dispose():void
+ {
+ if(this == HIDE_TIMELINE)
+ {
+ return;
+ }
+ super.dispose();
+ originTransform = null;
+ originPivot = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/objects/XMLDataParser.as b/src/dragonBones/objects/XMLDataParser.as
index cef6938..784868f 100644
--- a/src/dragonBones/objects/XMLDataParser.as
+++ b/src/dragonBones/objects/XMLDataParser.as
@@ -6,488 +6,303 @@
* @langversion 3.0
* @version 2.0
*/
- import dragonBones.animation.Tween;
- import dragonBones.errors.UnknownDataError;
- import dragonBones.utils.BytesType;
+
+ import dragonBones.core.DragonBones;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.AnimationData;
+ import dragonBones.objects.ArmatureData;
+ import dragonBones.objects.BoneData;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.DisplayData;
+ import dragonBones.objects.Frame;
+ import dragonBones.objects.SkeletonData;
+ import dragonBones.objects.SkinData;
+ import dragonBones.objects.SlotData;
+ import dragonBones.objects.Timeline;
+ import dragonBones.objects.TransformFrame;
+ import dragonBones.objects.TransformTimeline;
import dragonBones.utils.ConstValues;
- import dragonBones.utils.TransformUtils;
- import dragonBones.utils.dragonBones_internal;
+ import dragonBones.utils.DBDataUtil;
+ import dragonBones.utils.parseOldXMLData;
+
import flash.geom.ColorTransform;
- import flash.utils.ByteArray;
+ import flash.geom.Point;
+ import flash.geom.Rectangle;
+
use namespace dragonBones_internal;
+
/**
- * The XMLDataParser xlass creates and parses xml data from dragonBones generated maps.
+ * The XMLDataParser class parses xml data from dragonBones generated maps.
*/
- public class XMLDataParser
+ final public class XMLDataParser
{
- private static const ANGLE_TO_RADIAN:Number = Math.PI / 180;
- private static const HALF_PI:Number = Math.PI * 0.5;
- private static var _currentSkeletonData:SkeletonData;
- private static var _helpNode:BoneTransform = new BoneTransform();
- private static var _helpFrameData:FrameData = new FrameData();
+ public static function parseTextureAtlasData(rawData:XML, scale:Number = 1):Object
+ {
+ var textureAtlasData:Object = {};
+ textureAtlasData.__name = rawData.@[ConstValues.A_NAME];
+ for each (var subTextureXML:XML in rawData[ConstValues.SUB_TEXTURE])
+ {
+ var subTextureName:String = subTextureXML.@[ConstValues.A_NAME];
+ var subTextureData:Rectangle = new Rectangle();
+ subTextureData.x = int(subTextureXML.@[ConstValues.A_X]) / scale;
+ subTextureData.y = int(subTextureXML.@[ConstValues.A_Y]) / scale;
+ subTextureData.width = int(subTextureXML.@[ConstValues.A_WIDTH]) / scale;
+ subTextureData.height = int(subTextureXML.@[ConstValues.A_HEIGHT]) / scale;
+
+ textureAtlasData[subTextureName] = subTextureData;
+ }
+
+ return textureAtlasData;
+ }
- private static function checkSkeletonXMLVersion(skeletonXML:XML):void
+ /**
+ * Parse the SkeletonData.
+ * @param xml The SkeletonData xml to parse.
+ * @return A SkeletonData instance.
+ */
+ public static function parseSkeletonData(rawData:XML):SkeletonData
{
- var version:String = skeletonXML.attribute(ConstValues.A_VERSION);
+ if(!rawData)
+ {
+ throw new ArgumentError();
+ }
+ var version:String = rawData.@[ConstValues.A_VERSION];
switch (version)
{
- case "1.4":
case "1.5":
case "2.0":
case "2.1":
case "2.1.1":
case "2.1.2":
- case ConstValues.VERSION:
+ case "2.2":
+ return parseOldXMLData(rawData as XML);
+ case DragonBones.DATA_VERSION:
break;
- default:
- throw new Error("Nonsupport data version!");
+ default:
+ throw new Error("Nonsupport version!");
}
- }
-
- /** @private */
- public static function getElementsByAttribute(xmlList:XMLList, attribute:String, value:String):XMLList
- {
- var result:XMLList = new XMLList();
- var length:uint = xmlList.length();
- for (var i:int = 0; i < length; i++)
+
+ var frameRate:uint = int(rawData.@[ConstValues.A_FRAME_RATE]);
+
+ var data:SkeletonData = new SkeletonData();
+ data.name = rawData.@[ConstValues.A_NAME];
+ for each(var armatureXML:XML in rawData[ConstValues.ARMATURE])
{
- var xml:XML = xmlList[i];
- if (xml.@[attribute].toString() == value)
- {
- result[result.length()] = xmlList[i];
- }
+ data.addArmatureData(parseArmatureData(armatureXML, data, frameRate));
}
- return result;
- }
- /**
- * Compress all data into a ByteArray for serialization.
- * @param skeletonXML The Skeleton data.
- * @param textureAtlasXML The TextureAtlas data.
- * @param byteArray The ByteArray representing the map.
- * @return ByteArray. A DragonBones compatible ByteArray.
- */
- public static function compressData(skeletonXML:XML, textureAtlasXML:XML, byteArray:ByteArray):ByteArray
- {
- var byteArrayCopy:ByteArray = new ByteArray();
- byteArrayCopy.writeBytes(byteArray);
- var xmlBytes:ByteArray = new ByteArray();
- xmlBytes.writeUTFBytes(textureAtlasXML.toXMLString());
- xmlBytes.compress();
- byteArrayCopy.position = byteArrayCopy.length;
- byteArrayCopy.writeBytes(xmlBytes);
- byteArrayCopy.writeInt(xmlBytes.length);
- xmlBytes.length = 0;
- xmlBytes.writeUTFBytes(skeletonXML.toXMLString());
- xmlBytes.compress();
- byteArrayCopy.position = byteArrayCopy.length;
- byteArrayCopy.writeBytes(xmlBytes);
- byteArrayCopy.writeInt(xmlBytes.length);
- return byteArrayCopy;
+
+ return data;
}
- /**
- * Decompress a compatible DragonBones data.
- * @param compressedByteArray The ByteArray to decompress.
- * @return A DecompressedData instance.
- */
- public static function decompressData(compressedByteArray:ByteArray):DecompressedData
+
+ private static function parseArmatureData(armatureXML:XML, data:SkeletonData, frameRate:uint):ArmatureData
{
- var dataType:String = BytesType.getType(compressedByteArray);
- switch (dataType)
+ var armatureData:ArmatureData = new ArmatureData();
+ armatureData.name = armatureXML.@[ConstValues.A_NAME];
+
+ for each(var boneXML:XML in armatureXML[ConstValues.BONE])
{
- case BytesType.SWF:
- case BytesType.PNG:
- case BytesType.JPG:
- try
- {
- compressedByteArray.position = compressedByteArray.length - 4;
- var strSize:int = compressedByteArray.readInt();
- var position:uint = compressedByteArray.length - 4 - strSize;
- var xmlBytes:ByteArray = new ByteArray();
- xmlBytes.writeBytes(compressedByteArray, position, strSize);
- xmlBytes.uncompress();
- compressedByteArray.length = position;
- var skeletonXML:XML = XML(xmlBytes.readUTFBytes(xmlBytes.length));
- compressedByteArray.position = compressedByteArray.length - 4;
- strSize = compressedByteArray.readInt();
- position = compressedByteArray.length - 4 - strSize;
- xmlBytes.length = 0;
- xmlBytes.writeBytes(compressedByteArray, position, strSize);
- xmlBytes.uncompress();
- compressedByteArray.length = position;
- var textureAtlasXML:XML = XML(xmlBytes.readUTFBytes(xmlBytes.length));
- }
- catch (e:Error)
- {
- throw new Error("Decompress error!");
- }
- var decompressedData:DecompressedData = new DecompressedData(skeletonXML, textureAtlasXML, compressedByteArray);
- return decompressedData;
- case BytesType.ZIP:
- throw new Error("Can not decompress zip!");
- default:
- throw new UnknownDataError();
+ armatureData.addBoneData(parseBoneData(boneXML));
}
- return null;
- }
- /**
- * Parse the SkeletonData.
- * @param skeletonXML The Skeleton xml to parse.
- * @return A SkeletonData instance.
- */
- public static function parseSkeletonData(skeletonXML:XML):SkeletonData
- {
- checkSkeletonXMLVersion(skeletonXML);
- var skeletonData:SkeletonData = new SkeletonData();
- skeletonData._name = skeletonXML.attribute(ConstValues.A_NAME);
- skeletonData._frameRate = int(skeletonXML.attribute(ConstValues.A_FRAME_RATE));
- _currentSkeletonData = skeletonData;
- for each (var armatureXML:XML in skeletonXML.elements(ConstValues.ARMATURES).elements(ConstValues.ARMATURE))
+
+ for each(var skinXML:XML in armatureXML[ConstValues.SKIN])
{
- var armatureName:String = armatureXML.attribute(ConstValues.A_NAME);
- var armatureData:ArmatureData = skeletonData.getArmatureData(armatureName);
- if (armatureData)
- {
- parseArmatureData(armatureXML, armatureData);
- }
- else
- {
- armatureData = new ArmatureData();
- parseArmatureData(armatureXML, armatureData);
- skeletonData._armatureDataList.addData(armatureData, armatureName);
- }
+ armatureData.addSkinData(parseSkinData(skinXML, data));
}
- for each (var animationXML:XML in skeletonXML.elements(ConstValues.ANIMATIONS).elements(ConstValues.ANIMATION))
+ DBDataUtil.transformArmatureData(armatureData);
+ armatureData.sortBoneDataList();
+
+ for each(var animationXML:XML in armatureXML[ConstValues.ANIMATION])
{
- var animationName:String = animationXML.attribute(ConstValues.A_NAME);
- armatureData = skeletonData.getArmatureData(animationName);
- var animationData:AnimationData = skeletonData.getAnimationData(animationName);
- if (animationData)
- {
- parseAnimationData(animationXML, animationData, armatureData);
- }
- else
- {
- animationData = new AnimationData();
- parseAnimationData(animationXML, animationData, armatureData);
- skeletonData._animationDataList.addData(animationData, animationName);
- }
+ armatureData.addAnimationData(parseAnimationData(animationXML, armatureData, frameRate));
}
- _currentSkeletonData = null;
- return skeletonData;
+
+ return armatureData;
}
- private static function parseArmatureData(armatureXML:XML, armatureData:ArmatureData):void
+ private static function parseBoneData(boneXML:XML):BoneData
{
- var boneXMLList:XMLList = armatureXML.elements(ConstValues.BONE);
- for each (var boneXML:XML in boneXMLList)
- {
- var boneName:String = boneXML.attribute(ConstValues.A_NAME);
- var parentName:String = boneXML.attribute(ConstValues.A_PARENT);
- var parentXML:XML = getElementsByAttribute(boneXMLList, ConstValues.A_NAME, parentName)[0];
- var boneData:BoneData = armatureData.getBoneData(boneName);
- if (boneData)
- {
- parseBoneData(boneXML, parentXML, boneData);
- }
- else
- {
- boneData = new BoneData();
- parseBoneData(boneXML, parentXML, boneData);
- armatureData._boneDataList.addData(boneData, boneName);
- }
- }
+ var boneData:BoneData = new BoneData();
+ boneData.name = boneXML.@[ConstValues.A_NAME];
+ boneData.parent = boneXML.@[ConstValues.A_PARENT];
+ boneData.length = Number(boneXML.@[ConstValues.A_LENGTH]);
- armatureData.updateBoneList();
+ parseTransform(boneXML[ConstValues.TRANSFORM][0], boneData.global);
+ boneData.transform.copy(boneData.global);
+
+ return boneData;
}
- /** @private */
- dragonBones_internal static function parseBoneData(boneXML:XML, parentXML:XML, boneData:BoneData):void
+ private static function parseSkinData(skinXML:XML, data:SkeletonData):SkinData
{
- parseNode(boneXML, boneData.node);
- if (parentXML)
- {
- boneData._parent = parentXML.attribute(ConstValues.A_NAME);
- parseNode(parentXML, _helpNode);
- TransformUtils.transformPointWithParent(boneData.node, _helpNode);
- }
- else
+ var skinData:SkinData = new SkinData();
+ skinData.name = skinXML.@[ConstValues.A_NAME];
+
+ for each(var slotXML:XML in skinXML[ConstValues.SLOT])
{
- boneData._parent = null;
+ skinData.addSlotData(parseSlotData(slotXML, data));
}
- if (_currentSkeletonData)
+
+ return skinData;
+ }
+
+ private static function parseSlotData(slotXML:XML, data:SkeletonData):SlotData
+ {
+ var slotData:SlotData = new SlotData();
+ slotData.name = slotXML.@[ConstValues.A_NAME];
+ slotData.parent = slotXML.@[ConstValues.A_PARENT];
+ slotData.zOrder = Number(slotXML.@[ConstValues.A_Z_ORDER]);
+ for each(var displayXML:XML in slotXML[ConstValues.DISPLAY])
{
- var displayXMLList:XMLList = boneXML.elements(ConstValues.DISPLAY);
- var length:uint = displayXMLList.length();
- for (var i:int = 0; i < length; i++)
- {
- var displayXML:XML = displayXMLList[i];
- var displayName:String = displayXML.attribute(ConstValues.A_NAME);
- boneData._displayNames[i] = displayName;
- var displayData:DisplayData = _currentSkeletonData.getDisplayData(displayName);
- if (displayData)
- {
- parseDisplayData(displayXML, displayData);
- }
- else
- {
- displayData = new DisplayData();
- parseDisplayData(displayXML, displayData);
- _currentSkeletonData._displayDataList.addData(displayData, displayName);
- }
- }
+ slotData.addDisplayData(parseDisplayData(displayXML, data));
}
+
+ return slotData;
}
- private static function parseDisplayData(displayXML:XML, displayData:DisplayData):void
+ private static function parseDisplayData(displayXML:XML, data:SkeletonData):DisplayData
{
- displayData._isArmature = Boolean(int(displayXML.attribute(ConstValues.A_IS_ARMATURE)));
- displayData.pivotX = Number(displayXML.attribute(ConstValues.A_PIVOT_X));
- displayData.pivotY = Number(displayXML.attribute(ConstValues.A_PIVOT_Y));
+ var displayData:DisplayData = new DisplayData();
+ displayData.name = displayXML.@[ConstValues.A_NAME];
+ displayData.type = displayXML.@[ConstValues.A_TYPE];
+
+ displayData.pivot = data.addSubTexturePivot(
+ 0,
+ 0,
+ displayData.name
+ );
+
+ parseTransform(displayXML[ConstValues.TRANSFORM][0], displayData.transform, displayData.pivot);
+
+ return displayData;
}
/** @private */
- dragonBones_internal static function parseAnimationData(animationXML:XML, animationData:AnimationData, armatureData:ArmatureData):void
+ dragonBones_internal static function parseAnimationData(animationXML:XML, armatureData:ArmatureData, frameRate:uint):AnimationData
{
- for each (var movementXML:XML in animationXML.elements(ConstValues.MOVEMENT))
+ var animationData:AnimationData = new AnimationData();
+ animationData.name = animationXML.@[ConstValues.A_NAME];
+ animationData.frameRate = frameRate;
+ animationData.loop = int(animationXML.@[ConstValues.A_LOOP]);
+ animationData.fadeInTime = Number(animationXML.@[ConstValues.A_FADE_IN_TIME]);
+ animationData.duration = Number(animationXML.@[ConstValues.A_DURATION]) / frameRate;
+ animationData.scale = Number(animationXML.@[ConstValues.A_SCALE]);
+ animationData.tweenEasing = Number(animationXML.@[ConstValues.A_TWEEN_EASING]);
+
+ parseTimeline(animationXML, animationData, parseMainFrame, frameRate);
+
+ var timeline:TransformTimeline;
+ var timelineName:String;
+ for each(var timelineXML:XML in animationXML[ConstValues.TIMELINE])
{
- var movementName:String = movementXML.attribute(ConstValues.A_NAME);
- var movementData:MovementData = animationData.getMovementData(movementName);
- if (movementData)
- {
- parseMovementData(movementXML, armatureData, movementData);
- }
- else
- {
- movementData = new MovementData();
- parseMovementData(movementXML, armatureData, movementData);
- animationData._movementDataList.addData(movementData, movementName);
- }
+ timeline = parseTransformTimeline(timelineXML, animationData.duration, frameRate);
+ timelineName = timelineXML.@[ConstValues.A_NAME];
+ animationData.addTimeline(timeline, timelineName);
}
+
+ DBDataUtil.addHideTimeline(animationData, armatureData);
+ DBDataUtil.transformAnimationData(animationData, armatureData);
+
+ return animationData;
}
- private static function parseMovementData(movementXML:XML, armatureData:ArmatureData, movementData:MovementData):void
+ private static function parseTimeline(timelineXML:XML, timeline:Timeline, frameParser:Function, frameRate:uint):void
{
- if (_currentSkeletonData)
+ var position:Number = 0;
+ var frame:Frame;
+ for each(var frameXML:XML in timelineXML[ConstValues.FRAME])
{
- var frameRate:uint = _currentSkeletonData._frameRate;
- var duration:int = int(movementXML.attribute(ConstValues.A_DURATION));
- movementData.duration = (duration > 1) ? (duration / frameRate) : 0;
- movementData.durationTo = int(movementXML.attribute(ConstValues.A_DURATION_TO)) / frameRate;
- movementData.durationTween = int(movementXML.attribute(ConstValues.A_DURATION_TWEEN)) / frameRate;
- movementData.loop = Boolean(int(movementXML.attribute(ConstValues.A_LOOP)) == 1);
- movementData.tweenEasing = Number(movementXML.attribute(ConstValues.A_TWEEN_EASING)[0]);
+ frame = frameParser(frameXML, frameRate);
+ frame.position = position;
+ timeline.addFrame(frame);
+ position += frame.duration;
}
- var boneNames:Vector. = armatureData.boneNames;
- var movementBoneXMLList:XMLList = movementXML.elements(ConstValues.BONE);
- for each (var movementBoneXML:XML in movementBoneXMLList)
+ if(frame)
{
- var boneName:String = movementBoneXML.attribute(ConstValues.A_NAME);
- var boneData:BoneData = armatureData.getBoneData(boneName);
- var parentMovementBoneXML:XML = getElementsByAttribute(movementBoneXMLList, ConstValues.A_NAME, boneData.parent)[0];
- var movementBoneData:MovementBoneData = movementData.getMovementBoneData(boneName);
- if (movementBoneXML)
- {
- if (movementBoneData)
- {
- parseMovementBoneData(movementBoneXML, parentMovementBoneXML, boneData, movementBoneData);
- }
- else
- {
- movementBoneData = new MovementBoneData();
- parseMovementBoneData(movementBoneXML, parentMovementBoneXML, boneData, movementBoneData);
- movementData._movementBoneDataList.addData(movementBoneData, boneName);
- }
- }
- var index:int = boneNames.indexOf(boneName);
- if (index >= 0)
- {
- boneNames.splice(index, 1);
- }
- }
- for each (boneName in boneNames)
- {
- movementData._movementBoneDataList.addData(MovementBoneData.HIDE_DATA, boneName);
- }
- var movementFrameXMLList:XMLList = movementXML.elements(ConstValues.FRAME);
- var length:uint = movementFrameXMLList.length();
- var movementFrameList:Vector. = movementData._movementFrameList;
- for (var i:int = 0; i < length; i++)
- {
- var movementFrameXML:XML = movementFrameXMLList[i];
- var movementFrameData:MovementFrameData = movementFrameList.length > i ? movementFrameList[i] : null;
- if (movementFrameData)
- {
- parseMovementFrameData(movementFrameXML, movementFrameData);
- }
- else
- {
- movementFrameData = new MovementFrameData();
- parseMovementFrameData(movementFrameXML, movementFrameData)
- if (movementFrameList.indexOf(movementFrameData) < 0)
- {
- movementFrameList.push(movementFrameData);
- }
- }
+ frame.duration = timeline.duration - frame.position;
}
}
- private static function parseMovementBoneData(movementBoneXML:XML, parentMovementBoneXML:XML, boneData:BoneData, movementBoneData:MovementBoneData):void
+ private static function parseTransformTimeline(timelineXML:XML, duration:Number, frameRate:uint):TransformTimeline
{
- movementBoneData.setValues(
- Number(movementBoneXML.attribute(ConstValues.A_MOVEMENT_SCALE)),
- Number(movementBoneXML.attribute(ConstValues.A_MOVEMENT_DELAY))
- );
+ var timeline:TransformTimeline = new TransformTimeline();
+ timeline.duration = duration;
- var i:uint = 0;
- var parentTotalDuration:uint = 0;
- var totalDuration:uint = 0;
- var currentDuration:uint = 0;
- if (parentMovementBoneXML)
- {
- var parentFrameXMLList:XMLList = parentMovementBoneXML.elements(ConstValues.FRAME);
- var parentFrameCount:uint = parentFrameXMLList.length();
- var parentFrameXML:XML;
- }
- var frameXMLList:XMLList = movementBoneXML.elements(ConstValues.FRAME);
- var frameCount:uint = frameXMLList.length();
- var frameList:Vector. = movementBoneData._frameList;
- for (var j:int = 0; j < frameCount; j++)
- {
- var frameXML:XML = frameXMLList[j];
- var frameData:FrameData = frameList.length > j ? frameList[j] : null;
-
- if (frameData)
- {
- parseFrameData(frameXML, frameData);
- }
- else
- {
- frameData = new FrameData();
- parseFrameData(frameXML, frameData);
- if (frameList.indexOf(frameData) < 0)
- {
- frameList.push(frameData);
- }
- }
- if (parentMovementBoneXML)
- {
- while (i < parentFrameCount && (parentFrameXML ? (totalDuration < parentTotalDuration || totalDuration >= parentTotalDuration + currentDuration) : true))
- {
- parentFrameXML = parentFrameXMLList[i];
- parentTotalDuration += currentDuration;
- currentDuration = int(parentFrameXML.attribute(ConstValues.A_DURATION));
- i++;
- }
- parseFrameData(parentFrameXML, _helpFrameData);
- var tweenFrameXML:XML = parentFrameXMLList[i];
- var progress:Number;
- if (tweenFrameXML)
- {
- progress = (totalDuration - parentTotalDuration) / currentDuration;
- }
- else
- {
- tweenFrameXML = parentFrameXML;
- progress = 0;
- }
- if (isNaN(_helpFrameData.tweenEasing))
- {
- progress = 0;
- }
- else
- {
- progress = Tween.getEaseValue(progress, _helpFrameData.tweenEasing);
- }
- parseNode(tweenFrameXML, _helpNode);
- TransformUtils.setOffSetNode(_helpFrameData.node, _helpNode, _helpNode, _helpFrameData.tweenRotate);
-
- _helpNode.setValues(
- _helpFrameData.node.x + progress * _helpNode.x,
- _helpFrameData.node.y + progress * _helpNode.y,
- _helpFrameData.node.skewX + progress * _helpNode.skewX,
- _helpFrameData.node.skewY + progress * _helpNode.skewY,
- _helpFrameData.node.scaleX + progress * _helpNode.scaleX,
- _helpFrameData.node.scaleY + progress * _helpNode.scaleY,
- _helpFrameData.node.pivotX + progress * _helpNode.pivotX,
- _helpFrameData.node.pivotY + progress * _helpNode.pivotY
- );
-
- TransformUtils.transformPointWithParent(frameData.node, _helpNode);
- }
- totalDuration += int(frameXML.attribute(ConstValues.A_DURATION));
- frameData.node.x -= boneData.node.x;
- frameData.node.y -= boneData.node.y;
- frameData.node.skewX -= boneData.node.skewX;
- frameData.node.skewY -= boneData.node.skewY;
- frameData.node.scaleX -= boneData.node.scaleX;
- frameData.node.scaleY -= boneData.node.scaleY;
- frameData.node.pivotX -= boneData.node.pivotX;
- frameData.node.pivotY -= boneData.node.pivotY;
- frameData.node.z -= boneData.node.z;
- }
+ parseTimeline(timelineXML, timeline, parseTransformFrame, frameRate);
+
+ timeline.scale = Number(timelineXML.@[ConstValues.A_SCALE]);
+ timeline.offset = Number(timelineXML.@[ConstValues.A_OFFSET]);
+
+ return timeline;
}
- private static function parseMovementFrameData(movementFrameXML:XML, movementFrameData:MovementFrameData):void
+ private static function parseFrame(frameXML:XML, frame:Frame, frameRate:uint):void
{
- if(_currentSkeletonData)
- {
- movementFrameData.setValues(
- Number(movementFrameXML.attribute(ConstValues.A_DURATION)) / _currentSkeletonData._frameRate,
- movementFrameXML.attribute(ConstValues.A_MOVEMENT),
- movementFrameXML.attribute(ConstValues.A_EVENT),
- movementFrameXML.attribute(ConstValues.A_SOUND)
- );
- }
+ frame.duration = Number(frameXML.@[ConstValues.A_DURATION]) / frameRate;
+ frame.action = frameXML.@[ConstValues.A_ACTION];
+ frame.event = frameXML.@[ConstValues.A_EVENT];
+ frame.sound = frameXML.@[ConstValues.A_SOUND];
}
- /** @private */
- dragonBones_internal static function parseFrameData(frameXML:XML, frameData:FrameData):void
+ private static function parseMainFrame(frameXML:XML, frameRate:uint):Frame
{
- parseNode(frameXML, frameData.node);
- if (_currentSkeletonData)
- {
- var colorTransformXML:XML = frameXML.elements(ConstValues.COLOR_TRANSFORM)[0];
- if (colorTransformXML)
- {
- parseColorTransform(colorTransformXML, frameData.colorTransform);
- }
- frameData.duration = int(frameXML.attribute(ConstValues.A_DURATION)) / _currentSkeletonData._frameRate;
- frameData.tweenEasing = Number(frameXML.attribute(ConstValues.A_TWEEN_EASING));
- frameData.tweenRotate = int(frameXML.attribute(ConstValues.A_TWEEN_ROTATE));
- frameData.displayIndex = int(frameXML.attribute(ConstValues.A_DISPLAY_INDEX));
- frameData.movement = String(frameXML.attribute(ConstValues.A_MOVEMENT));
- frameData.event = String(frameXML.attribute(ConstValues.A_EVENT));
- frameData.sound = String(frameXML.attribute(ConstValues.A_SOUND));
- frameData.soundEffect = String(frameXML.attribute(ConstValues.A_SOUND_EFFECT));
- var visibleStr:String = String(frameXML.attribute(ConstValues.A_VISIBLE));
- frameData.visible = (visibleStr == "1" || visibleStr == "");
- }
+ var frame:Frame = new Frame();
+ parseFrame(frameXML, frame, frameRate);
+ return frame;
}
- private static function parseNode(xml:XML, node:BoneTransform):void
+ private static function parseTransformFrame(frameXML:XML, frameRate:uint):TransformFrame
{
- node.x = Number(xml.attribute(ConstValues.A_X));
- node.y = Number(xml.attribute(ConstValues.A_Y));
- node.skewX = Number(xml.attribute(ConstValues.A_SKEW_X)) * ANGLE_TO_RADIAN;
- node.skewY = Number(xml.attribute(ConstValues.A_SKEW_Y)) * ANGLE_TO_RADIAN;
- node.scaleX = Number(xml.attribute(ConstValues.A_SCALE_X));
- node.scaleY = Number(xml.attribute(ConstValues.A_SCALE_Y));
- node.pivotX = Number(xml.attribute(ConstValues.A_PIVOT_X));
- node.pivotY = Number(xml.attribute(ConstValues.A_PIVOT_Y));
- node.z = int(xml.attribute(ConstValues.A_Z));
+ var frame:TransformFrame = new TransformFrame();
+ parseFrame(frameXML, frame, frameRate);
+
+ frame.visible = uint(frameXML.@[ConstValues.A_HIDE]) != 1;
+ frame.tweenEasing = Number(frameXML.@[ConstValues.A_TWEEN_EASING]);
+ frame.tweenRotate = Number(frameXML.@[ConstValues.A_TWEEN_ROTATE]);
+ frame.displayIndex = Number(frameXML.@[ConstValues.A_DISPLAY_INDEX]);
+ //
+ frame.zOrder = Number(frameXML.@[ConstValues.A_Z_ORDER][0]);
+
+ parseTransform(frameXML[ConstValues.TRANSFORM][0], frame.global, frame.pivot);
+ frame.transform.copy(frame.global);
+
+ var colorTransformXML:XML = frameXML[ConstValues.COLOR_TRANSFORM][0];
+ if(colorTransformXML)
+ {
+ frame.color = new ColorTransform();
+ frame.color.alphaOffset = Number(colorTransformXML.@[ConstValues.A_ALPHA_OFFSET]);
+ frame.color.redOffset = Number(colorTransformXML.@[ConstValues.A_RED_OFFSET]);
+ frame.color.greenOffset = Number(colorTransformXML.@[ConstValues.A_GREEN_OFFSET]);
+ frame.color.blueOffset = Number(colorTransformXML.@[ConstValues.A_BLUE_OFFSET]);
+
+ frame.color.alphaMultiplier = Number(colorTransformXML.@[ConstValues.A_ALPHA_MULTIPLIER]) * 0.01;
+ frame.color.redMultiplier = Number(colorTransformXML.@[ConstValues.A_RED_MULTIPLIER]) * 0.01;
+ frame.color.greenMultiplier = Number(colorTransformXML.@[ConstValues.A_GREEN_MULTIPLIER]) * 0.01;
+ frame.color.blueMultiplier = Number(colorTransformXML.@[ConstValues.A_BLUE_MULTIPLIER]) * 0.01;
+ }
+
+ return frame;
}
- private static function parseColorTransform(xml:XML, colorTransform:ColorTransform):void
+ private static function parseTransform(transformXML:XML, transform:DBTransform, pivot:Point = null):void
{
- colorTransform.alphaOffset = int(xml.attribute(ConstValues.A_ALPHA));
- colorTransform.redOffset = int(xml.attribute(ConstValues.A_RED));
- colorTransform.greenOffset = int(xml.attribute(ConstValues.A_GREEN));
- colorTransform.blueOffset = int(xml.attribute(ConstValues.A_BLUE));
- colorTransform.alphaMultiplier = int(xml.attribute(ConstValues.A_ALPHA_MULTIPLIER)) * 0.01;
- colorTransform.redMultiplier = int(xml.attribute(ConstValues.A_RED_MULTIPLIER)) * 0.01;
- colorTransform.greenMultiplier = int(xml.attribute(ConstValues.A_GREEN_MULTIPLIER)) * 0.01;
- colorTransform.blueMultiplier = int(xml.attribute(ConstValues.A_BLUE_MULTIPLIER)) * 0.01;
+ if(transformXML)
+ {
+ if(transform)
+ {
+ transform.x = Number(transformXML.@[ConstValues.A_X]);
+ transform.y = Number(transformXML.@[ConstValues.A_Y]);
+ transform.skewX = Number(transformXML.@[ConstValues.A_SKEW_X]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.skewY = Number(transformXML.@[ConstValues.A_SKEW_Y]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.scaleX = Number(transformXML.@[ConstValues.A_SCALE_X]);
+ transform.scaleY = Number(transformXML.@[ConstValues.A_SCALE_Y]);
+ }
+ if(pivot)
+ {
+ pivot.x = Number(transformXML.@[ConstValues.A_PIVOT_X]);
+ pivot.y = Number(transformXML.@[ConstValues.A_PIVOT_Y]);
+ }
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/src/dragonBones/textures/ITextureAtlas.as b/src/dragonBones/textures/ITextureAtlas.as
index 6719daa..9d9a6d1 100644
--- a/src/dragonBones/textures/ITextureAtlas.as
+++ b/src/dragonBones/textures/ITextureAtlas.as
@@ -10,7 +10,6 @@ package dragonBones.textures
/**
* The ITextureAtlas interface defines the methods used by all ITextureAtlas within the dragonBones system (flash or starling DisplayObject based).
* @see dragonBones.Armature
- * @see dragonBones.animation.WorldClock
*/
public interface ITextureAtlas
{
diff --git a/src/dragonBones/textures/NativeTextureAtlas.as b/src/dragonBones/textures/NativeTextureAtlas.as
index 40dc394..22e7604 100644
--- a/src/dragonBones/textures/NativeTextureAtlas.as
+++ b/src/dragonBones/textures/NativeTextureAtlas.as
@@ -6,11 +6,11 @@ package dragonBones.textures
* @langversion 3.0
* @version 2.0
*/
- import dragonBones.textures.SubTextureData;
- import dragonBones.utils.ConstValues;
- import dragonBones.utils.dragonBones_internal;
- import flash.display.MovieClip;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.DataParser;
+
import flash.display.BitmapData;
+ import flash.display.MovieClip;
import flash.geom.Rectangle;
use namespace dragonBones_internal;
@@ -20,14 +20,6 @@ package dragonBones.textures
*/
public class NativeTextureAtlas implements ITextureAtlas
{
- /**
- * @private
- */
- protected var _width:int;
- /**
- * @private
- */
- protected var _height:int;
/**
* @private
*/
@@ -81,11 +73,10 @@ package dragonBones.textures
* @param textureScale A scale value (x and y axis)
* @param isDifferentXML
*/
- public function NativeTextureAtlas(texture:Object, textureAtlasXML:XML, textureScale:Number = 1, isDifferentXML:Boolean = false)
+ public function NativeTextureAtlas(texture:Object, textureAtlasRawData:Object, textureScale:Number = 1, isDifferentXML:Boolean = false)
{
_scale = textureScale;
_isDifferentXML = isDifferentXML;
- _subTextureDataDic = {};
if (texture is BitmapData)
{
_bitmapData = texture as BitmapData;
@@ -95,7 +86,7 @@ package dragonBones.textures
_movieClip = texture as MovieClip;
_movieClip.stop();
}
- parseData(textureAtlasXML);
+ parseData(textureAtlasRawData);
}
/**
* Clean up all resources used by this NativeTextureAtlas instance.
@@ -108,7 +99,6 @@ package dragonBones.textures
_bitmapData.dispose();
}
_bitmapData = null;
- _subTextureDataDic = {};
}
/**
* The area occupied by all assets related to that name.
@@ -120,25 +110,12 @@ package dragonBones.textures
return _subTextureDataDic[name];
}
- protected function parseData(textureAtlasXML:XML):void
+ protected function parseData(textureAtlasRawData:Object):void
{
- _name = textureAtlasXML.attribute(ConstValues.A_NAME);
- _width = int(textureAtlasXML.attribute(ConstValues.A_WIDTH));
- _height = int(textureAtlasXML.attribute(ConstValues.A_HEIGHT));
- var scale:Number = _isDifferentXML ? _scale : 1;
- for each (var subTextureXML:XML in textureAtlasXML.elements(ConstValues.SUB_TEXTURE))
- {
- var subTextureName:String = subTextureXML.attribute(ConstValues.A_NAME);
- var subTextureData:SubTextureData = new SubTextureData();
- subTextureData.x = int(subTextureXML.attribute(ConstValues.A_X)) / scale;
- subTextureData.y = int(subTextureXML.attribute(ConstValues.A_Y)) / scale;
- subTextureData.width = int(subTextureXML.attribute(ConstValues.A_WIDTH)) / scale;
- subTextureData.height = int(subTextureXML.attribute(ConstValues.A_HEIGHT)) / scale;
- //1.4
- subTextureData.pivotX = int(subTextureXML.attribute(ConstValues.A_PIVOT_X));
- subTextureData.pivotY = int(subTextureXML.attribute(ConstValues.A_PIVOT_Y));
- _subTextureDataDic[subTextureName] = subTextureData;
- }
+ _subTextureDataDic = DataParser.parseTextureAtlas(textureAtlasRawData, _isDifferentXML ? _scale : 1);
+ _name = _subTextureDataDic.__name;
+
+ delete _subTextureDataDic.__name;
}
dragonBones_internal function movieClipToBitmapData():void
@@ -146,10 +123,15 @@ package dragonBones.textures
if (!_bitmapData && _movieClip)
{
_movieClip.gotoAndStop(1);
- _bitmapData = new BitmapData(_width, _height, true, 0xFF00FF);
+ _bitmapData = new BitmapData(getNearest2N(_movieClip.width), getNearest2N(_movieClip.height), true, 0xFF00FF);
_bitmapData.draw(_movieClip);
_movieClip.gotoAndStop(_movieClip.totalFrames);
}
}
+
+ private function getNearest2N(_n:uint):uint
+ {
+ return _n & _n - 1?1 << _n.toString(2).length:_n;
+ }
}
}
\ No newline at end of file
diff --git a/src/dragonBones/textures/StarlingTextureAtlas.as b/src/dragonBones/textures/StarlingTextureAtlas.as
index 775c941..a984946 100644
--- a/src/dragonBones/textures/StarlingTextureAtlas.as
+++ b/src/dragonBones/textures/StarlingTextureAtlas.as
@@ -6,10 +6,11 @@
* @langversion 3.0
* @version 2.0
*/
- import dragonBones.utils.ConstValues;
- import dragonBones.utils.dragonBones_internal;
+ import dragonBones.core.dragonBones_internal;
+ import dragonBones.objects.DataParser;
+
import flash.display.BitmapData;
- import flash.geom.Rectangle;
+
import starling.textures.SubTexture;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
@@ -50,19 +51,16 @@
* @param textureAtlasXML A textureAtlas xml
* @param isDifferentXML
*/
- public function StarlingTextureAtlas(texture:Texture, textureAtlasXML:XML, isDifferentXML:Boolean = false)
+ public function StarlingTextureAtlas(texture:Texture, textureAtlasRawData:Object, isDifferentXML:Boolean = false)
{
+ super(texture, null);
if (texture)
{
_scale = texture.scale;
_isDifferentXML = isDifferentXML;
- }
- super(texture, textureAtlasXML);
- if (textureAtlasXML)
- {
- _name = textureAtlasXML.attribute(ConstValues.A_NAME);
}
_subTextureDic = {};
+ parseData(textureAtlasRawData);
}
/**
* Clean up all resources used by this StarlingTextureAtlas instance.
@@ -74,7 +72,7 @@
{
subTexture.dispose();
}
- _subTextureDic = {};
+ _subTextureDic = null;
if (_bitmapData)
{
@@ -102,29 +100,15 @@
}
/**
* @private
- * @param atlasXml
*/
- override protected function parseAtlasXml(atlasXml:XML):void
+ protected function parseData(textureAtlasRawData:Object):void
{
- var scale:Number = _isDifferentXML ? _scale : 1;
-
- for each (var subTexture:XML in atlasXml.SubTexture)
+ var textureAtlasData:Object = DataParser.parseTextureAtlas(textureAtlasRawData, _isDifferentXML ? _scale : 1);
+ _name = textureAtlasData.__name;
+ delete textureAtlasData.__name;
+ for(var subTextureName:String in textureAtlasData)
{
- var name:String = subTexture.attribute("name");
- var x:Number = parseFloat(subTexture.attribute("x")) / scale;
- var y:Number = parseFloat(subTexture.attribute("y")) / scale;
- var width:Number = parseFloat(subTexture.attribute("width")) / scale;
- var height:Number = parseFloat(subTexture.attribute("height")) / scale;
- var frameX:Number = parseFloat(subTexture.attribute("frameX")) / scale;
- var frameY:Number = parseFloat(subTexture.attribute("frameY")) / scale;
- var frameWidth:Number = parseFloat(subTexture.attribute("frameWidth")) / scale;
- var frameHeight:Number = parseFloat(subTexture.attribute("frameHeight")) / scale;
- //1.4
- var region:SubTextureData = new SubTextureData(x, y, width, height);
- region.pivotX = int(subTexture.attribute(ConstValues.A_PIVOT_X));
- region.pivotY = int(subTexture.attribute(ConstValues.A_PIVOT_Y));
- var frame:Rectangle = frameWidth > 0 && frameHeight > 0 ? new Rectangle(frameX, frameY, frameWidth, frameHeight) : null;
- addRegion(name, region, frame);
+ this.addRegion(subTextureName, textureAtlasData[subTextureName], null);
}
}
}
diff --git a/src/dragonBones/textures/SubTextureData.as b/src/dragonBones/textures/SubTextureData.as
deleted file mode 100644
index d8a9a0f..0000000
--- a/src/dragonBones/textures/SubTextureData.as
+++ /dev/null
@@ -1,19 +0,0 @@
-package dragonBones.textures
-{
- import flash.geom.Rectangle;
-
- //1.4
- /** @private */
- public class SubTextureData extends Rectangle
- {
- public var pivotX:Number;
- public var pivotY:Number;
-
- public function SubTextureData(x:Number = 0, y:Number = 0, width:Number = 0, height:Number = 0)
- {
- super(x, y, width, height);
- pivotX = 0;
- pivotY = 0;
- }
- }
-}
\ No newline at end of file
diff --git a/src/dragonBones/utils/ConstValues.as b/src/dragonBones/utils/ConstValues.as
index a4cb408..57cf6af 100644
--- a/src/dragonBones/utils/ConstValues.as
+++ b/src/dragonBones/utils/ConstValues.as
@@ -4,64 +4,61 @@
/** @private */
final public class ConstValues
{
- public static const VERSION:String = "2.2";
- public static const SKELETON:String = "skeleton";
- public static const ARMATURES:String = "armatures";
+ public static const ANGLE_TO_RADIAN:Number = Math.PI / 180;
+
+ public static const DRAGON_BONES:String = "dragonBones";
public static const ARMATURE:String = "armature";
- public static const BONE:String = "b";
- public static const DISPLAY:String = "d";
- public static const ANIMATIONS:String = "animations";
+ public static const SKIN:String = "skin";
+ public static const BONE:String = "bone";
+ public static const SLOT:String = "slot";
+ public static const DISPLAY:String = "display";
public static const ANIMATION:String = "animation";
- public static const MOVEMENT:String = "mov";
- public static const FRAME:String = "f";
+ public static const TIMELINE:String = "timeline";
+ public static const FRAME:String = "frame";
+ public static const TRANSFORM:String = "transform";
public static const COLOR_TRANSFORM:String = "colorTransform";
+
public static const TEXTURE_ATLAS:String = "TextureAtlas";
public static const SUB_TEXTURE:String = "SubTexture";
- public static const AT:String = "@";
+
public static const A_VERSION:String = "version";
+ public static const A_IMAGE_PATH:String = "imagePath";
public static const A_FRAME_RATE:String = "frameRate";
public static const A_NAME:String = "name";
- public static const A_DURATION:String = "dr";
- public static const A_DURATION_TO:String = "to";
- public static const A_DURATION_TWEEN:String = "drTW";
- public static const A_LOOP:String = "lp";
- public static const A_MOVEMENT_SCALE:String = "sc";
- public static const A_MOVEMENT_DELAY:String = "dl";
public static const A_PARENT:String = "parent";
- public static const A_SKEW_X:String = "kX";
- public static const A_SKEW_Y:String = "kY";
- public static const A_SCALE_X:String = "cX";
- public static const A_SCALE_Y:String = "cY";
- public static const A_Z:String = "z";
- public static const A_DISPLAY_INDEX:String = "dI";
- public static const A_EVENT:String = "evt";
- public static const A_SOUND:String = "sd";
- public static const A_SOUND_EFFECT:String = "sdE";
- public static const A_TWEEN_EASING:String = "twE";
- public static const A_TWEEN_ROTATE:String = "twR";
- public static const A_IS_ARMATURE:String = "isArmature";
- public static const A_MOVEMENT:String = "mov";
- public static const A_VISIBLE:String = "visible";
- public static const A_X:String = "x";
- public static const A_Y:String = "y";
+ public static const A_LENGTH:String = "length";
+ public static const A_TYPE:String = "type";
+ public static const A_FADE_IN_TIME:String = "fadeInTime";
+ public static const A_DURATION:String = "duration";
+ public static const A_SCALE:String = "scale";
+ public static const A_OFFSET:String = "offset";
+ public static const A_LOOP:String = "loop";
+ public static const A_EVENT:String = "event";
+ public static const A_SOUND:String = "sound";
+ public static const A_ACTION:String = "action";
+ public static const A_HIDE:String = "hide";
+ public static const A_TWEEN_EASING:String = "tweenEasing";
+ public static const A_TWEEN_ROTATE:String = "tweenRotate";
+ public static const A_DISPLAY_INDEX:String = "displayIndex";
+ public static const A_Z_ORDER:String = "z";
public static const A_WIDTH:String = "width";
public static const A_HEIGHT:String = "height";
+ public static const A_X:String = "x";
+ public static const A_Y:String = "y";
+ public static const A_SKEW_X:String = "skX";
+ public static const A_SKEW_Y:String = "skY";
+ public static const A_SCALE_X:String = "scX";
+ public static const A_SCALE_Y:String = "scY";
public static const A_PIVOT_X:String = "pX";
public static const A_PIVOT_Y:String = "pY";
- public static const A_ALPHA:String = "a";
- public static const A_RED:String = "r";
- public static const A_GREEN:String = "g";
- public static const A_BLUE:String = "b";
+ public static const A_ALPHA_OFFSET:String = "aO";
+ public static const A_RED_OFFSET:String = "rO";
+ public static const A_GREEN_OFFSET:String = "gO";
+ public static const A_BLUE_OFFSET:String = "bO";
public static const A_ALPHA_MULTIPLIER:String = "aM";
public static const A_RED_MULTIPLIER:String = "rM";
public static const A_GREEN_MULTIPLIER:String = "gM";
public static const A_BLUE_MULTIPLIER:String = "bM";
- public static const V_SOUND_LEFT:String = "l";
- public static const V_SOUND_RIGHT:String = "r";
- public static const V_SOUND_LEFT_TO_RIGHT:String = "lr";
- public static const V_SOUND_RIGHT_TO_LEFT:String = "rl";
- public static const V_SOUND_FADE_IN:String = "in";
- public static const V_SOUND_FADE_OUT:String = "out";
}
-}
+}
\ No newline at end of file
diff --git a/src/dragonBones/utils/DBDataUtil.as b/src/dragonBones/utils/DBDataUtil.as
new file mode 100644
index 0000000..0be8159
--- /dev/null
+++ b/src/dragonBones/utils/DBDataUtil.as
@@ -0,0 +1,263 @@
+package dragonBones.utils
+{
+ import dragonBones.animation.TimelineState;
+ import dragonBones.objects.AnimationData;
+ import dragonBones.objects.ArmatureData;
+ import dragonBones.objects.BoneData;
+ import dragonBones.objects.DBTransform;
+ import dragonBones.objects.DisplayData;
+ import dragonBones.objects.Frame;
+ import dragonBones.objects.SkinData;
+ import dragonBones.objects.SlotData;
+ import dragonBones.objects.TransformFrame;
+ import dragonBones.objects.TransformTimeline;
+
+ import flash.geom.Point;
+
+ /** @private */
+ public final class DBDataUtil
+ {
+ private static const _helpTransform1:DBTransform = new DBTransform();
+ private static const _helpTransform2:DBTransform = new DBTransform();
+
+ public static function transformArmatureData(armatureData:ArmatureData):void
+ {
+ var i:int = armatureData.boneDataList.length;
+ var boneData:BoneData;
+ var parentBoneData:BoneData;
+ while(i --)
+ {
+ boneData = armatureData.boneDataList[i];
+ if(boneData.parent)
+ {
+ parentBoneData = armatureData.getBoneData(boneData.parent);
+ if(parentBoneData)
+ {
+ boneData.transform.copy(boneData.global);
+ TransformUtil.transformPointWithParent(boneData.transform, parentBoneData.global);
+ }
+ }
+ }
+ }
+
+ public static function transformArmatureDataAnimations(armatureData:ArmatureData):void
+ {
+ var animationDataList:Vector. = armatureData.animationDataList;
+ var i:int = animationDataList.length;
+ while(i --)
+ {
+ transformAnimationData(animationDataList[i], armatureData);
+ }
+ }
+
+ public static function transformAnimationData(animationData:AnimationData, armatureData:ArmatureData):void
+ {
+ var skinData:SkinData = armatureData.getSkinData(null);
+ var i:int = armatureData.boneDataList.length;
+
+ var boneData:BoneData;
+ var timeline:TransformTimeline;
+ var slotData:SlotData;
+ var displayData:DisplayData
+ var parentTimeline:TransformTimeline;
+ var frameList:Vector.;
+ var originTransform:DBTransform;
+ var originPivot:Point;
+ var prevFrame:TransformFrame;
+ var frameListLength:uint;
+ var frame:TransformFrame;
+
+ while(i --)
+ {
+ boneData = armatureData.boneDataList[i];
+ timeline = animationData.getTimeline(boneData.name);
+ if(!timeline)
+ {
+ continue;
+ }
+
+ slotData = null;
+ for each(slotData in skinData.slotDataList)
+ {
+ if(slotData.parent == boneData.name)
+ {
+ break;
+ }
+ }
+
+ parentTimeline = boneData.parent?animationData.getTimeline(boneData.parent):null;
+
+ frameList = timeline.frameList;
+
+ originTransform = null;
+ originPivot = null;
+ prevFrame = null;
+ frameListLength = frameList.length;
+ for(var j:int = 0;j < frameListLength;j ++)
+ {
+ frame = frameList[j] as TransformFrame;
+ if(parentTimeline)
+ {
+ //tweenValues to transform.
+ _helpTransform1.copy(frame.global);
+
+ //get transform from parent timeline.
+ getTimelineTransform(parentTimeline, frame.position, _helpTransform2);
+ TransformUtil.transformPointWithParent(_helpTransform1, _helpTransform2);
+
+ //transform to tweenValues.
+ frame.transform.copy(_helpTransform1);
+ }
+ else
+ {
+ frame.transform.copy(frame.global);
+ }
+
+ frame.transform.x -= boneData.transform.x;
+ frame.transform.y -= boneData.transform.y;
+ frame.transform.skewX -= boneData.transform.skewX;
+ frame.transform.skewY -= boneData.transform.skewY;
+ frame.transform.scaleX -= boneData.transform.scaleX;
+ frame.transform.scaleY -= boneData.transform.scaleY;
+
+ if(!timeline.transformed)
+ {
+ if(slotData)
+ {
+ frame.zOrder -= slotData.zOrder;
+ }
+ }
+
+ if(!originTransform)
+ {
+ originTransform = timeline.originTransform;
+ originTransform.copy(frame.transform);
+ originTransform.skewX = TransformUtil.formatRadian(originTransform.skewX);
+ originTransform.skewY = TransformUtil.formatRadian(originTransform.skewY);
+ originPivot = timeline.originPivot;
+ originPivot.x = frame.pivot.x;
+ originPivot.y = frame.pivot.y;
+ }
+
+ frame.transform.x -= originTransform.x;
+ frame.transform.y -= originTransform.y;
+ frame.transform.skewX = TransformUtil.formatRadian(frame.transform.skewX - originTransform.skewX);
+ frame.transform.skewY = TransformUtil.formatRadian(frame.transform.skewY - originTransform.skewY);
+ frame.transform.scaleX -= originTransform.scaleX;
+ frame.transform.scaleY -= originTransform.scaleY;
+
+ if(!timeline.transformed)
+ {
+ frame.pivot.x -= originPivot.x;
+ frame.pivot.y -= originPivot.y;
+ }
+
+ if(prevFrame)
+ {
+ var dLX:Number = frame.transform.skewX - prevFrame.transform.skewX;
+
+ if(prevFrame.tweenRotate)
+ {
+
+ if(prevFrame.tweenRotate > 0)
+ {
+ if(dLX < 0)
+ {
+ frame.transform.skewX += Math.PI * 2;
+ frame.transform.skewY += Math.PI * 2;
+ }
+
+ if(prevFrame.tweenRotate > 1)
+ {
+ frame.transform.skewX += Math.PI * 2 * (prevFrame.tweenRotate - 1);
+ frame.transform.skewY += Math.PI * 2 * (prevFrame.tweenRotate - 1);
+ }
+ }
+ else
+ {
+ if(dLX > 0)
+ {
+ frame.transform.skewX -= Math.PI * 2;
+ frame.transform.skewY -= Math.PI * 2;
+ }
+
+ if(prevFrame.tweenRotate < 1)
+ {
+ frame.transform.skewX += Math.PI * 2 * (prevFrame.tweenRotate + 1);
+ frame.transform.skewY += Math.PI * 2 * (prevFrame.tweenRotate + 1);
+ }
+ }
+ }
+ else
+ {
+ frame.transform.skewX = prevFrame.transform.skewX + TransformUtil.formatRadian(frame.transform.skewX - prevFrame.transform.skewX);
+ frame.transform.skewY = prevFrame.transform.skewY + TransformUtil.formatRadian(frame.transform.skewY - prevFrame.transform.skewY);
+ }
+ }
+
+ prevFrame = frame;
+ }
+ timeline.transformed = true;
+ }
+ }
+
+ public static function getTimelineTransform(timeline:TransformTimeline, position:Number, retult:DBTransform):void
+ {
+ var frameList:Vector. = timeline.frameList;
+ var i:int = frameList.length;
+
+ var currentFrame:TransformFrame;
+ var tweenEasing:Number;
+ var progress:Number;
+ var nextFrame:TransformFrame;
+ while(i --)
+ {
+ currentFrame = frameList[i] as TransformFrame;
+ if(currentFrame.position <= position && currentFrame.position + currentFrame.duration > position)
+ {
+ tweenEasing = currentFrame.tweenEasing;
+ if(i == frameList.length - 1 || isNaN(tweenEasing) || position == currentFrame.position)
+ {
+ retult.copy(currentFrame.global);
+ }
+ else
+ {
+ progress = (position - currentFrame.position) / currentFrame.duration;
+ if(tweenEasing)
+ {
+ progress = TimelineState.getEaseValue(progress, tweenEasing);
+ }
+
+ nextFrame = timeline.frameList[i + 1] as TransformFrame;
+
+ retult.x = currentFrame.global.x + (nextFrame.global.x - currentFrame.global.x) * progress;
+ retult.y = currentFrame.global.y + (nextFrame.global.y - currentFrame.global.y) * progress;
+ retult.skewX = TransformUtil.formatRadian(currentFrame.global.skewX + (nextFrame.global.skewX - currentFrame.global.skewX) * progress);
+ retult.skewY = TransformUtil.formatRadian(currentFrame.global.skewY + (nextFrame.global.skewY - currentFrame.global.skewY) * progress);
+ retult.scaleX = currentFrame.global.scaleX + (nextFrame.global.scaleX - currentFrame.global.scaleX) * progress;
+ retult.scaleY = currentFrame.global.scaleY + (nextFrame.global.scaleY - currentFrame.global.scaleY) * progress;
+ }
+ break;
+ }
+ }
+ }
+
+ public static function addHideTimeline(animationData:AnimationData, armatureData:ArmatureData):void
+ {
+ var boneDataList:Vector. =armatureData.boneDataList;
+ var i:int = boneDataList.length;
+
+ var boneData:BoneData;
+ var boneName:String;
+ while(i --)
+ {
+ boneData = boneDataList[i];
+ boneName = boneData.name;
+ if(!animationData.getTimeline(boneName))
+ {
+ animationData.addTimeline(TransformTimeline.HIDE_TIMELINE, boneName);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dragonBones/utils/TransformUtil.as b/src/dragonBones/utils/TransformUtil.as
new file mode 100644
index 0000000..c8239b6
--- /dev/null
+++ b/src/dragonBones/utils/TransformUtil.as
@@ -0,0 +1,55 @@
+package dragonBones.utils
+{
+ import dragonBones.objects.DBTransform;
+
+ import flash.geom.Matrix;
+
+ /** @private */
+ final public class TransformUtil
+ {
+ private static const HALF_PI:Number = Math.PI * 0.5;
+ private static const DOUBLE_PI:Number = Math.PI * 2;
+
+ private static const _helpMatrix:Matrix = new Matrix();
+
+ public static function transformPointWithParent(transform:DBTransform, parent:DBTransform):void
+ {
+ transformToMatrix(parent, _helpMatrix);
+ _helpMatrix.invert();
+
+ var x:Number = transform.x;
+ var y:Number = transform.y;
+
+ transform.x = _helpMatrix.a * x + _helpMatrix.c * y + _helpMatrix.tx;
+ transform.y = _helpMatrix.d * y + _helpMatrix.b * x + _helpMatrix.ty;
+
+ transform.skewX = formatRadian(transform.skewX - parent.skewX);
+ transform.skewY = formatRadian(transform.skewY - parent.skewY);
+ }
+
+ public static function transformToMatrix(transform:DBTransform, matrix:Matrix):void
+ {
+ matrix.a = transform.scaleX * Math.cos(transform.skewY)
+ matrix.b = transform.scaleX * Math.sin(transform.skewY)
+ matrix.c = -transform.scaleY * Math.sin(transform.skewX);
+ matrix.d = transform.scaleY * Math.cos(transform.skewX);
+ matrix.tx = transform.x;
+ matrix.ty = transform.y;
+ }
+
+ public static function formatRadian(radian:Number):Number
+ {
+ radian %= DOUBLE_PI;
+ if (radian > Math.PI)
+ {
+ radian -= DOUBLE_PI;
+ }
+ if (radian < -Math.PI)
+ {
+ radian += DOUBLE_PI;
+ }
+ return radian;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/dragonBones/utils/TransformUtils.as b/src/dragonBones/utils/TransformUtils.as
deleted file mode 100644
index 6642855..0000000
--- a/src/dragonBones/utils/TransformUtils.as
+++ /dev/null
@@ -1,107 +0,0 @@
-package dragonBones.utils
-{
-
- import dragonBones.objects.BoneTransform;
- import flash.geom.ColorTransform;
- import flash.geom.Matrix;
- import flash.geom.Point;
-
- /** @private */
- public class TransformUtils
- {
- private static const DOUBLE_PI:Number = Math.PI * 2;
- private static var _helpMatrix:Matrix = new Matrix();
- private static var _helpPoint:Point = new Point();
-
- public static function transformPointWithParent(bone:BoneTransform, parent:BoneTransform):void
- {
- nodeToMatrix(parent, _helpMatrix);
- _helpPoint.x = bone.x;
- _helpPoint.y = bone.y;
- _helpMatrix.invert();
- _helpPoint = _helpMatrix.transformPoint(_helpPoint);
- bone.x = _helpPoint.x;
- bone.y = _helpPoint.y;
- bone.skewX -= parent.skewX;
- bone.skewY -= parent.skewY;
- }
-
- public static function nodeToMatrix(node:BoneTransform, matrix:Matrix):void
- {
- matrix.a = node.scaleX * Math.cos(node.skewY)
- matrix.b = node.scaleX * Math.sin(node.skewY)
- matrix.c = -node.scaleY * Math.sin(node.skewX);
- matrix.d = node.scaleY * Math.cos(node.skewX);
- matrix.tx = node.x;
- matrix.ty = node.y;
- }
-
- public static function setOffSetColorTransform(from:ColorTransform, to:ColorTransform, offSet:ColorTransform):void
- {
- offSet.alphaOffset = to.alphaOffset - from.alphaOffset;
- offSet.redOffset = to.redOffset - from.redOffset;
- offSet.greenOffset = to.greenOffset - from.greenOffset;
- offSet.blueOffset = to.blueOffset - from.blueOffset;
- offSet.alphaMultiplier = to.alphaMultiplier - from.alphaMultiplier;
- offSet.redMultiplier = to.redMultiplier - from.redMultiplier;
- offSet.greenMultiplier = to.greenMultiplier - from.greenMultiplier;
- offSet.blueMultiplier = to.blueMultiplier - from.blueMultiplier;
- }
-
- public static function setTweenColorTransform(current:ColorTransform, offSet:ColorTransform, tween:ColorTransform, progress:Number):void
- {
- tween.alphaOffset = current.alphaOffset + progress * offSet.alphaOffset;
- tween.redOffset = current.redOffset + progress * offSet.redOffset;
- tween.greenOffset = current.greenOffset + progress * offSet.greenOffset;
- tween.blueOffset = current.blueOffset + progress * offSet.blueOffset;
- tween.alphaMultiplier = current.alphaMultiplier + progress * offSet.alphaMultiplier;
- tween.redMultiplier = current.redMultiplier + progress * offSet.redMultiplier;
- tween.greenMultiplier = current.greenMultiplier + progress * offSet.greenMultiplier;
- tween.blueMultiplier = current.blueMultiplier + progress * offSet.blueMultiplier;
- }
-
- public static function setOffSetNode(from:BoneTransform, to:BoneTransform, offSet:BoneTransform, tweenRotate:int = 0):void
- {
- offSet.x = to.x - from.x;
- offSet.y = to.y - from.y;
- offSet.skewX = to.skewX - from.skewX;
- offSet.skewY = to.skewY - from.skewY;
- offSet.scaleX = to.scaleX - from.scaleX;
- offSet.scaleY = to.scaleY - from.scaleY;
- offSet.pivotX = to.pivotX - from.pivotX;
- offSet.pivotY = to.pivotY - from.pivotY;
-
- offSet.skewX %= DOUBLE_PI;
- if (offSet.skewX > Math.PI)
- {
- offSet.skewX -= DOUBLE_PI;
- }
- if (offSet.skewX < -Math.PI)
- {
- offSet.skewX += DOUBLE_PI;
- }
-
- offSet.skewY %= DOUBLE_PI;
- if (offSet.skewY > Math.PI)
- {
- offSet.skewY -= DOUBLE_PI;
- }
- if (offSet.skewY < -Math.PI)
- {
- offSet.skewY += DOUBLE_PI;
- }
-
- if (tweenRotate)
- {
- offSet.skewX += tweenRotate * DOUBLE_PI;
- offSet.skewY += tweenRotate * DOUBLE_PI;
- }
- }
-
- public static function setTweenNode(current:BoneTransform, offSet:BoneTransform, tween:BoneTransform, progress:Number):void
- {
- tween.setValues(current.x + progress * offSet.x, current.y + progress * offSet.y, current.skewX + progress * offSet.skewX, current.skewY + progress * offSet.skewY, current.scaleX + progress * offSet.scaleX, current.scaleY + progress * offSet.scaleY, current.pivotX + progress * offSet.pivotX, current.pivotY + progress * offSet.pivotY, tween.z);
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/dragonBones/utils/checkBytesTailisXML.as b/src/dragonBones/utils/checkBytesTailisXML.as
new file mode 100644
index 0000000..0edeb69
--- /dev/null
+++ b/src/dragonBones/utils/checkBytesTailisXML.as
@@ -0,0 +1,51 @@
+package dragonBones.utils
+{
+ import flash.utils.ByteArray;
+
+ public function checkBytesTailisXML(bytes:ByteArray):Boolean
+ {
+ var offset:int = bytes.length;
+
+ var count1:int = 20;
+ while(count1 --)
+ {
+ if(offset --)
+ {
+ switch(bytes[offset])
+ {
+ case charCodes[" "]:
+ case charCodes["\t"]:
+ case charCodes["\r"]:
+ case charCodes["\n"]:
+ //
+ break;
+ case charCodes[">"]:
+ var count2:int = 20;
+ while(count2 --)
+ {
+ if(offset --)
+ {
+ if(bytes[offset] == charCodes["<"])
+ {
+ return true;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ return false;
+ break;
+ }
+ }
+ }
+ return false;
+ }
+}
+
+const charCodes:Object = new Object();
+for each(var c:String in " \t\r\n<>".split(""))
+{
+ charCodes[c] = c.charCodeAt(0);
+}
\ No newline at end of file
diff --git a/src/dragonBones/utils/parseOldXMLData.as b/src/dragonBones/utils/parseOldXMLData.as
new file mode 100644
index 0000000..0bba45d
--- /dev/null
+++ b/src/dragonBones/utils/parseOldXMLData.as
@@ -0,0 +1,356 @@
+package dragonBones.utils
+{
+ import dragonBones.objects.SkeletonData;
+ import dragonBones.objects.ArmatureData;
+
+ public function parseOldXMLData(rawData:XML):SkeletonData
+ {
+ var frameRate:uint = int(rawData.@[A_FRAME_RATE]);
+
+ var data:SkeletonData = new SkeletonData();
+ data.name = rawData.@[A_NAME];
+
+ for each(var armatureXML:XML in rawData[ARMATURES][ARMATURE])
+ {
+ data.addArmatureData(parseArmatureData(armatureXML, data));
+ }
+
+ for each(var animationsXML:XML in rawData[ANIMATIONS][ANIMATION])
+ {
+ var armatureData:ArmatureData = data.getArmatureData(animationsXML.@[A_NAME]);
+ if(armatureData)
+ {
+ for each(var animationXML:XML in animationsXML[MOVEMENT])
+ {
+ armatureData.addAnimationData(parseAnimationData(animationXML, armatureData, frameRate));
+ }
+ }
+ }
+
+ return data;
+ }
+}
+
+import dragonBones.objects.AnimationData;
+import dragonBones.objects.ArmatureData;
+import dragonBones.objects.BoneData;
+import dragonBones.objects.DBTransform;
+import dragonBones.objects.DisplayData;
+import dragonBones.objects.Frame;
+import dragonBones.objects.SkeletonData;
+import dragonBones.objects.SkinData;
+import dragonBones.objects.SlotData;
+import dragonBones.objects.Timeline;
+import dragonBones.objects.TransformFrame;
+import dragonBones.objects.TransformTimeline;
+import dragonBones.utils.ConstValues;
+import dragonBones.utils.DBDataUtil;
+
+import flash.geom.ColorTransform;
+import flash.geom.Point;
+
+const ARMATURES:String = "armatures";
+const ANIMATIONS:String = "animations";
+const ARMATURE:String = "armature";
+const BONE:String = "b";
+const DISPLAY:String = "d";
+const ANIMATION:String = "animation";
+const MOVEMENT:String = "mov";
+const FRAME:String = "f";
+const COLOR_TRANSFORM:String = "colorTransform";
+
+const A_VERSION:String = "version";
+const A_FRAME_RATE:String = "frameRate";
+const A_NAME:String = "name";
+const A_PARENT:String = "parent";
+const A_TYPE:String = "isArmature";
+const A_DURATION:String = "dr";
+const A_FADE_IN_TIME:String = "to";
+const A_DURATION_TWEEN:String = "drTW";
+const A_LOOP:String = "lp";
+const A_SCALE:String = "sc";
+const A_OFFSET:String = "dl";
+const A_EVENT:String = "evt";
+const A_SOUND:String = "sd";
+const A_TWEEN_EASING:String = "twE";
+const A_TWEEN_ROTATE:String = "twR";
+const A_ACTION:String = "mov";
+const A_VISIBLE:String = "visible";
+const A_DISPLAY_INDEX:String = "dI";
+const A_Z_ORDER:String = "z";
+const A_X:String = "x";
+const A_Y:String = "y";
+const A_SKEW_X:String = "kX";
+const A_SKEW_Y:String = "kY";
+const A_SCALE_X:String = "cX";
+const A_SCALE_Y:String = "cY";
+const A_PIVOT_X:String = "pX";
+const A_PIVOT_Y:String = "pY";
+
+const A_ALPHA_OFFSET:String = "a";
+const A_RED_OFFSET:String = "r";
+const A_GREEN_OFFSET:String = "g";
+const A_BLUE_OFFSET:String = "b";
+const A_ALPHA_MULTIPLIER:String = "aM";
+const A_RED_MULTIPLIER:String = "rM";
+const A_GREEN_MULTIPLIER:String = "gM";
+const A_BLUE_MULTIPLIER:String = "bM";
+
+function parseArmatureData(armatureXML:XML, data:SkeletonData):ArmatureData
+{
+ var armatureData:ArmatureData = new ArmatureData();
+ armatureData.name = armatureXML.@[A_NAME];
+
+ for each(var boneXML:XML in armatureXML[BONE])
+ {
+ armatureData.addBoneData(parseBoneData(boneXML));
+ }
+
+ armatureData.addSkinData(parseSkinData(armatureXML, data));
+
+ DBDataUtil.transformArmatureData(armatureData);
+ armatureData.sortBoneDataList();
+ return armatureData;
+}
+
+function parseBoneData(boneXML:XML):BoneData
+{
+ var boneData:BoneData = new BoneData();
+ boneData.name = boneXML.@[A_NAME];
+ boneData.parent = boneXML.@[A_PARENT];
+
+ parseTransform(boneXML, boneData.global);
+ boneData.transform.copy(boneData.global);
+
+ return boneData;
+}
+
+function parseSkinData(armatureXML:XML, data:SkeletonData):SkinData
+{
+ var skinData:SkinData = new SkinData();
+ //skinData.name
+ for each(var boneXML:XML in armatureXML[BONE])
+ {
+ skinData.addSlotData(parseSlotData(boneXML, data));
+ }
+
+ return skinData;
+}
+
+function parseSlotData(boneXML:XML, data:SkeletonData):SlotData
+{
+ var slotData:SlotData = new SlotData();
+ slotData.name = boneXML.@[A_NAME];
+ slotData.parent = slotData.name;
+ slotData.zOrder = boneXML.@[A_Z_ORDER];
+
+ for each(var displayXML:XML in boneXML[DISPLAY])
+ {
+ var displayData:DisplayData = parseDisplayData(displayXML, data);
+ slotData.addDisplayData(displayData);
+ }
+
+ return slotData;
+}
+
+function parseDisplayData(displayXML:XML, data:SkeletonData):DisplayData
+{
+ var displayData:DisplayData = new DisplayData();
+ displayData.name = displayXML.@[A_NAME];
+ if(uint(displayXML.@[A_TYPE]) == 1)
+ {
+ displayData.type = DisplayData.ARMATURE;
+ }
+ else
+ {
+ displayData.type = DisplayData.IMAGE;
+ }
+
+ //
+ //displayData.transform.x = -Number(frameXML.@[A_PIVOT_X]);
+ //displayData.transform.y = -Number(frameXML.@[A_PIVOT_Y]);
+ displayData.transform.x = NaN;
+ displayData.transform.y = NaN;
+ displayData.transform.skewX = 0;
+ displayData.transform.skewY = 0;
+ displayData.transform.scaleX = 1;
+ displayData.transform.scaleY = 1;
+
+ displayData.pivot = data.addSubTexturePivot(
+ Number(displayXML.@[A_PIVOT_X]),
+ Number(displayXML.@[A_PIVOT_Y]),
+ displayData.name
+ );
+
+ return displayData;
+}
+
+function parseAnimationData(animationXML:XML, armatureData:ArmatureData, frameRate:uint):AnimationData
+{
+ var animationData:AnimationData = new AnimationData();
+ animationData.name = animationXML.@[A_NAME];
+ animationData.frameRate = frameRate;
+ animationData.loop = uint(animationXML.@[A_LOOP]) == 1?0:1;
+ animationData.fadeInTime = uint(animationXML.@[A_FADE_IN_TIME]) / frameRate;
+ animationData.duration = uint(animationXML.@[A_DURATION]) / frameRate;
+ var durationTween:Number = Number(animationXML.@[A_DURATION_TWEEN][0]);
+ if(isNaN(durationTween))
+ {
+ animationData.scale = 1;
+ }
+ else
+ {
+ animationData.scale = durationTween / frameRate / animationData.duration;
+ }
+ animationData.tweenEasing = Number(animationXML.@[A_TWEEN_EASING][0]);
+
+ parseTimeline(animationXML, animationData, parseMainFrame, frameRate);
+
+ var skinData:SkinData = armatureData.skinDataList[0];
+ var slotData:SlotData;
+
+ var timeline:TransformTimeline;
+ var timelineName:String;
+ for each(var timelineXML:XML in animationXML[BONE])
+ {
+ timeline = parseTransformTimeline(timelineXML, animationData.duration, frameRate);
+ timelineName = timelineXML.@[A_NAME];
+ animationData.addTimeline(timeline, timelineName);
+ if(skinData)
+ {
+ slotData = skinData.getSlotData(timelineName);
+ formatDisplayTransformXYAndTimelinePivot(slotData, timeline);
+ }
+ }
+
+ DBDataUtil.addHideTimeline(animationData, armatureData);
+ DBDataUtil.transformAnimationData(animationData, armatureData);
+
+ return animationData;
+}
+
+
+function parseTimeline(timelineXML:XML, timeline:Timeline, frameParser:Function, frameRate:uint):void
+{
+ var position:Number = 0;
+ var frame:Frame;
+ for each(var frameXML:XML in timelineXML[FRAME])
+ {
+ frame = frameParser(frameXML, frameRate);
+ frame.position = position;
+ timeline.addFrame(frame);
+ position += frame.duration;
+ }
+ if(frame)
+ {
+ frame.duration = timeline.duration - frame.position;
+ }
+}
+
+function parseTransformTimeline(timelineXML:XML, duration:Number, frameRate:uint):TransformTimeline
+{
+ var timeline:TransformTimeline = new TransformTimeline();
+ timeline.duration = duration;
+
+ parseTimeline(timelineXML, timeline, parseTransformFrame, frameRate);
+
+ timeline.scale = Number(timelineXML.@[A_SCALE]);
+ timeline.offset = (1 - Number(timelineXML.@[A_OFFSET])) % 1;
+
+ return timeline;
+}
+
+function parseFrame(frameXML:XML, frame:Frame, frameRate:uint):void
+{
+ frame.duration = uint(frameXML.@[A_DURATION]) / frameRate;
+ frame.action = frameXML.@[A_ACTION];
+ frame.event = frameXML.@[A_EVENT];
+ frame.sound = frameXML.@[A_SOUND];
+}
+
+function parseMainFrame(frameXML:XML, frameRate:uint):Frame
+{
+ var frame:Frame = new Frame();
+ parseFrame(frameXML, frame, frameRate);
+ return frame;
+}
+
+function parseTransformFrame(frameXML:XML, frameRate:uint):TransformFrame
+{
+ var frame:TransformFrame = new TransformFrame();
+ parseFrame(frameXML, frame, frameRate);
+
+ frame.visible = frameXML.@[A_VISIBLE][0]?uint(frameXML.@[A_VISIBLE]) == 1:true;
+ frame.tweenEasing = Number(frameXML.@[A_TWEEN_EASING]);
+ frame.tweenRotate = int(frameXML.@[A_TWEEN_ROTATE]);
+ frame.displayIndex = int(frameXML.@[A_DISPLAY_INDEX]);
+ frame.zOrder = int(frameXML.@[A_Z_ORDER]);
+
+ parseTransform(frameXML, frame.global, frame.pivot);
+ frame.transform.copy(frame.global);
+
+ frame.pivot.x *= -1;
+ frame.pivot.y *= -1;
+
+ var colorTransformXML:XML = frameXML[COLOR_TRANSFORM][0];
+ if(colorTransformXML)
+ {
+ frame.color = new ColorTransform();
+ frame.color.alphaOffset = int(colorTransformXML.@[A_ALPHA_OFFSET]);
+ frame.color.redOffset = int(colorTransformXML.@[A_RED_OFFSET]);
+ frame.color.greenOffset = int(colorTransformXML.@[A_GREEN_OFFSET]);
+ frame.color.blueOffset = int(colorTransformXML.@[A_BLUE_OFFSET]);
+
+ frame.color.alphaMultiplier = int(colorTransformXML.@[A_ALPHA_MULTIPLIER]) * 0.01;
+ frame.color.redMultiplier = int(colorTransformXML.@[A_RED_MULTIPLIER]) * 0.01;
+ frame.color.greenMultiplier = int(colorTransformXML.@[A_GREEN_MULTIPLIER]) * 0.01;
+ frame.color.blueMultiplier = int(colorTransformXML.@[A_BLUE_MULTIPLIER]) * 0.01;
+ }
+
+ return frame;
+}
+
+function parseTransform(transformXML:XML, transform:DBTransform, pivot:Point = null):void
+{
+ if(transformXML)
+ {
+ if(transform)
+ {
+ transform.x = Number(transformXML.@[A_X]);
+ transform.y = Number(transformXML.@[A_Y]);
+ transform.skewX = Number(transformXML.@[A_SKEW_X]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.skewY = Number(transformXML.@[A_SKEW_Y]) * ConstValues.ANGLE_TO_RADIAN;
+ transform.scaleX = Number(transformXML.@[A_SCALE_X]);
+ transform.scaleY = Number(transformXML.@[A_SCALE_Y]);
+ }
+ if(pivot)
+ {
+ pivot.x = Number(transformXML.@[A_PIVOT_X]);
+ pivot.y = Number(transformXML.@[A_PIVOT_Y]);
+ }
+ }
+}
+
+function formatDisplayTransformXYAndTimelinePivot(slotData:SlotData, timeline:TransformTimeline):void
+{
+ if(!slotData)
+ {
+ return;
+ }
+
+ var displayData:DisplayData;
+ for each(var frame:TransformFrame in timeline.frameList)
+ {
+ if(frame.displayIndex >= 0)
+ {
+ displayData = slotData.displayDataList[frame.displayIndex];
+ if(isNaN(displayData.transform.x))
+ {
+ displayData.transform.x = frame.pivot.x;
+ displayData.transform.y = frame.pivot.y;
+ }
+ frame.pivot.x -= displayData.transform.x;
+ frame.pivot.y -= displayData.transform.y;
+ }
+ }
+}
\ No newline at end of file