Support for Atlas with spine-starling in addition to Starling's texture atlas.

This commit is contained in:
NathanSweet 2013-10-30 22:27:06 +01:00
parent 51a0876561
commit 725fd49c77
13 changed files with 325 additions and 16 deletions

View File

@ -87,7 +87,7 @@ public class Atlas {
else if (direction == "xy")
page.uWrap = page.vWrap = TextureWrap.repeat;
textureLoader.load(page, line);
textureLoader.loadPage(page, line);
pages.push(page);
@ -139,6 +139,7 @@ public class Atlas {
region.index = parseInt(reader.readValue());
textureLoader.loadRegion(region);
regions.push(region);
}
}
@ -156,7 +157,7 @@ public class Atlas {
public function dispose () : void {
for (var i:int = 0, n:int = pages.length; i < n; i++)
textureLoader.unload(pages[i].rendererObject);
textureLoader.unloadPage(pages[i]);
}
}

View File

@ -52,6 +52,7 @@ public class AtlasRegion {
public var rotate:Boolean;
public var splits:Vector.<int>;
public var pads:Vector.<int>;
public var rendererObject:Object;
}
}

View File

@ -34,8 +34,9 @@
package spine.atlas {
public interface TextureLoader {
function load (page:AtlasPage, path:String) : void;
function unload (texture:Object) : void;
function loadPage (page:AtlasPage, path:String) : void;
function loadRegion (region:AtlasRegion) : void;
function unloadPage (page:AtlasPage) : void;
}
}

View File

@ -36,6 +36,7 @@ import flash.display.Bitmap;
import flash.display.BitmapData;
import spine.atlas.AtlasPage;
import spine.atlas.AtlasRegion;
import spine.atlas.TextureLoader;
public class SingleTextureLoader implements TextureLoader {
@ -51,14 +52,17 @@ public class SingleTextureLoader implements TextureLoader {
throw new ArgumentError("object must be a Bitmap or BitmapData.");
}
public function load (page:AtlasPage, path:String) : void {
public function loadPage (page:AtlasPage, path:String) : void {
page.rendererObject = pageBitmapData;
page.width = pageBitmapData.width;
page.height = pageBitmapData.height;
}
public function loadRegion (region:AtlasRegion) : void {
}
public function unload (texture:Object) : void {
BitmapData(texture).dispose();
public function unloadPage (page:AtlasPage) : void {
BitmapData(page.rendererObject).dispose();
}
}

View File

@ -0,0 +1,79 @@
package {
import spine.Event;
import spine.SkeletonData;
import spine.SkeletonJson;
import spine.animation.AnimationStateData;
import spine.atlas.Atlas;
import spine.attachments.AtlasAttachmentLoader;
import spine.starling.SingleTextureLoader;
import spine.starling.SkeletonAnimation;
import spine.starling.StarlingAtlasAttachmentLoader;
import starling.core.Starling;
import starling.display.Sprite;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
public class AtlasExample extends Sprite {
[Embed(source = "spineboy-atlas.atlas", mimeType = "application/octet-stream")]
static public const SpineboyAtlasFile:Class;
[Embed(source = "spineboy-atlas.png")]
static public const SpineboyAtlasTexture:Class;
[Embed(source = "spineboy.json", mimeType = "application/octet-stream")]
static public const SpineboyJson:Class;
private var skeleton:SkeletonAnimation;
public function AtlasExample () {
var atlas:Atlas = new Atlas(new SpineboyAtlasFile(), new SingleTextureLoader(new SpineboyAtlasTexture()));
var json:SkeletonJson = new SkeletonJson(new AtlasAttachmentLoader(atlas));
var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson());
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 SkeletonAnimation(skeletonData, stateData);
skeleton.x = 320;
skeleton.y = 420;
skeleton.state.onStart = function (trackIndex:int) : void {
trace(trackIndex + " start: " + skeleton.state.getCurrent(trackIndex));
};
skeleton.state.onEnd = function (trackIndex:int) : void {
trace(trackIndex + " end: " + skeleton.state.getCurrent(trackIndex));
};
skeleton.state.onComplete = function (trackIndex:int, count:int) : void {
trace(trackIndex + " complete: " + skeleton.state.getCurrent(trackIndex) + ", " + count);
};
skeleton.state.onEvent = function (trackIndex:int, event:Event) : void {
trace(trackIndex + " event: " + skeleton.state.getCurrent(trackIndex) + ", "
+ event.data.name + ": " + event.intValue + ", " + event.floatValue + ", " + event.stringValue);
};
skeleton.state.setAnimationByName(0, "walk", true);
skeleton.state.addAnimationByName(0, "jump", false, 3);
skeleton.state.addAnimationByName(0, "walk", true, 0);
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.state.setAnimationByName(0, "jump", false);
skeleton.state.addAnimationByName(0, "walk", true, 0);
}
}
}
}

View File

@ -9,7 +9,7 @@ public class Main extends Sprite {
private var _starling:Starling;
public function Main () {
_starling = new Starling(Game, stage);
_starling = new Starling(AtlasExample, stage);
_starling.start();
}
}

View File

@ -15,11 +15,11 @@ import starling.events.TouchPhase;
import starling.textures.Texture;
import starling.textures.TextureAtlas;
public class Game extends Sprite {
[Embed(source = "spineboy.xml", mimeType = "application/octet-stream")]
public class StarlingAtlasExample extends Sprite {
[Embed(source = "spineboy-starling.xml", mimeType = "application/octet-stream")]
static public const SpineboyAtlasXml:Class;
[Embed(source = "spineboy.png")]
[Embed(source = "spineboy-starling.png")]
static public const SpineboyAtlasTexture:Class;
[Embed(source = "spineboy.json", mimeType = "application/octet-stream")]
@ -27,7 +27,7 @@ public class Game extends Sprite {
private var skeleton:SkeletonAnimation;
public function Game () {
public function StarlingAtlasExample () {
var texture:Texture = Texture.fromBitmap(new SpineboyAtlasTexture());
var xml:XML = XML(new SpineboyAtlasXml());
var atlas:TextureAtlas = new TextureAtlas(texture, xml);

View File

@ -0,0 +1,131 @@
spineboy.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
eyes
rotate: false
xy: 312, 24
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
eyes-closed
rotate: false
xy: 348, 24
size: 34, 27
orig: 34, 27
offset: 0, 0
index: -1
head
rotate: false
xy: 2, 2
size: 121, 132
orig: 121, 132
offset: 0, 0
index: -1
left-arm
rotate: true
xy: 217, 10
size: 35, 29
orig: 35, 29
offset: 0, 0
index: -1
left-foot
rotate: false
xy: 386, 55
size: 65, 30
orig: 65, 30
offset: 0, 0
index: -1
left-hand
rotate: false
xy: 125, 2
size: 35, 38
orig: 35, 38
offset: 0, 0
index: -1
left-lower-leg
rotate: true
xy: 320, 85
size: 49, 64
orig: 49, 64
offset: 0, 0
index: -1
left-shoulder
rotate: true
xy: 162, 6
size: 34, 53
orig: 34, 53
offset: 0, 0
index: -1
left-upper-leg
rotate: true
xy: 248, 55
size: 33, 67
orig: 33, 67
offset: 0, 0
index: -1
neck
rotate: true
xy: 282, 19
size: 34, 28
orig: 34, 28
offset: 0, 0
index: -1
pelvis
rotate: false
xy: 386, 87
size: 63, 47
orig: 63, 47
offset: 0, 0
index: -1
right-arm
rotate: true
xy: 195, 47
size: 21, 45
orig: 21, 45
offset: 0, 0
index: -1
right-foot
rotate: false
xy: 317, 53
size: 67, 30
orig: 67, 30
offset: 0, 0
index: -1
right-hand
rotate: false
xy: 248, 21
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
right-lower-leg
rotate: false
xy: 195, 70
size: 51, 64
orig: 51, 64
offset: 0, 0
index: -1
right-shoulder
rotate: false
xy: 386, 2
size: 52, 51
orig: 52, 51
offset: 0, 0
index: -1
right-upper-leg
rotate: true
xy: 248, 90
size: 44, 70
orig: 44, 70
offset: 0, 0
index: -1
torso
rotate: false
xy: 125, 42
size: 68, 92
orig: 68, 92
offset: 0, 0
index: -1

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -0,0 +1,87 @@
/******************************************************************************
* Spine Runtime Software License - Version 1.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* Redistribution and use in source and binary forms in whole or in part, with
* or without modification, are permitted provided that the following conditions
* are met:
*
* 1. A Spine Essential, Professional, Enterprise, or Education License must
* be purchased from Esoteric Software and the license must remain valid:
* http://esotericsoftware.com/
* 2. Redistributions of source code must retain this license, which is the
* above copyright notice, this declaration of conditions and the following
* disclaimer.
* 3. Redistributions in binary form must reproduce this license, which is the
* above copyright notice, this declaration of conditions and the following
* disclaimer, in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.starling {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;
import spine.atlas.AtlasPage;
import spine.atlas.AtlasRegion;
import spine.atlas.TextureLoader;
import starling.textures.SubTexture;
import starling.textures.Texture;
public class SingleTextureLoader implements TextureLoader {
private var pageBitmapData:BitmapData;
/** @param object A Bitmap or BitmapData. */
public function SingleTextureLoader (object:*) {
if (object is BitmapData)
pageBitmapData = BitmapData(object);
else if (object is Bitmap)
pageBitmapData = Bitmap(object).bitmapData;
else
throw new ArgumentError("object must be a Bitmap or BitmapData.");
}
public function loadPage (page:AtlasPage, path:String) : void {
page.rendererObject = Texture.fromBitmapData(pageBitmapData);
page.width = pageBitmapData.width;
page.height = pageBitmapData.height;
}
public function loadRegion (region:AtlasRegion) : void {
var image:SkeletonImage = new SkeletonImage(Texture(region.page.rendererObject));
if (region.rotate) {
image.setTexCoordsTo(0, region.u, region.v2);
image.setTexCoordsTo(1, region.u, region.v);
image.setTexCoordsTo(2, region.u2, region.v2);
image.setTexCoordsTo(3, region.u2, region.v);
} else {
image.setTexCoordsTo(0, region.u, region.v);
image.setTexCoordsTo(1, region.u2, region.v);
image.setTexCoordsTo(2, region.u, region.v2);
image.setTexCoordsTo(3, region.u2, region.v2);
}
region.rendererObject = image;
}
public function unloadPage (page:AtlasPage) : void {
BitmapData(pageBitmapData).dispose();
}
}
}

View File

@ -40,6 +40,8 @@ import spine.Bone;
import spine.Skeleton;
import spine.SkeletonData;
import spine.Slot;
import spine.atlas.AtlasPage;
import spine.atlas.AtlasRegion;
import spine.attachments.RegionAttachment;
import starling.animation.IAnimatable;
@ -87,12 +89,15 @@ public class SkeletonSprite extends DisplayObject implements IAnimatable {
var a:Number = slot.a;
var rgb:uint = Color.rgb(r * slot.r, g * slot.g, b * slot.b);
var image:SkeletonImage = regionAttachment.rendererObject as SkeletonImage;
var image:SkeletonImage;
image = regionAttachment.rendererObject as SkeletonImage;
if (image == null) image = SkeletonImage(AtlasRegion(regionAttachment.rendererObject).rendererObject);
var vertexData:VertexData = image.vertexData;
vertexData.setPosition(0, vertices[2], vertices[3]);
vertexData.setPosition(0, vertices[2], vertices[3]);
vertexData.setColorAndAlpha(0, rgb, a);
vertexData.setPosition(1, vertices[4], vertices[5]);
vertexData.setColorAndAlpha(1, rgb, a);