0
votes

I want to teach myself some basic physics programming by creating a simple 2d platformer with SDL 2. It seems I'm falling at the first hurdle though, because I can't get movement using both velocity and acceleration per time unit, rather than per frame, to work.

I start by calculating the time per frame in the usual way:

previous_time = current_time;
current_time = SDL_GetTicks();
delta_time = current_time - previous_time;

Then, after the movement flag is set to true by pressing a directional button, this is passed to a function to handle the movement.

//Pass the movement flag and the milliseconds per frame to the right movement function.
if ( player.get_x() <= 740 ) {

    player.x_movement_right(delta_time, 1, moving_right);

}

The integer that's passed doesn't do anything yet. Anyway, the function then determines the acceleration based on if the movement flag is set to true, and what the current velocity is:

void Player::x_movement_right(float dt, int direction, bool moving_right) {

    dt /= 1000;

    if (moving_right == true && _x_velocity <= 200 ) {

        _x_acceleration = 50;

    }
    else if ( moving_right == false && _x_velocity > 0 ) {

        _x_acceleration = -50;

    }
    else {

        _x_acceleration = 0;

    }

    _x_velocity += _x_acceleration * dt;

    _x_position += _x_velocity * dt;

}

The same process occurs if the left movement flag is activated, with inverted values of course. Yet after compiling I hit the directional keys and nothing happens.

What I've already tried:

  • I removed the dt's at the bottom of the movement function. The player avatar moves with incredible speed, since the acceleration is now per frame, rather than per second.
  • Same thing when I don't divide dt at the beginning of the movement function, since it's now per millisecond rather than per second.
  • I tried rounding the velocity times dt at the bottom, since I suspected SDL might have trouble calculation positions with floating point numbers rather than integers. Still no movement.

Based on this I suspect it has something to do with the numbers being too small, but I can't quite wrap my head around what the problem is or how to solve it. So, does anyone know what undoubtedly obvious thing I'm missing? Thanks in advance!

1
Can you provide the types of those variables? Also, I would suggest you debug this code by taking a look at every variable in the movement function, as they execute. If you are using an int type for the velocity/position, this might be your issue.MateusMP
Thanks, I'll try that. The variables are all indeed integers, since they correspond to a number of pixels on screen. I'm not clear on how conversions work exactly though, so if there's a potential problem there I'd love to hear.wasneeplus
If you velocity and position are integers, you won't be able to add a fraction. For instance: int x = 0; x += 0.1 Final value of x is 0. Your variables need to be float/double if you want to add float fractions.MateusMP
That seems like just the obvious overlooked answer I was looking for. I will see about changing it and report back.wasneeplus
Thank you for your help. Turns out it was a simple matter of changing the types of the variables to float. Now it works fine. Have a nice day!wasneeplus

1 Answers

0
votes

There is no way to know with the information shown, but there are several points that may help you:

  • Are your _x_velocity and the like floating point types? In what units are you measuring distance? It may be that your increment has not enough resolution to be nonzero.

  • Have you printed the values of each variable or run the program in a debugger?

  • What do you mean by "SDL might have trouble calculation positions with floating point numbers"? If you are using SDL's basic 2D renderer, you just need to give it the type it needs in whatever units they ask. The conversions are up to you.

Overall, I'd recommend trying to code the simulation outside SDL or graphics in general. Getting acquainted with C++, debugging and floating-point is also a plus.