Fixed spine-starling rendering.

This commit is contained in:
NathanSweet 2013-05-01 10:25:46 +02:00
parent 131cdbd576
commit 4838ebf4ef
5 changed files with 78 additions and 81 deletions

1
.gitignore vendored
View File

@ -55,3 +55,4 @@ spine-love/love/
spine-as3/bin spine-as3/bin
spine-starling/spine-starling/bin spine-starling/spine-starling/bin
spine-starling/spine-starling-example/bin-debug spine-starling/spine-starling-example/bin-debug
spine-starling/spine-starling-example/bin-release

View File

@ -1,23 +1,30 @@
package { package {
import spine.AnimationStateData;
import spine.SkeletonAnimationSprite; import spine.SkeletonAnimationSprite;
import spine.SkeletonData; import spine.SkeletonData;
import spine.StarlingSkeletonJson; import spine.StarlingSkeletonJson;
import starling.core.Starling;
import starling.display.Sprite; import starling.display.Sprite;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.textures.Texture; import starling.textures.Texture;
import starling.textures.TextureAtlas; import starling.textures.TextureAtlas;
public class Game extends Sprite { public class Game extends Sprite {
[Embed(source = "spineboy.xml", mimeType = "application/octet-stream")] [Embed(source = "spineboy.xml", mimeType = "application/octet-stream")]
static public const SpineboyAtlasXml:Class; static public const SpineboyAtlasXml:Class;
[Embed(source = "spineboy.png")] [Embed(source = "spineboy.png")]
static public const SpineboyAtlasTexture:Class; static public const SpineboyAtlasTexture:Class;
[Embed(source = "spineboy.json", mimeType = "application/octet-stream")] [Embed(source = "spineboy.json", mimeType = "application/octet-stream")]
static public const SpineboyJson:Class; static public const SpineboyJson:Class;
private var skeleton:SkeletonAnimationSprite;
public function Game () { public function Game () {
var texture:Texture = Texture.fromBitmap(new SpineboyAtlasTexture()); var texture:Texture = Texture.fromBitmap(new SpineboyAtlasTexture());
var xml:XML = XML(new SpineboyAtlasXml()); var xml:XML = XML(new SpineboyAtlasXml());
@ -26,13 +33,31 @@ public class Game extends Sprite {
var json:StarlingSkeletonJson = new StarlingSkeletonJson(atlas); var json:StarlingSkeletonJson = new StarlingSkeletonJson(atlas);
var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson()); var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson());
var skeleton:SkeletonAnimationSprite = new SkeletonAnimationSprite(skeletonData); var stateData:AnimationStateData = new AnimationStateData(skeletonData);
stateData.setMixByName("walk", "jump", 0.2);
stateData.setMixByName("jump", "walk", 0.4);
stateData.setMixByName("jump", "jump", 0.2);
skeleton = new SkeletonAnimationSprite(skeletonData);
skeleton.setAnimationStateData(stateData);
skeleton.x = 320; skeleton.x = 320;
skeleton.y = 420; skeleton.y = 420;
skeleton.width = 100;
skeleton.height = 100;
skeleton.setAnimation("walk", true); skeleton.setAnimation("walk", true);
skeleton.addAnimation("jump", false, 3);
skeleton.addAnimation("walk", true);
addChild(skeleton); addChild(skeleton);
Starling.juggler.add(skeleton);
addEventListener(TouchEvent.TOUCH, onClick);
}
private function onClick (event:TouchEvent) : void {
var touch:Touch = event.getTouch(this);
if (touch && touch.phase == TouchPhase.BEGAN) {
skeleton.setAnimation("jump", false);
skeleton.addAnimation("walk", true);
}
} }
} }
} }

View File

@ -1,9 +1,4 @@
package spine { package spine {
import spine.AnimationState;
import spine.AnimationStateData;
import spine.SkeletonData;
import starling.events.EnterFrameEvent;
public class SkeletonAnimationSprite extends SkeletonSprite { public class SkeletonAnimationSprite extends SkeletonSprite {
public var states:Vector.<AnimationState> = new Vector.<AnimationState>(); public var states:Vector.<AnimationState> = new Vector.<AnimationState>();
@ -13,12 +8,11 @@ public class SkeletonAnimationSprite extends SkeletonSprite {
addAnimationState(); addAnimationState();
} }
override protected function onEnterFrame (event:EnterFrameEvent) : void { override public function advanceTime (time:Number) : void {
super.onEnterFrame(event); super.advanceTime(time);
var deltaTime:Number = event.passedTime * timeScale;
for each (var state:AnimationState in states) { for each (var state:AnimationState in states) {
state.update(deltaTime); state.update(time);
state.apply(skeleton); state.apply(skeleton);
} }
skeleton.updateWorldTransform(); skeleton.updateWorldTransform();

View File

@ -13,6 +13,10 @@ public class SkeletonImage extends Image {
return mVertexData; return mVertexData;
} }
public function updateVertices () : void {
onVertexDataChanged();
}
override public function get tinted () : Boolean { override public function get tinted () : Boolean {
return true; return true;
} }

View File

@ -3,36 +3,27 @@ import flash.geom.Matrix;
import flash.geom.Point; import flash.geom.Point;
import flash.geom.Rectangle; import flash.geom.Rectangle;
import spine.Bone;
import spine.Skeleton;
import spine.SkeletonData;
import spine.Slot;
import spine.attachments.RegionAttachment; import spine.attachments.RegionAttachment;
import starling.animation.IAnimatable;
import starling.core.RenderSupport; import starling.core.RenderSupport;
import starling.display.DisplayObject; import starling.display.DisplayObject;
import starling.events.EnterFrameEvent;
import starling.events.Event;
import starling.utils.MatrixUtil;
public class SkeletonSprite extends DisplayObject { public class SkeletonSprite extends DisplayObject implements IAnimatable {
static private var tempPoint:Point = new Point(); static private var tempPoint:Point = new Point();
static private var tempMatrix:Matrix = new Matrix(); static private var tempMatrix:Matrix = new Matrix();
private var _skeleton:Skeleton; private var _skeleton:Skeleton;
public var timeScale:Number = 1;
public function SkeletonSprite (skeletonData:SkeletonData) { public function SkeletonSprite (skeletonData:SkeletonData) {
_skeleton = new Skeleton(skeletonData); _skeleton = new Skeleton(skeletonData);
_skeleton.updateWorldTransform(); _skeleton.updateWorldTransform();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
Bone.yDown = true; Bone.yDown = true;
} }
protected function onEnterFrame (event:EnterFrameEvent) : void { public function advanceTime (time:Number) : void {
_skeleton.update(event.passedTime * timeScale); _skeleton.update(time);
} }
override public function render (support:RenderSupport, alpha:Number) : void { override public function render (support:RenderSupport, alpha:Number) : void {
@ -79,16 +70,18 @@ public class SkeletonSprite extends DisplayObject {
vertexData[28] = b; vertexData[28] = b;
vertexData[29] = a; vertexData[29] = a;
image.updateVertices();
support.batchQuad(image, alpha, image.texture); support.batchQuad(image, alpha, image.texture);
} }
} }
} }
override public function getBounds (targetSpace:DisplayObject, resultRect:Rectangle = null) : Rectangle { override public function hitTest (localPoint:Point, forTouch:Boolean = false) : DisplayObject {
if (forTouch && (!visible || !touchable))
return null;
var minX:Number = Number.MAX_VALUE, minY:Number = Number.MAX_VALUE; var minX:Number = Number.MAX_VALUE, minY:Number = Number.MAX_VALUE;
var maxX:Number = Number.MIN_VALUE, maxY:Number = Number.MIN_VALUE; var maxX:Number = Number.MIN_VALUE, maxY:Number = Number.MIN_VALUE;
var scaleX:Number = this.scaleX;
var scaleY:Number = this.scaleY;
var slots:Vector.<Slot> = skeleton.slots; var slots:Vector.<Slot> = skeleton.slots;
var value:Number; var value:Number;
for (var i:int = 0, n:int = slots.length; i < n; i++) { for (var i:int = 0, n:int = slots.length; i < n; i++) {
@ -100,102 +93,82 @@ public class SkeletonSprite extends DisplayObject {
regionAttachment.updateVertices(slot.bone); regionAttachment.updateVertices(slot.bone);
var vertices:Vector.<Number> = regionAttachment.vertices; var vertices:Vector.<Number> = regionAttachment.vertices;
value = vertices[0] * scaleX; value = vertices[0];
if (value < minX) if (value < minX)
minX = value; minX = value;
if (value > maxX) if (value > maxX)
maxX = value; maxX = value;
value = vertices[1] * scaleY; value = vertices[1];
if (value < minY) if (value < minY)
minY = value; minY = value;
if (value > maxY) if (value > maxY)
maxY = value; maxY = value;
value = vertices[2] * scaleX; value = vertices[2];
if (value < minX) if (value < minX)
minX = value; minX = value;
if (value > maxX) if (value > maxX)
maxX = value; maxX = value;
value = vertices[3] * scaleY; value = vertices[3];
if (value < minY) if (value < minY)
minY = value; minY = value;
if (value > maxY) if (value > maxY)
maxY = value; maxY = value;
value = vertices[4] * scaleX; value = vertices[4];
if (value < minX) if (value < minX)
minX = value; minX = value;
if (value > maxX) if (value > maxX)
maxX = value; maxX = value;
value = vertices[5] * scaleY; value = vertices[5];
if (value < minY) if (value < minY)
minY = value; minY = value;
if (value > maxY) if (value > maxY)
maxY = value; maxY = value;
value = vertices[6] * scaleX; value = vertices[6];
if (value < minX) if (value < minX)
minX = value; minX = value;
if (value > maxX) if (value > maxX)
maxX = value; maxX = value;
value = vertices[7] * scaleY; value = vertices[7];
if (value < minY) if (value < minY)
minY = value; minY = value;
if (value > maxY) if (value > maxY)
maxY = value; maxY = value;
} }
minX *= scaleX;
maxX *= scaleX;
minY *= scaleY;
maxY *= scaleY;
var temp:Number;
if (maxX < minX) {
temp = maxX;
maxX = minX;
minX = temp;
}
if (maxY < minY) {
temp = maxY;
maxY = minY;
minY = temp;
}
if (localPoint.x >= minX && localPoint.x < maxX && localPoint.y >= minY && localPoint.y < maxY)
return this;
return null;
}
override public function getBounds (targetSpace:DisplayObject, resultRect:Rectangle = null) : Rectangle {
if (!resultRect) if (!resultRect)
resultRect = new Rectangle(); resultRect = new Rectangle();
// FIXME
resultRect.setTo(0, 0, 0, 0); resultRect.setTo(0, 0, 0, 0);
return resultRect; return resultRect;
// No idea why the below makes rendering very small. :( Returning 0,0 0x0 renders fine??
if (targetSpace == this) {
resultRect.x = minX;
resultRect.y = minY;
resultRect.width = maxX - minX;
resultRect.height = maxY - minY;
} else if (targetSpace == parent && rotation == 0.0) {
resultRect.x = x + minX - pivotX * scaleX;
resultRect.y = y + minY - pivotY * scaleY;
resultRect.width = (maxX - minX) * scaleX;
resultRect.height = (maxY - minY) * scaleY;
if (scaleX < 0) {
resultRect.width *= -1;
resultRect.x -= resultRect.width;
}
if (scaleY < 0) {
resultRect.height *= -1;
resultRect.y -= resultRect.height;
}
} else {
getTransformationMatrix(targetSpace, tempMatrix);
MatrixUtil.transformCoords(tempMatrix, minX, minY, tempPoint);
minX = tempPoint.x;
minY = tempPoint.y;
MatrixUtil.transformCoords(tempMatrix, maxX, maxY, tempPoint);
if (minX > tempPoint.x) {
maxX = minX;
minX = tempPoint.x;
} else
maxX = tempPoint.x;
if (minY > tempPoint.y) {
maxY = minY;
minY = tempPoint.y;
} else
maxY = tempPoint.y;
resultRect.x = minX;
resultRect.y = minY;
resultRect.width = maxX - minX;
resultRect.height = maxY - minY;
}
return resultRect;
} }
public function get skeleton () : Skeleton { public function get skeleton () : Skeleton {