A Spine 4.x runtime integration for the melonJS game engine, using the official @esotericsoftware/spine-webgl and @esotericsoftware/spine-canvas runtimes.
Live Example — 15 official Spine characters including spineboy, raptor, owl, dragon, and more
SpineBatcher extending melonJS Batcher with two-color tinting and indexed drawingSkeleton.yDown runtime switch, including physics force direction vectors (windX/Y, gravityX/Y)setCombinedSkin()findBone(), findSlot(), findConstraint(), getAnimationNames(), getSkinNames()Slider/SliderData/SliderTimeline/SliderMixTimeline, plus IkConstraint, TransformConstraint, PathConstraint, PhysicsConstraint) re-exported for one-import instanceof narrowing of findConstraint() resultssetAnimation(), addAnimation(), setEmptyAnimation()This plugin is already bundled with the required Spine 4.x runtime, so there is no need to install it separately.
Note: this plugin requires melonJS version 20.0.0 or higher.
To install the plugin using npm:
$ npm install @melonjs/spine-plugin
Then import and use the plugin in your project. For example:
import Spine, { SpinePlugin } from '@melonjs/spine-plugin';
import * as me from 'melonjs';
// register the plugin
me.plugin.register(SpinePlugin);
// prepare/declare assets for the preloader
const DataManifest = [
{
"name": "alien-ess.json",
"type": "spine",
"src": "data/spine/alien-ess.json"
},
{
"name": "alien.atlas",
"type": "spine",
"src": "data/spine/alien.atlas"
},
];
// create a new Application
const app = new me.Application(800, 600, {
parent: "screen",
renderer: me.video.AUTO,
});
// mandatory since melonJS 20.0: the renderer is built here
await app.init();
// preload assets
me.loader.preload(DataManifest, function() {
// create a new Spine Renderable
let spineAlien = new Spine(100, 100, {atlasFile: "alien.atlas", jsonFile: "alien-ess.json"});
// set default animation
spineAlien.setAnimation(0, "death", true);
// add it to the game world
app.world.addChild(spineAlien);
});
Note: use "spine" as a value for the
typeproperty to indicate which assets are actual Spine assets and to be loaded using the plugin
| Method | Description |
|---|---|
setAnimation(trackIndex, name, loop) |
Set the current animation for a track |
setAnimationByIndex(trackIndex, index, loop) |
Set animation by index |
addAnimation(trackIndex, name, loop, delay) |
Queue an animation after the current one |
setEmptyAnimation(trackIndex, mixDuration) |
Clear a track with optional mix out |
isCurrentAnimation(name) |
Check if a specific animation is playing |
setDefaultMixTime(mixTime) |
Set default mix duration between animations |
setTransitionMixTime(from, to, mixTime) |
Set mix duration between two specific animations |
addAnimationListener(listener) |
Register animation event callbacks |
removeAnimationListener(listener) |
Remove a registered listener |
getAnimationNames() |
Get list of available animation names |
| Method | Description |
|---|---|
setSkinByName(skinName) |
Set a skin by name |
setCombinedSkin(name, ...skinNames) |
Combine multiple skins (mix-and-match) |
getSkinNames() |
Get list of available skin names |
| Method | Description |
|---|---|
findBone(boneName) |
Find a bone by name |
findSlot(slotName) |
Find a slot by name |
findConstraint(constraintName) |
Find a constraint by name (IK / Transform / Path / Physics / Slider) — added in 3.1.0 |
getConstraintNames() |
Get the list of constraint names available in the skeleton — added in 3.1.0 |
setToSetupPose() |
Reset skeleton to setup pose |
setSkeleton(atlasFile, jsonFile) |
Load a skeleton (if not set via constructor) |
Spine 4.3 introduced Slider constraints — a pre-baked animation indexed by a numeric time value, optionally driven by a bone's rotation. The plugin re-exports the Spine runtime's Slider classes (and the four pre-existing constraint classes) alongside the default Spine export so consumers can do instanceof Slider (or instanceof IkConstraint, etc.) without a second import from @esotericsoftware/spine-core:
import Spine, {
// 4.3 Slider classes
Slider, SliderData, SliderTimeline, SliderMixTimeline,
// other constraint classes — for narrowing findConstraint() results
IkConstraint, TransformConstraint, PathConstraint, PhysicsConstraint,
} from "@melonjs/spine-plugin";
const diamond = new Spine(750, 600, { atlasFile: "diamond-pma.atlas", jsonFile: "diamond-pro.json" });
diamond.setAnimation(0, "idle-rotating", true);
// query the "rotation" Slider constraint
const slider = diamond.findConstraint("rotation");
if (slider instanceof Slider) {
// scrub a slider manually (disable bone auto-driving first)
slider.bone = null;
slider.pose.time = 1.0; // jump to t=1s in the slider's animation
slider.pose.mix = 1.0; // 0..1 — how much of the slider pose to apply
}
See the diamond example for an interactive demo.
| Method | Description |
|---|---|
flipX(flip) |
Flip horizontally |
flipY(flip) |
Flip vertically |
scale(x, y) |
Scale the skeleton |
rotate(angle) |
Rotate the skeleton |
| @melonjs/spine-plugin | melonJS | spine-runtime |
|---|---|---|
| v3.x.x | v19.7.1 (or higher) | v4.3.x |
| v2.2.x | v18.3.0 (or higher) | v4.2.x |
| v2.1.x | v18.3.0 (or higher) | v4.2.x |
| v2.0.x | v18.2.1 (or higher) | v4.2.x |
| v2.0.0 | v18.2.0 (or higher) | v4.2.x |
| v1.5.x | v15.12.0 (or higher) | v4.1, v4.2-beta |
Note: skeleton data is editor-version locked — plugin 3.x and 4.x require assets exported from a Spine 4.3 editor; 4.2 exports will not load (and vice-versa on plugin 2.x).
If you need technical support, you can contact us through the following channels: