diff --git a/spine-as3/spine-as3/src/spine/atlas/Atlas.as b/spine-as3/spine-as3/src/spine/atlas/Atlas.as index 8036807ee..d1b1f07e7 100644 --- a/spine-as3/spine-as3/src/spine/atlas/Atlas.as +++ b/spine-as3/spine-as3/src/spine/atlas/Atlas.as @@ -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]); } } diff --git a/spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as b/spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as index 67238b27a..292268b4f 100644 --- a/spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as +++ b/spine-as3/spine-as3/src/spine/atlas/AtlasRegion.as @@ -52,6 +52,7 @@ public class AtlasRegion { public var rotate:Boolean; public var splits:Vector.; public var pads:Vector.; + public var rendererObject:Object; } } diff --git a/spine-as3/spine-as3/src/spine/atlas/TextureLoader.as b/spine-as3/spine-as3/src/spine/atlas/TextureLoader.as index 1ea88d7c4..88a3ab5ea 100644 --- a/spine-as3/spine-as3/src/spine/atlas/TextureLoader.as +++ b/spine-as3/spine-as3/src/spine/atlas/TextureLoader.as @@ -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; } } diff --git a/spine-as3/spine-as3/src/spine/flash/SingleTextureLoader.as b/spine-as3/spine-as3/src/spine/flash/SingleTextureLoader.as index 1847f4883..0c303f38c 100644 --- a/spine-as3/spine-as3/src/spine/flash/SingleTextureLoader.as +++ b/spine-as3/spine-as3/src/spine/flash/SingleTextureLoader.as @@ -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(); } } diff --git a/spine-starling/spine-starling-example/src/AtlasExample.as b/spine-starling/spine-starling-example/src/AtlasExample.as new file mode 100644 index 000000000..e25f03355 --- /dev/null +++ b/spine-starling/spine-starling-example/src/AtlasExample.as @@ -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); + } + } +} +} diff --git a/spine-starling/spine-starling-example/src/Main.as b/spine-starling/spine-starling-example/src/Main.as index ab6b7c99d..08e618af1 100644 --- a/spine-starling/spine-starling-example/src/Main.as +++ b/spine-starling/spine-starling-example/src/Main.as @@ -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(); } } diff --git a/spine-starling/spine-starling-example/src/Game.as b/spine-starling/spine-starling-example/src/StarlingAtlasExample.as similarity index 92% rename from spine-starling/spine-starling-example/src/Game.as rename to spine-starling/spine-starling-example/src/StarlingAtlasExample.as index f2c93bc69..7efc309fc 100644 --- a/spine-starling/spine-starling-example/src/Game.as +++ b/spine-starling/spine-starling-example/src/StarlingAtlasExample.as @@ -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); diff --git a/spine-starling/spine-starling-example/src/spineboy-atlas.atlas b/spine-starling/spine-starling-example/src/spineboy-atlas.atlas new file mode 100644 index 000000000..3e1c84e4f --- /dev/null +++ b/spine-starling/spine-starling-example/src/spineboy-atlas.atlas @@ -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 diff --git a/spine-starling/spine-starling-example/src/spineboy-atlas.png b/spine-starling/spine-starling-example/src/spineboy-atlas.png new file mode 100644 index 000000000..c55c6af41 Binary files /dev/null and b/spine-starling/spine-starling-example/src/spineboy-atlas.png differ diff --git a/spine-starling/spine-starling-example/src/spineboy.png b/spine-starling/spine-starling-example/src/spineboy-starling.png similarity index 100% rename from spine-starling/spine-starling-example/src/spineboy.png rename to spine-starling/spine-starling-example/src/spineboy-starling.png diff --git a/spine-starling/spine-starling-example/src/spineboy.xml b/spine-starling/spine-starling-example/src/spineboy-starling.xml similarity index 100% rename from spine-starling/spine-starling-example/src/spineboy.xml rename to spine-starling/spine-starling-example/src/spineboy-starling.xml diff --git a/spine-starling/spine-starling/src/spine/starling/SingleTextureLoader.as b/spine-starling/spine-starling/src/spine/starling/SingleTextureLoader.as new file mode 100644 index 000000000..33c282a92 --- /dev/null +++ b/spine-starling/spine-starling/src/spine/starling/SingleTextureLoader.as @@ -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(); + } +} + +} diff --git a/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as b/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as index 12d62b8e8..ec97f5736 100644 --- a/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as +++ b/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as @@ -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);