June 26th, 2018 (back)

RAPTR - Physics and GitHub

Gravity, Jump, and Movement Impulses

In a throwback to "Intro to Mechanics" I decided to do a simple physics system. Our fella has a position, velocity, and acceleration now. The game defines how gravity impacts the entities. It's not perfect, but it is easy enough to work with and I can break out of the physics system when I need to.

via Gfycat

The Code!

I am finally at a place where I don't feel to judge by the haste of development. So, here it is: https://github.com/justinvh/raptr

Movement Logic

The first thing we do is see if we are falling. We can do this by grabbing our current position and adding the influence of the game's gravity with a variable to track how long we have been falling.

  // External forces, like gravity
  Rect fall_check = this->want_position_y();
  fall_check.y += game->gravity * fall_time_ms / 1000.0;
  if (game->entity_can_move_to(static_cast(this), fall_check)) {
    vel.y += game->gravity * fall_time_ms / 1000.0;
    fall_time_ms += delta_ms;
    falling = true;
  } else {
    if (falling) {
      vel.y = 0;
    }
    falling = false;
    fall_time_ms = 0;
  }

Next, we check if we can move in the X or Y direction based on the position and velocity data.

  Rect want_x = this->want_position_x();
  Rect want_y = this->want_position_y();

  if (game->entity_can_move_to(his, want_x)) {
    if (vel.x < 0) {
      sprite->flip_x = false;
    } else if (vel.x > 0) {
      sprite->flip_x = true;
    }
    sprite->x = want_x.x;
    auto& pos = this->position();
    pos.x = want_x.x;
  }

  if (game->entity_can_move_to(this, want_y)) {
    sprite->y = want_y.y;
    auto& pos = this->position();
    pos.y = want_y.y;
  }

This is making programming movement a pretty easy process. The interaction with the controller input is then:

bool Character::on_right_joy(const ControllerState& state)
{
  float mag_x = std::fabs(state.x);

  if (mag_x < 0.01f) {
    this->stop();
  } else if (mag_x < 0.5f) {
    this->walk(state.x/ 0.5f);
  } else if (mag_x >= 0.5f) {
    this->run(state.x / 1.0f);
  }

  return true;
}


bool Character::on_button_down(const ControllerState& state)
{
  if (state.button == Button::a && this->velocity().y >= 0) {
    this->velocity().y -= this->jump_vel;
    sprite->set_animation("Jump");
  }
  return true;