mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-10 17:18:44 +08:00
223 lines
7.4 KiB
Haxe
223 lines
7.4 KiB
Haxe
/******************************************************************************
|
|
* Spine Runtimes License Agreement
|
|
* Last updated April 5, 2025. Replaces all prior versions.
|
|
*
|
|
* Copyright (c) 2013-2025, Esoteric Software LLC
|
|
*
|
|
* Integration of the Spine Runtimes into software or otherwise creating
|
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
|
* conditions of Section 2 of the Spine Editor License Agreement:
|
|
* http://esotericsoftware.com/spine-editor-license
|
|
*
|
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
|
* "Products"), provided that each user of the Products must obtain their own
|
|
* Spine Editor license and redistribution of the Products in any form must
|
|
* include this license and copyright notice.
|
|
*
|
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 SOFTWARE LLC BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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
|
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*****************************************************************************/
|
|
|
|
package flixelExamples;
|
|
|
|
import flixel.ui.FlxButton;
|
|
import flixel.group.FlxSpriteGroup;
|
|
import flixel.FlxSprite;
|
|
import flixel.graphics.FlxGraphic;
|
|
import spine.animation.AnimationStateData;
|
|
import openfl.Assets;
|
|
import spine.atlas.TextureAtlas;
|
|
import spine.SkeletonData;
|
|
import spine.flixel.SkeletonSprite;
|
|
import spine.flixel.FlixelTextureLoader;
|
|
import flixel.FlxG;
|
|
import flixel.FlxState;
|
|
import flixel.text.FlxText;
|
|
|
|
class FlixelState extends FlxState {
|
|
var spineSprite:SkeletonSprite;
|
|
var sprite:FlxSprite;
|
|
var sprite2:FlxSprite;
|
|
var myText:FlxText;
|
|
var group:FlxSpriteGroup;
|
|
var justSetWalking = false;
|
|
|
|
var jumping = false;
|
|
|
|
var scale = 4;
|
|
var speed:Float;
|
|
|
|
override public function create():Void {
|
|
FlxG.cameras.bgColor = 0xffa1b2b0;
|
|
|
|
// setting speed of spineboy (450 is the speed to not let him slide)
|
|
speed = 450 / scale;
|
|
|
|
// creating a group
|
|
group = new FlxSpriteGroup();
|
|
group.setPosition(50, 50);
|
|
add(group);
|
|
|
|
// creating the sprite to check overlapping
|
|
sprite = new FlxSprite();
|
|
sprite.loadGraphic(FlxGraphic.fromRectangle(150, 100, 0xff8d008d));
|
|
group.add(sprite);
|
|
|
|
// creating the text to display overlapping state
|
|
myText = new FlxText(0, 25, 150, "", 16);
|
|
myText.alignment = CENTER;
|
|
group.add(myText);
|
|
|
|
var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new BasicExample()));
|
|
button.setPosition(FlxG.width * .75, FlxG.height / 10);
|
|
add(button);
|
|
|
|
// creating a sprite for the floor
|
|
var floor = new FlxSprite();
|
|
floor.loadGraphic(FlxGraphic.fromRectangle(FlxG.width, FlxG.height - 100, 0xff822f02));
|
|
floor.y = FlxG.height - 100;
|
|
add(floor);
|
|
|
|
// instructions
|
|
var groupInstructions = new FlxSpriteGroup();
|
|
groupInstructions.setPosition(50, 405);
|
|
groupInstructions.add(new FlxText(0, 0, 200, "Left/Right - Move", 16));
|
|
groupInstructions.add(new FlxText(0, 25, 150, "Space - Jump", 16));
|
|
groupInstructions.add(new FlxText(200, 25, 400, "Click the button for the next example", 16));
|
|
add(groupInstructions);
|
|
|
|
// loading spineboy
|
|
var atlas = new TextureAtlas(Assets.getText("assets/spineboy.atlas"), new FlixelTextureLoader("assets/spineboy.atlas"));
|
|
var skeletondata = SkeletonData.from(Assets.getText("assets/spineboy-pro.json"), atlas, 1 / scale);
|
|
var animationStateData = new AnimationStateData(skeletondata);
|
|
spineSprite = new SkeletonSprite(skeletondata, animationStateData);
|
|
|
|
// positioning spineboy
|
|
spineSprite.setPosition(.5 * FlxG.width, .5 * FlxG.height);
|
|
|
|
// setting mix times
|
|
animationStateData.defaultMix = 0.5;
|
|
animationStateData.setMixByName("idle", "walk", 0.1);
|
|
animationStateData.setMixByName("walk", "idle", 0.1);
|
|
animationStateData.setMixByName("idle", "idle-turn", 0.05);
|
|
animationStateData.setMixByName("idle-turn", "idle", 0.05);
|
|
animationStateData.setMixByName("idle-turn", "walk", 0.3);
|
|
animationStateData.setMixByName("idle", "jump", 0);
|
|
animationStateData.setMixByName("jump", "idle", 0.05);
|
|
animationStateData.setMixByName("jump", "walk", 0.05);
|
|
animationStateData.setMixByName("walk", "jump", 0.05);
|
|
|
|
// setting idle animation
|
|
spineSprite.state.setAnimationByName(0, "idle", true);
|
|
|
|
// setting y offset function to move object body while jumping
|
|
var hip = spineSprite.skeleton.findBone("hip");
|
|
var initialY = 0.;
|
|
var initialOffsetY = 0.;
|
|
spineSprite.state.onStart.add(entry -> {
|
|
if (entry.animation.name == "jump") {
|
|
initialY = spineSprite.y;
|
|
initialOffsetY = spineSprite.offsetY;
|
|
}
|
|
});
|
|
spineSprite.state.onComplete.add(entry -> {
|
|
if (entry.animation.name == "jump") {
|
|
jumping = false;
|
|
spineSprite.y = initialY;
|
|
spineSprite.offsetY = initialOffsetY;
|
|
}
|
|
});
|
|
var diff = .0;
|
|
spineSprite.afterUpdateWorldTransforms = spineSprite -> {
|
|
if (jumping) {
|
|
diff -= hip.pose.y;
|
|
spineSprite.offsetY -= diff;
|
|
spineSprite.y += diff;
|
|
}
|
|
diff = hip.pose.y;
|
|
}
|
|
|
|
// adding spineboy to the stage
|
|
add(spineSprite);
|
|
|
|
// FlxG.debugger.visible = !FlxG.debugger.visible;
|
|
// debug ui
|
|
// FlxG.debugger.visible = true;
|
|
// FlxG.debugger.drawDebug = true;
|
|
// FlxG.log.redirectTraces = true;
|
|
|
|
// FlxG.debugger.track(spineSprite);
|
|
// FlxG.watch.add(spineSprite, "width");
|
|
// FlxG.watch.add(spineSprite, "offsetY");
|
|
// FlxG.watch.add(spineSprite, "y");
|
|
// FlxG.watch.add(this, "jumping");
|
|
super.create();
|
|
}
|
|
|
|
var justSetIdle = true;
|
|
|
|
override public function update(elapsed:Float):Void {
|
|
if (FlxG.overlap(spineSprite, group)) {
|
|
myText.text = "Overlapping";
|
|
} else {
|
|
myText.text = "Non overlapping";
|
|
}
|
|
|
|
if (!jumping && FlxG.keys.anyJustPressed([SPACE])) {
|
|
spineSprite.state.setAnimationByName(0, "jump", false);
|
|
jumping = true;
|
|
justSetIdle = false;
|
|
justSetWalking = false;
|
|
}
|
|
|
|
if (FlxG.keys.anyJustPressed([J])) {
|
|
// spineSprite.antialiasing = !spineSprite.antialiasing;
|
|
FlxG.debugger.visible = !FlxG.debugger.visible;
|
|
}
|
|
|
|
if (FlxG.keys.anyPressed([RIGHT, LEFT])) {
|
|
justSetIdle = false;
|
|
var flipped = false;
|
|
var deltaX;
|
|
if (FlxG.keys.anyPressed([RIGHT])) {
|
|
if (spineSprite.flipX == true)
|
|
flipped = true;
|
|
spineSprite.flipX = false;
|
|
}
|
|
if (FlxG.keys.anyPressed([LEFT])) {
|
|
if (spineSprite.flipX == false)
|
|
flipped = true;
|
|
spineSprite.flipX = true;
|
|
}
|
|
|
|
deltaX = (spineSprite.flipX == false ? 1 : -1) * speed * elapsed;
|
|
spineSprite.x += deltaX;
|
|
|
|
if (!jumping && !justSetWalking) {
|
|
justSetWalking = true;
|
|
if (flipped) {
|
|
spineSprite.state.setAnimationByName(0, "idle-turn", false);
|
|
spineSprite.state.addAnimationByName(0, "walk", true, 0);
|
|
} else {
|
|
spineSprite.state.setAnimationByName(0, "walk", true);
|
|
}
|
|
}
|
|
} else if (!jumping && !justSetIdle) {
|
|
justSetWalking = false;
|
|
justSetIdle = true;
|
|
spineSprite.state.setAnimationByName(0, "idle", true);
|
|
}
|
|
|
|
super.update(elapsed);
|
|
}
|
|
}
|