0
votes

I'm making a simple jumping game for android using libgdx and box2d and I cannot figure out how to make sprites move really smooth. I have checked several articles regarding timestep fixing and synchronizing renderer and physics emulation, but none of the suggested ways really helped (http://gafferongames.com/game-physics/fix-your-timestep/).

Finally I decided to run the most simple test setting box2d world step equal to the framerate (which in case of stable fps should provide the best performance), but still movement is not totally smooth. I have tested on PC and on Android device, with stable 60-61 FPS. Here is pseudocode:

In render:

world.step(Gdx.graphics.getDeltaTime(), 6, 2);  
stage.act();
stage.draw();

Stage basically has just one actor with act and draw overriden:

@Override
    public void draw(Batch batch, float arg1) {

        float x = this.getX() - width/2;
        float y = this.getY() - height/2;

        batch.draw(sprite, x, y, width, height);

    }

    @Override
    public void act (float delta) {

         ...

        //get body position
        position = body.getPosition();
        this.setPosition(position.x, position.y);

    }

Actor has box2d body attached to it, there is no gravity and body's velocity is set constant:

BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(world_position);
bodyDef.linearDamping = 0f; 
bodyDef.angularDamping = 0f;
bodyDef.fixedRotation = true;
bodyDef.gravityScale = 0f;

...fixure added to the body 

body.setLinearVelocity(0, -2f);

Camera is not moving, the case seems to be dead simple and yet sprite does not move exactly perfect. (Though it still looks smoother then when using time accumulator and interpolation)

Is it possible to achive absolutely smooth movement at all? Is there some mistake in my approach? I have checked some similar games on the same android device - it seems that objects are moving absolutely smooth, but maybe it just seems so, because too many things happen on the screen and I don't have time to notice.

Any advice would be appreciated.

2
I don't think is a good ideea to pass the delta on world.step, it should be a constant value..i was doing this in my game and sometimes my bodies will jump a lot more than they would normaly do..Boldijar Paul

2 Answers

1
votes

After further testing and researched I have figured out the problem - it was related not to FPS, but to pixel rounding. Box2d bodies have float coordinates - after converting them to round pixel values animation bemace much smoother.

0
votes

How about to use CCPhysicsSprite instead of change position of sprite by time? You can use a batch, too. Just

sprite = [CCPhysicsSprite spriteWithTexture:batch.texture]; [batch addChild:sprite];

CCPhysicsSprite class Example:

#import "CCPhysicsSprite.h"

CCPhysicsSprite *sprite = [CCPhysicsSprite spriteWithFile:@"sprite.png"];
[self addChild:sprite];

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(300/PTM_RATIO, 200/PTM_RATIO);
body = world->CreateBody(&bodyDef);

b2CircleShape circleShape;
circleShape.m_radius = 0.3;

b2FixtureDef fixtureDef;
fixtureDef.shape = &circleShape;
fixtureDef.density = 1;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);

[sprite setPTMRatio:PTM_RATIO];
[sprite setB2Body:body];
[sprite setPosition: ccp(300, 200)];