a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit 45ccc3fb2925663632edc8b671ffdd4cf5f2f211
parent 2bc29b7706016ef52fc0e95369c728780d8e6661
Author: amin <dev@aminmesbah.com>
Date:   Sat, 23 Nov 2019 17:43:48 +0000

Specify jump in terms of maximum height

It's gradually becoming pleasant to move around in this world. A little
high school physics goes a long way!

FossilOrigin-Name: 75ee64faa932d8fff75c11926138b0f1d62a71afc179dd20f47fe9259b4cdb58
Diffstat:
Msrc/game.c | 51++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -254,13 +254,12 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga dt = 1.0f / 60.0f; } - f32 max_velocity[] = { - [DIR_RIGHT] = 6.0f, - [DIR_LEFT] = -6.0f, - [DIR_UP] = 7.0f, - [DIR_DOWN] = -9.0f, - }; + f32 max_run_speed = 6.0f; + f32 max_climb_speed = 7.0f; + f32 max_fall_speed = 9.0f; + f32 acceleration_rate = 50.0f; + f32 gravity = 30.0f; f32 friction = 0.7f; enum Direction previous_facing_dir = player->facing; @@ -385,12 +384,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga move_mode_print(player->move_mode); - // TODO: tune these acceleration rates // simulate movement mode switch(player->move_mode) { case MOVE_MODE_FALLING: - player->acceleration.y = -acceleration_rate; + player->acceleration.y = -gravity; break; case MOVE_MODE_GROUNDED: player->acceleration.y = 0.0f; @@ -421,11 +419,17 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } break; case MOVE_MODE_JUMPING: - // TODO: Specify jumping in terms of jump height - max_velocity[DIR_UP] = 1000.0f; - player->acceleration.y = 30.0f * acceleration_rate; + { + f32 jump_height = 2.0f; + // v^2 = v0^2 - 2g(y - y0) + // 0 = v0^2 - 2g(h - 0) + // 0 = v0^2 - 2gh + // v0^2 = 2gh + // v0 = sqrt(2gh) + player->velocity.y = sqrtf(2.0f * gravity * jump_height); player->move_mode = MOVE_MODE_FALLING; break; + } case MOVE_MODE_FLOATING: if (btn_is_down(button_states, BTN_UP)) { @@ -449,8 +453,29 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga // Semi implicit Euler integration: https://gafferongames.com/post/integration_basics/ player->velocity = math_v2_a(player->velocity, math_v2f_m(player->acceleration, dt)); // TODO: clamp the length of the velocity vector, not each of its components - math_clamp(&player->velocity.x, max_velocity[DIR_LEFT], max_velocity[DIR_RIGHT]); - math_clamp(&player->velocity.y, max_velocity[DIR_DOWN], max_velocity[DIR_UP]); + math_clamp(&player->velocity.x, -max_run_speed, max_run_speed); + switch(player->move_mode) + { + case MOVE_MODE_CLIMBING: + math_clamp(&player->velocity.y, -max_fall_speed, max_climb_speed); + break; + case MOVE_MODE_FALLING: + if (player->velocity.y < -max_fall_speed) + { + player->velocity.y = -max_fall_speed; + } + break; + case MOVE_MODE_FLOATING: + math_clamp(&player->velocity.y, -max_run_speed, max_run_speed); + break; + default: + break; + } + + printf("v: "); + math_print(player->velocity); + printf("a: "); + math_print(player->acceleration); // game_detect_collisions {