• Editor
  • Getting started with Box2D

Related Discussions
...

Hey everybody,

after a rather long pause of not programming at all I've picked up my game again. I bought Spine a while ago and have experimented around with it for a bit. Now I started working with Box2D in LibGDX and saw that Spine also had a Box2D integration (according to the Kickstarter).

I'm kinda interested on how to get started (essentially how to tell Box2D about my character, letting gravity affect the attachments, etc.) and was searching for a documentation about it. But I couldn't find anything.

Is there anything I missed? Does somebody know a tutorial how to get started with Spine and Box2D or is there a documentation somewhere that I didn't find? Any help is highly appreciated ๐Ÿ™‚

Thanks.

Wow, thanks. How did I not find that via google yet? O.o Well thanks :p

I'll be looking at the code, trying to fiddle the thing into my existing infrastructure. Maybe this can become kind of a discussion thread about the whole thing :p In case you have problems or (more likely) I have problems :')

Well I wound up making a BoxAtlasAttachmentLoader class and have that make the RegionAttachement into Box2dAttachment, now I just gotta get all the attachments put into the right position rather than in a pile at 0,0 .. oh well progress is progress

And also in the update I had to add the skeleton.x and y to the bone's world offsets... but that could just be me doing something.. wrong.

Hmmmโ€ฆI can't seem to have TextureAtlasAttachmentLoader or BoxAttachmentLoader ๐Ÿ™
Can you maybe share your code? :o

//Edit:

Okay, so I updated to the latest Spine and LibGDX runtimes (and nightly builds) and now it includes all the methods I need, however the drawing gives me an out of bounds exception when creating the skeletonbinary O.o

What versions of libgdx and spine did you use? Also when I imported all the source files from spine into my project I had to fix quite a few errors (some of the variables didn't have public modifiers and demanded getters/ setters)

Hm my Spine src is from 6/28 and the LibGDX nightlies are about a month old, I don't recall needing to fix anything. :-/

And I'm using the json skeleton rather than the binary exports, but thge index error could be if your Atlas file hasn't been refreshed?

and here's what I popped into my BoxAtlasAttachmentLoader

import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.physics.box2d.Body;
import com.esotericsoftware.spine.Skin;
import com.esotericsoftware.spine.attachments.AttachmentLoader;
import com.esotericsoftware.spine.attachments.AttachmentType;
import com.esotericsoftware.spine.attachments.RegionAttachment;

public class BoxAtlasAttachmentLoader  implements AttachmentLoader {
	private TextureAtlas atlas;

public BoxAtlasAttachmentLoader (TextureAtlas atlas) {
	if (atlas == null) throw new IllegalArgumentException("atlas cannot be null.");
	this.atlas = atlas;
}

public Box2dAttachment newAttachment (Skin skin, AttachmentType type, String name) {
	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;		
}
static class Box2dAttachment extends RegionAttachment {
	Body body;

	public Box2dAttachment (String name) {
		super(name);
	}
}
}

Kate does the JSON version give you the same out of bounds error? I'm not 100% sure the binary export was updated for the new features yet, Nate will be able to shed some light on it.

Okay, I'll just edit this post because I hate double posting stuff :p I had some issues with getting Spine and Libgdx to work. The latest nightly has a bug that fails to read files. Had to take an old nightly and manually add the ObjectFloatMap class from the libgdx repository.

Now I reverse engineered the spine example into my own code and got it do work. Got the lovely boxes falling from the sky. However I'm getting a nullpointer when trying to read the animation (The animation feature was changed several times since the workshop. I lost my own animation files so I just wanted to use the Spineboy.

animation = skeletonData.findAnimation("walk");

seems to return null. So I just disabled the animation for now.

The guy just slithers across the floor, which is all nice and all but what I'd actually be interested in is how to make the skeleton interact with the boxes and gravity. You know, letting boxes bounce off his head and letting him fall down when not on the ground etc.

Is that even possible? :/ Because that'd be the thing I'm interested in. Also, if it is, I'd be interested how I would have to adjust my animation moves to not screw everything up with the gravity :o

The Box2DExample class linked above uses spineboy and box2d. It is up to date and should run out of the box. It works by creating physics bodies to match the images. This could be improved by using bounding boxes when that is released in a few days, which means you won't have so many physics bodies. Each frame the physics bodies are updated to match the animating skeleton. If you want a ragdoll effect, just stop updating their positions and let gravity in the physics simulation take over.

Hey Nate, thanks for the reply. It's appreciated that you take your time out of your days to help ๐Ÿ™‚

I made a little mistake that got the Box2D "boxes" stuck in the middle of the screen. They're now smoothly following my character.

Now I have two questions/ problems.

  1. When I flip the character to walk the other way the box2d attachments don't flip as well. Is there a smart way to resolve this? Picture below:
     Loading Image
    Hope you can see it; the arm goes in one direction and the attachments are mirrored to it.

  2. Hmm...okay. So the box2d attachments are being placed onto the skeleton for collision detection. Is there a simple way to reverse that? because:

    • If the character falls down a cliff it should do so until it hits the next ground-object

    • If the character jumps up some boxes he should land on those boxes, and not on the level that the jump was made on.

I hope somebody with more experience can help me with this.
Also if I stop updating the box2d attachments they just form this "blob" on the floor :c

Hi Kate,
I think you'll have to manually flip the body in the world when you flip the character.

And the falling down stuff gets complicated, like building joints between the bodies and letting the bodies drive the position of the bones rather than the Spine animation.

I'd love to have instant ragdoll creation build into Spine, but I think it's a bit beyond what we can expect an animation tool to provide.

  1. How do I flip the body in the world? And would I have to flip each attachment or does Box2D handle the entire thing as one object somewhere?

  2. Well I'd already be content with simple gravity without a ragdoll effect: letting the character fall down statically when going over an edge. (If it's clear what I mean) Sort of let the entire skeleton be one object that gets affected by gravity.
    Jumps could be implemented by creating an animation that lets the character move in place (in Spine) and then apply a force in Box2D into a certain direction? Maybe, idk. I'm just thinking out loud here :p

well for the falling, I'd think you'd want a separate body and have it be a dynamic body and have it drive the skeleton position, then use a filter group to keep it from colliding with the skeleton's body.

as for flipping the body.. Im afraid I dunno.. my character only goes to the right

Alright, yea. The big "box" as a dynamic object with a certain mass so that light things won't knock it away as the kind of "carrier", and then take the coordinates of that box for the skeleton to which the collision boxes are being attached. Sounds doable.

Oh, another thing. Nate mentioned that I could just stop updating the attachment positions to let the physics take over. I tried to do that...
 Loading Image

Something tells me that I didn't do it right :p :c

About the flip....theoretically it's not difficult. Though I wouldn't know how to do it mathematically...

I went down this same path. Box2D has no transforms like what you want to do to flip it. I think there are basically two approaches used elsewhere and those are:

  • maintain two separate bodies, one for going left and one for going right and just activate/deactivate them as needed
  • destroy/recreate the fixtures when changing direction

Neither are really ideal, and I am not experienced with box2d either, so I may be wrong here, so I'd also be happy to hear any solutions others have used.

14 days later

Ohai. Long time. Damn vacation :p
Alright...Yea I sat down a bit and tried to manually flip the bodies, read up about how stuff is usually flipped but then gave up after a while. No need to re-invent the wheel. The two aren't ideal. I'm not yet sure wether I'm gonna destroy and recreate the body or just keep two in memory. For that I'd have to know how resource intensive the game ends up being ๐Ÿ˜‰ But thanks for the advice.

2 months later
KateTheAwesome wrote

Yea I sat down a bit and tried to manually flip the bodies, read up about how stuff is usually flipped but then gave up after a while.

I have the same problem with flipping. The angle of the flipped body is incorrect. Maintain two separate bodies isn't excellent decision.

Hi ! Today I've played around with box2d and i have manage to have a pretty cool result but not the fanciest i think. I read in box2d forum thath fixture could change their vertex posistion and this is allow also in Jbox2d. So I basically change fixture as skeleton moves and also when it is fillpped all the fixture is automatically flipped ๐Ÿ™‚ . Here is the code ( i'm using bounding boxes but it should be the same ) :

//Creation of the player body
for(Slot s : skeleton.getSlots()){
		if(s.getAttachment() instanceof BoundingBoxAttachment){
		     BoundingBoxAttachment attach = (BoundingBoxAttachment) s.getAttachment() ;
		     
PolygonShape poly = new PolygonShape(); float[] vertices = Arrays.copyOf(attach.getVertices(), attach.getVertices().length); attach.computeWorldVertices(0, 0, s.getBone(), vertices); for(int i=0;i<vertices.length;i++){ vertices[i] = vertices[i]*GameScreen.WORLD_TO_BOX; } poly.set(vertices); Fixture fixt = box.createFixture(poly, 0); fixt.setUserData(attach.getName()); poly.dispose(); } }

and in my AnimationUpdate

if(bodyMap.has(e)){
			Body b = bodyMap.get(e).getBody();
			float x = aComp.getSkeleton().getX();
			float y = aComp.getSkeleton().getY();
			for(Fixture f : b.getFixtureList()){
			    Object safe = f.getUserData();
			    if(safe instanceof String){
				Slot findSlot = aComp.getSkeleton().findSlot(f.getUserData() == null ? "" : (String)f.getUserData());
				if(findSlot != null){
					BoundingBoxAttachment attach = (BoundingBoxAttachment) findSlot.getAttachment();
					 float[] vertices = new float[attach.getVertices().length];
					 attach.computeWorldVertices(x,y, findSlot.getBone(), vertices);
					     for(int i=0;i<vertices.length;i++){
					    	 vertices[i] = (vertices[i]*GameScreen.WORLD_TO_BOX) - b.getPosition().x;
					    	 i++;
					    	 vertices[i] = (vertices[i]*GameScreen.WORLD_TO_BOX) - b.getPosition().y;
					     }
					     
((PolygonShape)f.getShape()).set(vertices); } } } }

I know this solution hasn't the highest performance ( even true in my game i didn't see any fps drop ) but it works ๐Ÿ˜‰ . There are also a couple of problems i.e. some glitches due to heavy forces on the player body or fast speed of the animation that cause tunnelling .. but I have not found a solution yet . please tell me if your able to solve them .

Bye ๐Ÿ™‚