Hy,
I'm trying to understand a few things about the integration of spine in a box2d world. So, I took the example here (https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java) and I created a new application that implements the code of the example, minus all the creation of the world. But when I launch the desktopLauncher, I see this :
I try to fix it by changing the position of the bodies in the render method, but my method was not the good one. So, what can I do ? And how can I fix this problem ?
Thank you very much for your answers 🙂
Here is my code :
package com.box2dspine;
import com.esotericsoftware.spine.Animation;
import com.esotericsoftware.spine.Event;
import com.esotericsoftware.spine.Skeleton;
import com.esotericsoftware.spine.SkeletonData;
import com.esotericsoftware.spine.SkeletonJson;
import com.esotericsoftware.spine.SkeletonRenderer;
import com.esotericsoftware.spine.Skin;
import com.esotericsoftware.spine.Slot;
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxNativesLoader;
public class TestBox2DSpine extends ApplicationAdapter {
SpriteBatch batch;
ShapeRenderer renderer;
SkeletonRenderer skeletonRenderer;
TextureAtlas atlas;
Skeleton skeleton;
Animation animation;
float time;
Array<Event> events = new Array<Event>();
OrthographicCamera camera;
Box2DDebugRenderer box2dRenderer;
World world;
Body groundBody;
Matrix4 transform = new Matrix4();
Vector2 vector = new Vector2();
public void create () {
batch = new SpriteBatch();
renderer = new ShapeRenderer();
skeletonRenderer = new SkeletonRenderer();
skeletonRenderer.setPremultipliedAlpha(true);
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
// This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep
// track of the Box2D body for each attachment.
AtlasAttachmentLoader atlasLoader = new AtlasAttachmentLoader(atlas) {
public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
Box2dAttachment attachment = new Box2dAttachment(name);
AtlasRegion region = atlas.findRegion(attachment.getName());
if (region == null) throw new RuntimeException("Region not found in atlas: " + attachment);
attachment.setRegion(region);
return attachment;
}
};
SkeletonJson json = new SkeletonJson(atlasLoader);
json.setScale(0.6f * 0.05f);
SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("spineboy/spineboy.json"));
animation = skeletonData.findAnimation("walk");
skeleton = new Skeleton(skeletonData);
skeleton.setX(12);
skeleton.setY(1);
skeleton.updateWorldTransform();
// See Box2DTest in libgdx for more detailed information about Box2D setup.
camera = new OrthographicCamera(48, 32);
camera.position.set(16, 16, 0);
box2dRenderer = new Box2DDebugRenderer();
world = new World(new Vector2(0, -10), true);
//createWorld();
// Create a body for each attachment. Note it is probably better to create just a few bodies rather than one for each
// region attachment, but this is just an example.
for (Slot slot : skeleton.getSlots()) {
creerBodyFromSlot(slot);
}
}
private void creerBodyFromSlot(Slot slot)
{
if (!(slot.getAttachment() instanceof Box2dAttachment)) return;
Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
PolygonShape boxPol = new PolygonShape();
boxPol.setAsBox(attachment.getWidth() / 2 * attachment.getScaleX(), attachment.getHeight() / 2 * attachment.getScaleY(),
vector.set(attachment.getX(), attachment.getY()), attachment.getRotation() * MathUtils.degRad);
BodyDef boxBodyDef = new BodyDef();
boxBodyDef.type = BodyType.StaticBody;
attachment.body = world.createBody(boxBodyDef);
attachment.body.createFixture(boxPol, 1);
boxPol.dispose();
}
public void render () {
float delta = Gdx.graphics.getDeltaTime();
float remaining = delta;
while (remaining > 0) {
float d = Math.min(0.016f, remaining);
world.step(d, 6, 2);
time += d;
remaining -= d;
}
camera.update();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.projection);
batch.setTransformMatrix(camera.view);
batch.begin();
animation.apply(skeleton, time, time, true, events, 1, false, false);
skeleton.setX(skeleton.getX()+0.5f*delta);
skeleton.setY(skeleton.getY()+0.5f*delta);
skeleton.updateWorldTransform();
skeletonRenderer.draw(batch, skeleton);
batch.end();
// Position each attachment body.
for (Slot slot : skeleton.getSlots()) {
if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
if (attachment.body == null) continue;
float x = skeleton.getX() + slot.getBone().getWorldX();
float y = skeleton.getY() + slot.getBone().getWorldY();
float rotation = slot.getBone().getWorldRotationX();
attachment.body.setTransform(x, y, rotation * MathUtils.degRad);
}
box2dRenderer.render(world, camera.combined);
}
public void resize (int width, int height) {
batch.setProjectionMatrix(camera.projection);
renderer.setProjectionMatrix(camera.projection);
}
public void dispose () {
atlas.dispose();
}
static class Box2dAttachment extends RegionAttachment {
Body body;
public Box2dAttachment (String name) {
super(name);
}
}
}