- Modifié
as3 runtime duplicate skeletonData
Hi, i'm trying reuse skeletonData for several skeletonSprite. But on stage added only one. If I use starling runtime or recalls readSkeletonData the problem disappears. how can I reuse skeletonData for as3 runtime?
var skeletonData:SkeletonSprite = jsonData.readSkeletonData(json);
var skeleton:SkeletonSprite = new skeleton:SkeletonSprite (skeletonData);
addChild(skeleton);
var skeleton2:SkeletonSprite = new skeleton:SkeletonSprite (skeletonData);
skeleton2.x=300;
addChild(skeleton2);
the problem is solved after the addition of local displayObject cache.
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
package spine.flash {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import flash.utils.getTimer;
import spine.Bone;
import spine.Skeleton;
import spine.SkeletonData;
import spine.Slot;
import spine.atlas.AtlasRegion;
import spine.attachments.RegionAttachment;
public class SkeletonSprite extends Sprite {
static private var tempPoint:Point = new Point();
static private var tempMatrix:Matrix = new Matrix();
static private var blendModes:Vector.<String> = new <String>[
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
private var _skeleton:Skeleton;
public var timeScale:Number = 1;
private var lastTime:int;
private var cachedWrapper:Dictionary;
public function SkeletonSprite (skeletonData:SkeletonData) {
Bone.yDown = true;
cachedWrapper = new Dictionary();
_skeleton = new Skeleton(skeletonData);
_skeleton.updateWorldTransform();
addEventListener(Event.ENTER_FRAME, enterFrame);
}
private function enterFrame (event:Event) : void {
var time:int = getTimer();
advanceTime((time - lastTime) / 1000);
lastTime = time;
}
public function advanceTime (delta:Number) : void {
_skeleton.update(delta * timeScale);
removeChildren();
var drawOrder:Vector.<Slot> = skeleton.drawOrder;
for (var i:int = 0, n:int = drawOrder.length; i < n; i++) {
var slot:Slot = drawOrder[i];
var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment;
if (regionAttachment != null) {
var wrapper:Sprite = getLocalCache(regionAttachment);
wrapper.blendMode = blendModes[slot.data.blendMode.ordinal];
var colorTransform:ColorTransform = wrapper.transform.colorTransform;
colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
colorTransform.greenMultiplier = skeleton.g * slot.g * regionAttachment.g;
colorTransform.blueMultiplier = skeleton.b * slot.b * regionAttachment.b;
colorTransform.alphaMultiplier = skeleton.a * slot.a * regionAttachment.a;
wrapper.transform.colorTransform = colorTransform;
var bone:Bone = slot.bone;
var flipX:int = skeleton.flipX ? -1 : 1;
var flipY:int = skeleton.flipY ? -1 : 1;
if (bone.worldFlipX) flipX = -flipX;
if (bone.worldFlipY) flipY = -flipY;
wrapper.x = bone.worldX;
wrapper.y = bone.worldY;
wrapper.rotation = -bone.worldRotation * flipX * flipY;
wrapper.scaleX = bone.worldScaleX * flipX;
wrapper.scaleY = bone.worldScaleY * flipY;
addChild(wrapper);
}
}
}
private function getLocalCache(attachment:RegionAttachment) {
if (!cachedWrapper[attachment]) {
var regionCached:Bitmap = getGlobalCache(attachment)
var wrapper:Sprite = new Sprite();
var bmp:Bitmap = new Bitmap(regionCached.bitmapData, 'auto', true);
bmp.transform.matrix = regionCached.transform.matrix;
wrapper.addChild(bmp);
wrapper.transform.colorTransform = new ColorTransform();
cachedWrapper[attachment] = wrapper;
}
return cachedWrapper[attachment];
}
private function getGlobalCache(regionAttachment:RegionAttachment):Bitmap {
if (!regionAttachment['bitmap']) { // global spine cache
var region:AtlasRegion = AtlasRegion(regionAttachment.rendererObject);
var bitmapData:BitmapData = region.page.rendererObject as BitmapData;
var regionWidth:Number = region.rotate ? region.height : region.width;
var regionHeight:Number = region.rotate ? region.width : region.height;
var regionData:BitmapData = new BitmapData(regionWidth, regionHeight);
regionData.copyPixels(bitmapData, new Rectangle(region.x, region.y, regionWidth, regionHeight), new Point());
var bitmap:Bitmap = new Bitmap(regionData);
bitmap.smoothing = true;
// Rotate and scale using default registration point (top left corner, y-down, CW) instead of image center.
bitmap.rotation = -regionAttachment.rotation;
bitmap.scaleX = regionAttachment.scaleX * (regionAttachment.width / region.width);
bitmap.scaleY = regionAttachment.scaleY * (regionAttachment.height / region.height);
// Position using attachment translation, shifted as if scale and rotation were at image center.
var radians:Number = -regionAttachment.rotation * Math.PI / 180;
var cos:Number = Math.cos(radians);
var sin:Number = Math.sin(radians);
var shiftX:Number = -regionAttachment.width / 2 * regionAttachment.scaleX;
var shiftY:Number = -regionAttachment.height / 2 * regionAttachment.scaleY;
if (region.rotate) {
bitmap.rotation += 90;
shiftX += regionHeight * (regionAttachment.width / region.width);
}
bitmap.x = regionAttachment.x + shiftX * cos - shiftY * sin;
bitmap.y = -regionAttachment.y + shiftX * sin + shiftY * cos;
regionAttachment['bitmap'] = bitmap;
}
return regionAttachment['bitmap'];
}
public function get skeleton () : Skeleton {
return _skeleton;
}
}
}