mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
Merge branch '4.1' into 4.2-beta
This commit is contained in:
commit
24f47cf8ce
@ -13,7 +13,7 @@ In most cases, the `spine-player` module is best suited for your needs. Please r
|
||||
|
||||
For documentation of the core API in `spine-core`, please refer to our [Spine Runtimes Guide](http://esotericsoftware.com/spine-runtimes-guide).
|
||||
|
||||
For module specific APIs in `spine-canvas`, `spine-webgl`, and `spine-threejs`, please refer to the [Examples](#examples) in the respecitve `spine-<modulename>/example` folder. For `spine-webgl` specifically, we have provided additional [demos](spine-webgl/demos), which you can also [view online](http://de.esotericsoftware.com/spine-demos).
|
||||
For module specific APIs in `spine-canvas`, `spine-webgl`, and `spine-threejs`, please refer to the [Examples](#examples) in the respecitve `spine-<modulename>/example` folder. For `spine-webgl` specifically, we have provided additional [demos](spine-webgl/demos), which you can also [view online](http://esotericsoftware.com/spine-demos).
|
||||
|
||||
## Licensing
|
||||
|
||||
|
||||
@ -22,9 +22,19 @@
|
||||
<li>Pixi</li>
|
||||
<ul>
|
||||
<li><a href="/spine-pixi/example/index.html">Basic example</a></li>
|
||||
<li><a href="/spine-pixi/example/manual-loading.html">Manual Loading</a></li>
|
||||
<li>
|
||||
<a href="/spine-pixi/example/events-example.html">Events example</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-pixi/example/mix-and-match-example.html">Mix and match example</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-pixi/example/simple-input.html">Simple input</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-pixi/example/mouse-following.html">Mouse following</a>
|
||||
</li>
|
||||
</ul>
|
||||
<li>Phaser</li>
|
||||
<ul>
|
||||
@ -33,8 +43,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-phaser/example/events-example.html"
|
||||
>Events example</a
|
||||
>
|
||||
>Events example</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-phaser/example/mix-and-match-example.html"
|
||||
|
||||
@ -5,27 +5,22 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<!-- Creates a transparent logging overlay. -->
|
||||
<div id="log" class="overlay" style="user-select: none;" max-height: 300px; overflow: auto;>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function log(message) {
|
||||
const log = document.querySelector("#log");
|
||||
log.innerText += message + "\n";
|
||||
log.scrollTop = log.scrollHeight;
|
||||
console.log(message);
|
||||
}
|
||||
|
||||
(async function () {
|
||||
var app = new PIXI.Application({
|
||||
width: window.innerWidth,
|
||||
@ -43,11 +38,33 @@
|
||||
PIXI.Assets.add("spineboyAtlas", "./assets/spineboy-pma.atlas");
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
// Create the Spine display object
|
||||
const spineboy = spine.Spine.from("spineboyData", "spineboyAtlas", {
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
// Set animation "run" on track 0, looped.
|
||||
spineboy.state.setAnimation(0, "run", true);
|
||||
|
||||
// Set callbacks to receive animation state events.
|
||||
spineboy.state.addListener({
|
||||
start: (entry) => log(`Started animation ${entry.animation.name}`),
|
||||
interrupt: (entry) => log(`Interrupted animation ${entry.animation.name}`),
|
||||
end: (entry) => log(`Ended animation ${entry.animation.name}`),
|
||||
dispose: (entry) => log(`Disposed animation ${entry.animation.name}`),
|
||||
complete: (entry) => log(`Completed animation ${entry.animation.name}`),
|
||||
});
|
||||
|
||||
// Add a custom event listener along with an
|
||||
// unlooped animation to see the custom event logged.
|
||||
const trackEntry = spineboy.state.addAnimation(0, "walk", false, 3);
|
||||
trackEntry.listener = {
|
||||
event: (entry, event) =>
|
||||
log(`Custom event for ${entry.animation.name}: ${event.data.name}`),
|
||||
};
|
||||
|
||||
spineboy.state.addAnimation(0, "run", true, 0);
|
||||
|
||||
// Set the default mix time to use when transitioning
|
||||
// from one animation to the next.
|
||||
spineboy.state.data.defaultMix = 0.2;
|
||||
@ -56,11 +73,6 @@
|
||||
spineboy.x = window.innerWidth / 2;
|
||||
spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
|
||||
|
||||
// Set animation "run" on track 0, looped.
|
||||
spineboy.state.setAnimation(0, "run", true);
|
||||
|
||||
// Set callbacks to receive animation state events
|
||||
|
||||
// Add the display object to the stage.
|
||||
app.stage.addChild(spineboy);
|
||||
})();
|
||||
|
||||
@ -5,24 +5,8 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
@ -64,4 +48,4 @@
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@ -5,24 +5,8 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
|
||||
68
spine-ts/spine-pixi/example/mix-and-match-example.html
Normal file
68
spine-ts/spine-pixi/example/mix-and-match-example.html
Normal file
@ -0,0 +1,68 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>spine-pixi</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
(async function () {
|
||||
var app = new PIXI.Application({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
resolution: window.devicePixelRatio || 1,
|
||||
autoDensity: true,
|
||||
resizeTo: window,
|
||||
backgroundColor: 0x2c3e50,
|
||||
hello: true,
|
||||
});
|
||||
document.body.appendChild(app.view);
|
||||
|
||||
// Pre-load the skeleton data and atlas. You can also load .json skeleton data.
|
||||
PIXI.Assets.add("mixAndMatchData", "./assets/mix-and-match-pro.skel");
|
||||
PIXI.Assets.add("mixAndMatchAtlas", "./assets/mix-and-match-pma.atlas");
|
||||
await PIXI.Assets.load(["mixAndMatchData", "mixAndMatchAtlas"]);
|
||||
|
||||
// Create the Spine display object
|
||||
const mixAndMatch = spine.Spine.from("mixAndMatchData", "mixAndMatchAtlas", {
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
// Set the default mix time to use when transitioning
|
||||
// from one animation to the next.
|
||||
mixAndMatch.state.data.defaultMix = 0.2;
|
||||
|
||||
// Center the spine object on screen.
|
||||
mixAndMatch.x = window.innerWidth / 2;
|
||||
mixAndMatch.y = window.innerHeight / 2 + mixAndMatch.getBounds().height / 2;
|
||||
|
||||
// Add animations.
|
||||
mixAndMatch.state.setAnimation(0, "walk", true);
|
||||
mixAndMatch.state.addAnimation(0, "dance", true, 1.0);
|
||||
mixAndMatch.state.addAnimation(0, "walk", true, 1.0);
|
||||
|
||||
// Add a custom skin
|
||||
const skeletonData = mixAndMatch.skeleton.data;
|
||||
const skin = new spine.Skin("custom");
|
||||
skin.addSkin(skeletonData.findSkin("nose/short"));
|
||||
skin.addSkin(skeletonData.findSkin("skin-base"));
|
||||
skin.addSkin(skeletonData.findSkin("eyes/violet"));
|
||||
skin.addSkin(skeletonData.findSkin("hair/brown"));
|
||||
skin.addSkin(skeletonData.findSkin("clothes/hoodie-orange"));
|
||||
skin.addSkin(skeletonData.findSkin("legs/pants-jeans"));
|
||||
skin.addSkin(skeletonData.findSkin("accessories/bag"));
|
||||
skin.addSkin(skeletonData.findSkin("accessories/hat-red-yellow"));
|
||||
skin.addSkin(skeletonData.findSkin("eyelids/girly"));
|
||||
mixAndMatch.skeleton.setSkin(skin);
|
||||
mixAndMatch.skeleton.setSlotsToSetupPose();
|
||||
|
||||
// Add the display object to the stage.
|
||||
app.stage.addChild(mixAndMatch);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
90
spine-ts/spine-pixi/example/mouse-following.html
Normal file
90
spine-ts/spine-pixi/example/mouse-following.html
Normal file
@ -0,0 +1,90 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Spine Pixi Example</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
(async function () {
|
||||
var app = new PIXI.Application({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
resolution: window.devicePixelRatio || 1,
|
||||
autoDensity: true,
|
||||
resizeTo: window,
|
||||
backgroundColor: 0x2c3e50,
|
||||
hello: true,
|
||||
});
|
||||
document.body.appendChild(app.view);
|
||||
|
||||
// Pre-load the skeleton data and atlas. You can also load .json skeleton data.
|
||||
PIXI.Assets.add("spineboyData", "./assets/spineboy-pro.skel");
|
||||
PIXI.Assets.add("spineboyAtlas", "./assets/spineboy-pma.atlas");
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from("spineboyData", "spineboyAtlas", {
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
// Set the default mix time to use when transitioning
|
||||
// from one animation to another.
|
||||
spineboy.state.data.defaultMix = 0.2;
|
||||
|
||||
// Center the Spine object on screen.
|
||||
spineboy.x = window.innerWidth / 2;
|
||||
spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
|
||||
|
||||
// Set looping animations "idle" on track 0 and "aim" on track 1.
|
||||
spineboy.state.setAnimation(0, "idle", true);
|
||||
spineboy.state.setAnimation(1, "aim", true);
|
||||
|
||||
// Add the display object to the stage.
|
||||
app.stage.addChild(spineboy);
|
||||
|
||||
// Make the stage interactive and register pointer events
|
||||
app.stage.eventMode = "dynamic";
|
||||
let isDragging = false;
|
||||
|
||||
app.stage.on("pointerdown", (e) => {
|
||||
isDragging = true;
|
||||
setBonePosition(e);
|
||||
});
|
||||
|
||||
app.stage.on("pointermove", (e) => {
|
||||
if (isDragging) setBonePosition(e);
|
||||
});
|
||||
|
||||
app.stage.on("pointerup", (e) => (isDragging = false));
|
||||
|
||||
const setBonePosition = (e) => {
|
||||
// Transform the mouse/touch coordinates to Spineboy's coordinate
|
||||
// system origin. `position` is then relative to Spineboy's root
|
||||
// bone.
|
||||
const position = new spine.Vector2(
|
||||
e.data.global.x - spineboy.x,
|
||||
e.data.global.y - spineboy.y
|
||||
);
|
||||
|
||||
// Find the crosshair bone.
|
||||
const crosshairBone = spineboy.skeleton.findBone("crosshair");
|
||||
|
||||
// Take the mouse position, which is relative to the root bone,
|
||||
// and transform it to the crosshair bone's parent root bone
|
||||
// coordinate system via `worldToLocal()`. `position` is relative
|
||||
// to the crosshair bone's parent bone after this
|
||||
crosshairBone.parent.worldToLocal(position);
|
||||
|
||||
// Set the crosshair bone's position to the mouse position
|
||||
crosshairBone.x = position.x;
|
||||
crosshairBone.y = position.y;
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
62
spine-ts/spine-pixi/example/simple-input.html
Normal file
62
spine-ts/spine-pixi/example/simple-input.html
Normal file
@ -0,0 +1,62 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>spine-pixi</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2.4/dist/pixi.min.js"></script>
|
||||
<script src="../dist/iife/spine-pixi.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tweakpane@3.1.9/dist/tweakpane.min.js"></script>
|
||||
<link rel="stylesheet" href="../../index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
(async function () {
|
||||
var app = new PIXI.Application({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
resolution: window.devicePixelRatio || 1,
|
||||
autoDensity: true,
|
||||
resizeTo: window,
|
||||
backgroundColor: 0x2c3e50,
|
||||
hello: true,
|
||||
});
|
||||
document.body.appendChild(app.view);
|
||||
|
||||
// Pre-load the skeleton data and atlas. You can also load .json skeleton data.
|
||||
PIXI.Assets.add("spineboyData", "./assets/spineboy-pro.skel");
|
||||
PIXI.Assets.add("spineboyAtlas", "./assets/spineboy-pma.atlas");
|
||||
await PIXI.Assets.load(["spineboyData", "spineboyAtlas"]);
|
||||
|
||||
// Create the spine display object
|
||||
const spineboy = spine.Spine.from("spineboyData", "spineboyAtlas", {
|
||||
scale: 0.5,
|
||||
});
|
||||
|
||||
// Set the default animation and the
|
||||
// default mix for transitioning between animations.
|
||||
spineboy.state.setAnimation(0, "run", true);
|
||||
spineboy.state.data.defaultMix = 0.2;
|
||||
|
||||
// Center the spine object on screen.
|
||||
spineboy.x = window.innerWidth / 2;
|
||||
spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
|
||||
|
||||
// Make it so that you can interact with Spineboy.
|
||||
// Also, handle the case that you click or tap on the screen.
|
||||
// The callback function definition can be seen below.
|
||||
spineboy.eventMode = 'static';
|
||||
spineboy.on('pointerdown', onClick);
|
||||
|
||||
// Add the display object to the stage.
|
||||
app.stage.addChild(spineboy);
|
||||
|
||||
// This callback function handles what happens
|
||||
// when you click or tap on the screen.
|
||||
function onClick() {
|
||||
spineboy.state.addAnimation(0, "jump", false, 0);
|
||||
spineboy.state.addAnimation(0, "idle", true, 0);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -33,6 +33,9 @@
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "spine/spine.h"
|
||||
#include "UObject/ConstructorHelpers.h"
|
||||
#if ENGINE_MAJOR_VERSION >= 5
|
||||
#include "PhysicsEngine/BodySetup.h"
|
||||
#endif
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Spine"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user