0
\$\begingroup\$

While finishing up game loop and rendering integration, i made some blocks move back and forth in the x axis to test things out. Their initial positions are as follows:

initial block positions

The first block starts at 0,0(Top-left) and subsequent ones add 40 to both x and y.

Move code

s16 speed = 10;

if(block->sprite->position.x >= viewportWidth - block->sprite->width)
{
    block->sprite->position.x = viewportWidth - block->sprite->width;
    block->dir = -1;
}
else if(block->sprite->position.x <= 0)
{
    block->sprite->position.x = 0;
    block->dir = 1;
}

block->sprite->position.x += speed * block->dir;

However, if i change the speed to a number not multiple of 10(or using deltaTime to influence the speed), the blocks will de-sync when changin directions, as shown bellow:

Result of using roundf(1000 * deltaTime) as speed Result of using roundf(1000 * deltaTime) as speed

Result of using 13 speed and removing the clamping of position Result of using 13 speed and removing the clamping of position

I thought it was related to me using ints instead of floats for positions, tried to change but no luck. Looking at the game loop update, no block is being left out of any update phase either.

What bit of math an i missing? What causes this?

Thanks.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Your value of movespeed=10 is a special case where each block collides with the wall at the same distance into the wall.

In order to keep your spacing the same, the boxes must each travel a distance of movespeed every frame.

Think of a 1D problem with a single point on a line that goes from 0 to 100. Using your algorithm lets start at P1 = 97 and go through the steps.

P1 = 97 + 10 = 107

Next frame

P1 = 100 - 10 = 90

Since the point was brought back to 100, then you subtract 10, the point traveled 17 in one frame, which makes it desync from other boxes that align more accurately with the wall.

In order to fix the problem, you need to make sure the point always travels the same distance i.e.

If P1 = 97 and you add 10, then P1 = 100 + (100-(97+10)) = 93

Meaning that P1 traveled a distance of 3 towards the wall and then 7 away from the wall for a total of 10.

A way to implements this would be to change the previous lines to the following...

block->sprite->position.x = 2*(viewportWidth - block->sprite->width) - (block->sprite->position.x+movespeed);

and

block->sprite->position.x = -(block->sprite->position.x-movespeed);

and include the normal movement code in an else bracket

else
{
    block->sprite->position.x += speed * block->dir;
}
\$\endgroup\$

You must log in to answer this question.