systemExklusiv Posted June 9, 2015 Report Share Posted June 9, 2015 Hello everyone! I'm pondering on how to let a Spriter's sprite take part in B2D physics world. First of all my general question: How would you do it? My thoughts so far: First of all I used the loader/drawer of trixt0r to get to ready setup libGdx Sprites conveniently. From tis point I tried to get them taking part in physics. a) My first idea was to make out of each object/box of an entity a static B2D-Body which get a rectangular shape. The rect-shape is just for simplicity - of course the don't yield perfect coillsion. These bodies get updated each frame when the Spriter animation renders to get new x,y and rotation. By doing this, the texture regions of the sprite are sync'ed with the body's fixture shape. It follows a screenshot of the Spriters monster-Sprite, where all the objects (trixt0r lib for libGdx) which have textures attached to have a green bounding box around them. These Boxes are also shapes attached to B2D-Bodies (as fixture shape). This works so far unless I want to apply force to the monster itself. The problem is that the animation itself is controlling the physics not vice versa. I 'd want to let the monster fall down, I would have to make these by translation the coordinates of the Sprite instead of letting the Word control the position e.g. when its no longer grounded because there is no body underneath - thus I'm loosing the a lot of the advantages of a physics sim. I pasted in some code for setting this up (the following iteration is based on the code of libGdxDrawer class of trixt0r except the b2d stuff) - just to get the idea. public static void setUpBodiesToWorld(Player player, Loader<SpriteBox2D> loader,World world) { Iterator<Timeline.Key.Object> it = player.objectIterator(); while(it.hasNext()){ // itereation over all the objects with a libGdx-Sprite Timeline.Key.Object object = it.next(); /* the loader is of tpe Loader<SpriteBox2d> - its like Sprite , I put just a public field for the body in it */ SpriteBox2D sprite = loader.get(object.ref); /*Setting up the fixture shape of the body - below is just an example for taking the objects-boxes a shapes for bodies */ PolygonShape box = new PolygonShape(); box.setAsBox(sprite.getWidth() / 2 * sprite.getScaleX() , sprite.getHeight() / 2 * sprite.getScaleY() , vector.set(sprite.getX(), sprite.getY()), sprite.getRotation() * MathUtils.degRad); BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = BodyDef.BodyType.StaticBody; Body body = world.createBody(boxBodyDef); /*assigning the body and making a association between the TextureRegion and the body When rendering the sprite, the body can be easily retrieved and positioned*/ sprite.body = body; Fixture fixture = body.createFixture(box, 1); fixture.setUserData(sprite); box.dispose(); } } When the libGdx-Drawer iterates over the Player and retrieves the Sprites an additional body can be retrieved and positioned. b > My second guess was to draw a static form around the sprite (like the orange ellipse in the screenshot) which encompasses roughly the sprite. This shape is the bodyshape in B2D and keeps track of the curren pos and rotation. The sprite positions accordingly to the shape - but with odd visual side effects - e.g. things which look like they should collide don't and vice versa. I believe the main problem is that the physics aren't involved animating the bones and its difficult to make them behave physically afterwards. What are your thoughts/Experiences? Thanks david TristanFat, JohnnyType and AlisaMesy 3 Quote Link to comment Share on other sites More sharing options...
Trixt0r Posted June 23, 2015 Report Share Posted June 23, 2015 Hi systemExklusiv, the hardest part, to get Box2D working with the Spriter API is the fact, that you have to create correct joints between the sprites. If you have bones for an entity, this should be rather easy (depends on how bones are meant to work for an entity) and an automated process for creating the joints could be implemented. But if you do not know how a sprite is related to another one, you have to define the joints manually, which may cost you some time (depends on the complexity of an entity). However, if you know how to connect the Box2D objects, it should not be a problem to let Box2D manipulate the sprites. The inverse kinematics part of the library does a similar thing. The current transformation of each object/bone gets read and then manipulated. The trick is, to let the player first update itself, then manipulate the transformation of each spriter object and draw the actual result to the screen. The logic would look like this: // Update player, can actually be skipped if the box2D bodies are already initialized.player.update();// Setup box2D bodies and joints, has to be called only oncespriterBox2DFetch(player);// Simulate physicsbox2DWorld.step(1/60f, 6, 2);// Set the transformation of the spriter objects to the one of the box2D objectsspriterBox2DTransformation(player);// Draw the resultdrawer.draw(player); I may try to add an example to the test suite for this case, this week. - Trixt0r Quote Link to comment Share on other sites More sharing options...
systemExklusiv Posted October 10, 2015 Author Report Share Posted October 10, 2015 Oh man, sorry for the delay! Thanks form the answer! Yeah, your idea encompasses some really complicated 'force-applying' to simulate e.g. a walking movement. One could go further this direction: create a body for each object and interconnect them with joints. update all bodies by the animation except one at the center, which position etc. will be calculated by the physics world. All the other bodies will driven by the animation, in a way that joints are adjusted. But this seems difficult to accomplish. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.