Add physics to spine

How i can add physics to spine animation?
var widthCanvas= 1000;
var heightCanvas = 600;
var config = {
type: Phaser.CANVAS,
parent: ‘phaser-example’,
width: widthCanvas,
height: heightCanvas,
physics:{
default: ‘arcade’,
arcade: {
gravity: { y: 400 },
debug: true
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var bg_ground;

//skeleton animate
var lastFrameTime = Date.now() / 1000;
var assetManager;
var skeleton, state, bounds;
var skeletonRenderer;

var skelName = “loki”;
var animName = “idle_apple”;

function preload () {

this.load.image('bg', ' ./resources/BG/bg.png');
this.load.image('bg_ground', ' ./resources/BG/bg_ground.png');
this.load.image('iconThor', ' ./resources/UI/icon_thor.png');
this.load.image('iconLoki', ' ./resources/UI/icon_loki.png');
this.load.image('logo', ' ./resources/UI/logo.png');

this.load.script('spine', './js/spine-canvas.js');

}

function create() {
//Draw background
var heightGround = heightCanvas/8;
var bg = this.add.sprite(0, heightCanvas - heightGround, ‘bg’);

var scaleX=widthCanvas/bg.width;
var scaleY=(heightCanvas - heightGround)/bg.height;
scaleBg = scaleX>scaleY?scaleX:scaleY;

bg.setOrigin(0, 1);
bg.setScale(scaleBg);

bg_ground = this.add.sprite(0, heightCanvas - heightGround, 'bg_ground').setScale(scaleBg).setOrigin(0, 0); 
this.physics.add.existing(bg_ground, true);

var xLabel = widthCanvas/4;
var yLabel = heightCanvas/11;
var line = new Phaser.Geom.Line(xLabel, yLabel, widthCanvas-xLabel, yLabel);
graphics = this.add.graphics();
graphicsHpPlayer2 =  this.add.graphics();
graphics.lineStyle(40, '0x9438a0');
graphics.strokeLineShape(line);
console.log(line);
lineHpPlayer1 = new Phaser.Geom.Line(xLabel, yLabel, xLabel+(line.x2-line.x1)/3.3, yLabel);
lineHpPlayer2 = new Phaser.Geom.Line(widthCanvas-xLabel, yLabel, xLabel + 2.3*(line.x2-line.x1)/3.3, yLabel);
var lineEnemyHpPlayer1 = new Phaser.Geom.Line(xLabel, yLabel, xLabel+(line.x2-line.x1)/3.3, yLabel);
var lineEnemyHpPlayer2 = new Phaser.Geom.Line(widthCanvas-xLabel, yLabel, xLabel + 2.3*(line.x2-line.x1)/3.3, yLabel);
graphics.lineStyle(25, '0x91148d');
graphics.strokeLineShape(lineEnemyHpPlayer1);
graphics.strokeLineShape(lineEnemyHpPlayer2);   
graphics.lineStyle(25, '0xff0000');
graphics.strokeLineShape(lineHpPlayer1);
graphicsHpPlayer2.lineStyle(25, '0xff0000');
graphicsHpPlayer2.strokeLineShape(lineHpPlayer2);

this.add.image(xLabel, yLabel, 'iconThor').setScale(0.18);
this.add.image(widthCanvas-xLabel, yLabel, 'iconLoki').setScale(0.18);
this.add.image(widthCanvas/2, yLabel, 'logo').setScale(0.23);

skeletonRenderer = new spine.canvas.SkeletonRenderer(this.sys.context);
// skeletonRenderer.debugRendering = true;
//skeletonRenderer.triangleRendering = true;

assetManager = new spine.canvas.AssetManager();
assetManager.loadText("./resources/Character/Loki/loki_upgraded.json");
assetManager.loadText("./resources/Character/Loki/loki_upgraded.atlas");
assetManager.loadTexture("./resources/Character/Loki/loki_upgraded.png");

}

function update() {
if (assetManager.isLoadingComplete() && !skeleton)
{
var data = loadSkeleton(skelName, animName, “default”);

    skeleton = data.skeleton;

    state = data.state;

    bounds = data.bounds;

    this.sys.events.on('render', render, this);
}

}

function loadSkeleton (name, initialAnimation, skin) {
if (skin === undefined)
skin = “default”;

// Load the texture atlas using name.atlas and name.png from the AssetManager.
// The function passed to TextureAtlas is used to resolve relative paths.

atlas = new spine.TextureAtlas(assetManager.get("./resources/Character/Loki/loki_upgraded.atlas"), function(path) {
    return assetManager.get("./resources/Character/Loki/loki_upgraded.png");
});
// Create a AtlasAttachmentLoader, which is specific to the WebGL backend.
atlasLoader = new spine.AtlasAttachmentLoader(atlas);

// Create a SkeletonJson instance for parsing the .json file.
var skeletonJson = new spine.SkeletonJson(atlasLoader);

// Set the scale to apply during parsing, parse the file, and create a new skeleton.
var skeletonData = skeletonJson.readSkeletonData(assetManager.get("./resources/Character/Loki/loki_upgraded.json"));
var skeleton = new spine.Skeleton(skeletonData);
skeleton.flipY = true;
var bounds = calculateBounds(skeleton);
skeleton.setSkinByName(skin);

// Create an AnimationState, and set the initial animation in looping mode.
var animationState = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
animationState.setAnimation(0, initialAnimation, true);
// Pack everything up and return to caller.
return { skeleton: skeleton, state: animationState, bounds: bounds };

}

function calculateBounds(skeleton) {
var data = skeleton.data;
skeleton.setToSetupPose();
skeleton.updateWorldTransform();
var offset = new spine.Vector2();
var size = new spine.Vector2();
skeleton.getBounds(offset, size, []);
return { offset: offset, size: size };
}

function render ()
{
var now = Date.now() / 1000;
var delta = now - lastFrameTime;
lastFrameTime = now;

var canvas = this.sys.canvas;
var context = this.sys.context;

// magic
var centerX = bounds.offset.x + bounds.size.x / 2;
var centerY = bounds.offset.y + bounds.size.y / 2;
var scaleX = bounds.size.x / canvas.width;
var scaleY = bounds.size.y / canvas.height;
var scale = Math.max(scaleX, scaleY) *2;
if (scale < 1) scale = 1;
var width = canvas.width * scale;
var height = canvas.height * scale;

context.setTransform(1, 0, 0, 1, 0, 0);
context.scale(1/2.5,1/2.5);

context.translate(200,2.5*500);

state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
skeletonRenderer.draw(skeleton);

}

Phaser published examples of physics applied to spine on their examples page

https://phaser.io/examples/v3/view/spine/arcade-physics-spine-body

1 Like