Game mechanic player following path looks very roughly

I want my player entity to follow a path, which works, but it looks very roughly. Like it would stuck everytime.

    bool arrivedX = false;
bool arrivedY = false;

float speed = 0.06f;

if(bestway.empty()) {
//arrived
} else {

if(entity->x < bestway.front()->x * gridSize) {
entity->x += speed * machine->getDeltaTime();
} else if(entity->x > bestway.front()->x * gridSize) {
entity->x -= speed * machine->getDeltaTime();
} else {
arrivedX = true;
}

if(entity->y < bestway.front()->y * gridSize) {
entity->y += speed * machine->getDeltaTime();
} else if(entity->y > bestway.front()->y * gridSize) {
entity->y -= speed * machine->getDeltaTime();
} else {
arrivedY = true;
}

if(arrivedX && arrivedY) {
bestway.pop_front();
}
}


the vector contains grid coords from 0 to WIDTH or HEIGHT / gridSize. And the entity has pixels coords. I have tried already:

entity->x / gridSize < bestway.front()->x


which runs smoothly, but when it goes up or right it will omit one grid tile. I think it is because of when the player is at pixel 19 and the gridSize is 20 it would calculate 0 . 19/20 = 0... I tried to ceil and floor it, but it didn't work out. Hope you guys can help me.

edit:

        int ix = int( x + 0.5f );
int iy = int( y + 0.5f );

if(ix < bestway.front()->x * gridSize) {
x += speed * machine->getDeltaTime();
} else if(ix > bestway.front()->x * gridSize) {
x -= speed * machine->getDeltaTime();
} else {
arrivedX = true;
}


Video

http://youtu.be/-DugHbMdODg

• What are the types of entity->x and gridSize and bestway.front()->y? – akaltar Mar 12 '15 at 14:52
• hi. they're all integers. – Kronos Mar 12 '15 at 15:00
• And what is deltatime? What unit and what type? Also, what is your update frequency? – akaltar Mar 12 '15 at 15:04
• Deltatime is float most time between 30 and 60. But now I saw that when it stucks deltatime ist above 100. I use the SDL_iPhoneSetAnimationCallback() method for updating. So I don't know how often it updates. I have to figure this out first. – Kronos Mar 12 '15 at 15:33

I believe your error arises from rounding errors.

I believe the problem could be solved by using float for pixel-coordinate storage. This way you will always get the exact increment needed for the given delta time, which is usually very small and thus the resulting per update increment is less than 1, and truncated to 0.

Don't forget to use proper rounding when converting back for rendering or comparison. For rendering I would use: int ix = (int)( entity->x + 0.5 ) Which will yield 'proper' rounding: up from 0.5 and down with anything less.

Edit:

From the video it seems you are overshooting the position you are aiming for. There are three ways to solve this:

• After moving, check if you overshot and correct for it:

entity->x += speed * dt;
if( entity->x > movelocation->x * gridSize )
entity->x = movelocation->x * gridSize;

• Lower the speed you are moving with.

• Use a higher update frequency.

The most solid option seems to be checking for overshoot and correcting. Note: The simple code I provided doesn't account for the movement speed lost when arriving at each tile.

• Thanks for the answer. I cannot easily use float since I'm using the SDL_Rect x, y coords which are integers. And I really will not use a Wrapper or tricky stuff. Any idea? – Kronos Mar 12 '15 at 16:21
• Still is shaky... that is the better description for it. looks like it would increment, then decrement and so on... edit: used floats for x,y coords and updating the SDL_Rect so I can use it as well – Kronos Mar 12 '15 at 16:43
• @Kronos could you post the new code too? I showed how to convert the float to an integer, it should be smooth. I see no real reason for the jumping forward and backward.. A gif or video of the issue would be helpful as well. Also: Are you warning-free? You should usually treat compiler warning as errors. – akaltar Mar 12 '15 at 17:56
• Hi. there are no Warnings. I edited the original post and added a video. Hope this will help. – Kronos Mar 12 '15 at 18:36
• @Kronos Edited, I guess this will solve your problem. – akaltar Mar 12 '15 at 19:45