From 0a6e7b4ddc05477a5914695d1312aa3af98cc479 Mon Sep 17 00:00:00 2001 From: En Yi Date: Tue, 23 Apr 2024 22:44:52 +0800 Subject: [PATCH] Add delta time handling Internal Changelog: - Major change: all engine that does counting uses delta time instead of frame counting - Animation runs at 24 FPS - Water fill is at a constant rate as well - Particle update will need to be given delta time as well. - Particle system is not updated to use float, so no delta time handling for the system in this commit --- engine/EC.h | 15 +++---- engine/actions.h | 1 + engine/engine.c | 6 ++- engine/engine.h | 4 +- engine/particle_sys.c | 2 +- engine/particle_sys.h | 2 +- level_load_test.c | 7 +++- main.c | 8 +++- menu_test.c | 6 ++- particle_test.c | 13 ++++-- scene_test.c | 12 +++++- scenes/editor_scene.c | 16 +++++++- scenes/game_systems.c | 93 ++++++++++++++++++++++++------------------- scenes/items_ent.c | 10 ++--- scenes/water_flow.c | 5 +++ water_test.c | 6 ++- 16 files changed, 135 insertions(+), 71 deletions(-) diff --git a/engine/EC.h b/engine/EC.h index 8f2926a..0c1c227 100644 --- a/engine/EC.h +++ b/engine/EC.h @@ -49,8 +49,8 @@ typedef struct _CTransform_t { Vector2 accel; Vector2 fric_coeff; Vector2 shape_factor; - int8_t grav_delay; - int8_t grav_timer; + float grav_delay; + float grav_timer; MovementMode_t movement_mode; bool active; } CTransform_t; @@ -129,16 +129,15 @@ typedef struct _CHurtbox_t { } CHurtbox_t; typedef struct _CLifeTimer_t { - uint8_t timer; - uint8_t life_time; + float life_time; } CLifeTimer_t; typedef struct _CAirTimer_t { + float max_ftimer; + float curr_ftimer; + float decay_rate; uint8_t max_count; uint8_t curr_count; - uint16_t max_ftimer; - uint16_t curr_ftimer; - uint16_t decay_rate; } CAirTimer_t; typedef struct _BFSTile { @@ -177,6 +176,7 @@ typedef struct _CWaterRunner { uint8_t movement_delay; int8_t movement_speed; int16_t counter; + float fractional; }CWaterRunner_t; // Credits to bedroomcoders.co.uk for this @@ -206,6 +206,7 @@ typedef struct _CSprite_t { bool flip_y; bool pause; int current_frame; + float fractional; } CSprite_t; typedef struct _CMoveable_t { diff --git a/engine/actions.h b/engine/actions.h index 9fd8030..ca0dc75 100644 --- a/engine/actions.h +++ b/engine/actions.h @@ -18,5 +18,6 @@ typedef enum ActionType ACTION_PREVLEVEL, ACTION_TOGGLE_GRID, ACTION_SET_SPAWNPOINT, + ACTION_TOGGLE_TIMESLOW, }ActionType_t; #endif // __ACTIONS_H diff --git a/engine/engine.c b/engine/engine.c index d004d22..2398142 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -102,6 +102,7 @@ void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_ scene->render_function = render_func; scene->action_function = action_func; scene->state = SCENE_ENDED; + scene->time_scale = 1.0f; } void free_scene(Scene_t* scene) @@ -112,14 +113,15 @@ void free_scene(Scene_t* scene) deinit_particle_system(&scene->part_sys); } -inline void update_scene(Scene_t* scene) +inline void update_scene(Scene_t* scene, float delta_time) { + scene->delta_time = delta_time * scene->time_scale; system_func_t sys; sc_array_foreach(&scene->systems, sys) { sys(scene); } - update_particle_system(&scene->part_sys); + update_particle_system(&scene->part_sys, scene->delta_time); } inline void render_scene(Scene_t* scene) diff --git a/engine/engine.h b/engine/engine.h index 48bef79..64653e2 100644 --- a/engine/engine.h +++ b/engine/engine.h @@ -47,6 +47,8 @@ struct Scene { system_func_t render_function; action_func_t action_function; EntityManager_t ent_manager; + float delta_time; + float time_scale; //SceneType_t scene_type; SceneState_t state; ParticleSystem_t part_sys; @@ -63,7 +65,7 @@ void play_sfx(GameEngine_t* engine, unsigned int tag_idx); void update_sfx_list(GameEngine_t* engine); // Inline functions, for convenience -extern void update_scene(Scene_t* scene); +extern void update_scene(Scene_t* scene, float delta_time); extern void render_scene(Scene_t* scene); extern void do_action(Scene_t* scene, ActionType_t action, bool pressed); diff --git a/engine/particle_sys.c b/engine/particle_sys.c index 8316fa8..8afd690 100644 --- a/engine/particle_sys.c +++ b/engine/particle_sys.c @@ -151,7 +151,7 @@ EmitterHandle play_particle_emitter(ParticleSystem_t* system, const ParticleEmit return idx; } -void update_particle_system(ParticleSystem_t* system) +void update_particle_system(ParticleSystem_t* system, float delta_time) { uint32_t emitter_idx = system->emitter_list[0].next; uint32_t prev_idx = 0; diff --git a/engine/particle_sys.h b/engine/particle_sys.h index 4a18e70..0ca20ba 100644 --- a/engine/particle_sys.h +++ b/engine/particle_sys.h @@ -88,7 +88,7 @@ void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle hand void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle); bool is_emitter_handle_alive(ParticleSystem_t* system, EmitterHandle handle); -void update_particle_system(ParticleSystem_t* system); +void update_particle_system(ParticleSystem_t* system, float delta_time); void draw_particle_system(ParticleSystem_t* system); void deinit_particle_system(ParticleSystem_t* system); #endif // _PARTICLE_SYSTEM_H diff --git a/level_load_test.c b/level_load_test.c index 0eb7bcd..a6494de 100644 --- a/level_load_test.c +++ b/level_load_test.c @@ -6,6 +6,7 @@ #include "assets_loader.h" #include #include +#include Scene_t* scenes[1]; static GameEngine_t engine = @@ -39,10 +40,14 @@ int main(void) scenes[0] = &scene.scene; change_scene(&engine, 0); + const float DT = 1.0f/60.0f; while(true) { + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + process_inputs(&engine, &scene.scene); - update_scene(&scene.scene); + update_scene(&scene.scene, delta_time); update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta render_scene(&scene.scene); diff --git a/main.c b/main.c index 266c9f4..2e99e47 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #include "ent_impl.h" #include "mempool.h" #include +#include #define N_SCENES 4 Scene_t *scenes[N_SCENES]; @@ -79,6 +80,7 @@ int main(void) scenes[2] = &sandbox_scene.scene; change_scene(&engine, 0); + const float DT = 1.0f/60.0f; while (!WindowShouldClose()) { // This entire key processing relies on the assumption that a pressed key will @@ -92,7 +94,11 @@ int main(void) process_inputs(&engine, curr_scene); - update_scene(curr_scene); + + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + + update_scene(curr_scene, delta_time); update_entity_manager(&curr_scene->ent_manager); // This is needed to advance time delta render_scene(curr_scene); diff --git a/menu_test.c b/menu_test.c index c957aa8..a17b053 100644 --- a/menu_test.c +++ b/menu_test.c @@ -2,10 +2,12 @@ #include "scene_impl.h" #include #include +#include // Maintain own queue to handle key presses struct sc_queue_32 key_buffer; +const float DT = 1.0f/60.0f; int main(void) { sc_queue_init(&key_buffer); @@ -48,7 +50,9 @@ int main(void) sc_queue_add_last(&key_buffer, button); } - update_scene(&scene.scene); + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + update_scene(&scene.scene, delta_time); update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta BeginDrawing(); diff --git a/particle_test.c b/particle_test.c index 61d08d1..7eb4eb5 100644 --- a/particle_test.c +++ b/particle_test.c @@ -8,9 +8,7 @@ static const Vector2 GRAVITY = {0, GRAV_ACCEL}; void simple_particle_system_update(Particle_t* part, void* user_data) { - (void)user_data; - - float delta_time = DELTA_T; // TODO: Will need to think about delta time handling + float delta_time = *(float*)user_data; // TODO: Will need to think about delta time handling part->rotation += part->angular_vel; part->velocity = @@ -70,6 +68,9 @@ int main(void) .name = "test_spr" }; + const float DT = 1.0f/60.0f; + float delta_time = 0.0f; + EmitterConfig_t conf ={ .one_shot = true, .launch_range = {0, 360}, @@ -86,6 +87,7 @@ int main(void) .update_func = &simple_particle_system_update, .emitter_update_func = NULL, .spr = (tex.width == 0) ? NULL : &spr, + .user_data = &delta_time, }; EmitterConfig_t conf2 ={ @@ -106,6 +108,7 @@ int main(void) .update_func = &simple_particle_system_update, .emitter_update_func = &check_mouse_click, .spr = (tex.width == 0) ? NULL : &spr, + .user_data = &delta_time, }; bool key_press = false; @@ -114,6 +117,8 @@ int main(void) EmitterHandle han = 0; while(!WindowShouldClose()) { + float frame_time = GetFrameTime(); + delta_time = fminf(frame_time, DT); Vector2 mouse_pos = GetMousePosition(); if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { @@ -145,7 +150,7 @@ int main(void) han = 0; } - update_particle_system(&part_sys); + update_particle_system(&part_sys, delta_time); sprintf(text_buffer, "free: %u", get_number_of_free_emitter(&part_sys)); BeginDrawing(); ClearBackground(RAYWHITE); diff --git a/scene_test.c b/scene_test.c index 037cecb..140895d 100644 --- a/scene_test.c +++ b/scene_test.c @@ -3,6 +3,7 @@ #include "assets_loader.h" #include #include +#include #if defined(PLATFORM_WEB) #include #include @@ -10,6 +11,7 @@ return true; // Just preventDefault everything lol } #endif +const float DT = 1.0f/60.0f; Scene_t* scenes[1]; static GameEngine_t engine = @@ -26,7 +28,9 @@ void update_loop(void) Scene_t* scene = engine.scenes[engine.curr_scene]; process_inputs(&engine, scene); - update_scene(scene); + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + update_scene(scene, delta_time); update_entity_manager(&scene->ent_manager); // This is needed to advance time delta render_scene(scene); @@ -75,6 +79,7 @@ int main(void) emscripten_set_main_loop(update_loop, 0, 1); #else puts("Regular main loop"); + const float DT = 1.0f/60.0f; while(true) { @@ -82,7 +87,10 @@ int main(void) // appear in the polling of raylib process_inputs(&engine, &scene.scene); - update_scene(&scene.scene); + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + + update_scene(&scene.scene, delta_time); update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta render_scene(&scene.scene); diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index de9be8e..7e10c66 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -961,9 +961,20 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed) } break; case ACTION_SET_SPAWNPOINT: - { p_player->spawn_pos = p_player->position; - } + break; + case ACTION_TOGGLE_TIMESLOW: + if (!pressed) + { + if (scene->time_scale < 1.0f) + { + scene->time_scale = 1.0f; + } + else + { + scene->time_scale = 0.5f; + } + } break; default: break; @@ -1233,6 +1244,7 @@ void init_sandbox_scene(LevelScene_t* scene) sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART); sc_map_put_64(&scene->scene.action_map, KEY_B, ACTION_TOGGLE_GRID); sc_map_put_64(&scene->scene.action_map, KEY_V, ACTION_SET_SPAWNPOINT); + sc_map_put_64(&scene->scene.action_map, KEY_U, ACTION_TOGGLE_TIMESLOW); } diff --git a/scenes/game_systems.c b/scenes/game_systems.c index 6ff436a..ee273e3 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -63,7 +63,7 @@ static inline void destroy_tile(LevelSceneData_t* lvl_data, unsigned int tile_id .y = tile_idx / tilemap.width * tilemap.tile_size + tilemap.tile_size / 2, }, .n_particles = 5, - .user_data = lvl_data, + .user_data = CONTAINER_OF(lvl_data, LevelScene_t, data), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -247,7 +247,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) .config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .position = p_ent->position, .n_particles = 5, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -261,7 +261,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) .config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .position = p_ent->position, .n_particles = 5, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -274,7 +274,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) .config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .position = p_ent->position, .n_particles = 5, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -285,7 +285,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) .config = get_emitter_conf(&scene->engine->assets, "pe_single"), .position = p_ent->position, .n_particles = 1, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -300,7 +300,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent) .config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .position = p_ent->position, .n_particles = 2, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -932,9 +932,9 @@ void global_external_forces_system(Scene_t* scene) CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); - if (p_ctransform->grav_timer > 0) + if (p_ctransform->grav_timer > 0.0f) { - p_ctransform->grav_timer--; + p_ctransform->grav_timer -= scene->delta_time; continue; } @@ -1022,11 +1022,13 @@ void moveable_update_system(Scene_t* scene) } else if (remaining_distance > 0.1) { - p_ent->position.x += (remaining_distance > p_moveable->move_speed) ? p_moveable->move_speed : remaining_distance; + float x_to_move = p_moveable->move_speed * scene->delta_time; + p_ent->position.x += (remaining_distance > x_to_move) ? x_to_move : remaining_distance; } else { - p_ent->position.x += (remaining_distance < -p_moveable->move_speed) ? -p_moveable->move_speed : remaining_distance; + float x_to_move = p_moveable->move_speed * scene->delta_time; + p_ent->position.x += (remaining_distance < -x_to_move) ? -x_to_move : remaining_distance; memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity)); } } @@ -1083,8 +1085,8 @@ void moveable_update_system(Scene_t* scene) CBBox_t* p_other_bbox = get_component(other_ent, CBBOX_COMP_T); if (p_other_bbox != NULL) { - //any_solid |= p_other_bbox->solid; - any_solid |= true; + any_solid |= p_other_bbox->solid; + //any_solid |= true; break; } } @@ -1094,8 +1096,8 @@ void moveable_update_system(Scene_t* scene) CBBox_t* p_other_bbox = get_component(other_ent, CBBOX_COMP_T); if (p_other_bbox != NULL) { - //any_solid |= p_other_bbox->solid; - any_solid |= true; + any_solid |= p_other_bbox->solid; + //any_solid |= true; break; } } @@ -1257,7 +1259,7 @@ void movement_update_system(Scene_t* scene) LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); TileGrid_t tilemap = data->tilemap; // Update movement - float delta_time = DELTA_T; // TODO: Will need to think about delta time handling + float delta_time = scene->delta_time; CTransform_t * p_ctransform; unsigned long ent_idx; sc_map_foreach(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], ent_idx, p_ctransform) @@ -1486,7 +1488,7 @@ void state_transition_update_system(Scene_t* scene) .config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .position = p_ent->position, .n_particles = 5, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = (CONTAINER_OF(scene, LevelScene_t, scene)), .update_func = &simple_particle_system_update, .emitter_update_func = NULL, }; @@ -1703,16 +1705,16 @@ void hitbox_update_system(Scene_t* scene) CContainer_t* p_container = get_component(p_other_ent, CCONTAINER_T); if (p_container->item == CONTAINER_BOMB) { - p_clifetimer->life_time = 6; + p_clifetimer->life_time = 0.1f; } else { - p_clifetimer->life_time = 3; + p_clifetimer->life_time = 0.05f; } } else { - p_clifetimer->life_time = 3; + p_clifetimer->life_time = 0.05f; } } } @@ -1873,8 +1875,9 @@ void lifetimer_update_system(Scene_t* scene) CLifeTimer_t* p_lifetimer; sc_map_foreach(&scene->ent_manager.component_map[CLIFETIMER_T], ent_idx, p_lifetimer) { - p_lifetimer->life_time--; - if (p_lifetimer->life_time == 0) + p_lifetimer->life_time -= scene->delta_time; + + if (p_lifetimer->life_time <= 0.0f) { destroy_entity(scene, &tilemap, get_entity(&scene->ent_manager, ent_idx)); } @@ -1937,7 +1940,7 @@ void airtimer_update_system(Scene_t* scene) //.position = new_pos, .position = p_ent->position, .n_particles = 5, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &floating_particle_system_update, .emitter_update_func = &check_in_water, }; @@ -1949,22 +1952,22 @@ void airtimer_update_system(Scene_t* scene) } } - if (p_air->curr_ftimer > p_air->decay_rate) + if (p_air->curr_ftimer > p_air->decay_rate * scene->delta_time) { - p_air->curr_ftimer -= p_air->decay_rate; + p_air->curr_ftimer -= p_air->decay_rate * scene->delta_time; } else { if (p_air->curr_count > 0) { p_air->curr_count--; - p_air->curr_ftimer = p_air->max_ftimer; + p_air->curr_ftimer += p_air->max_ftimer; ParticleEmitter_t emitter = { .spr = get_sprite(&scene->engine->assets, "p_bigbubble"), .config = get_emitter_conf(&scene->engine->assets, "pe_slow"), .position = p_ent->position, .n_particles = 1, - .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), + .user_data = CONTAINER_OF(scene, LevelScene_t, scene), .update_func = &floating_particle_system_update, .emitter_update_func = NULL, }; @@ -2011,12 +2014,18 @@ void sprite_animation_system(Scene_t* scene) if (reset) p_cspr->current_frame = 0; // Animate it (handle frame count) - spr.sprite->elapsed++; - if (spr.sprite->elapsed == spr.sprite->speed) + p_cspr->fractional += scene->delta_time; + const float ANIM_FRAME_RATE = 1.0f/24; + if (p_cspr->fractional > ANIM_FRAME_RATE) { - p_cspr->current_frame++; - p_cspr->current_frame %= spr.sprite->frame_count; - spr.sprite->elapsed = 0; + p_cspr->fractional -= ANIM_FRAME_RATE; + spr.sprite->elapsed++; + if (spr.sprite->elapsed == spr.sprite->speed) + { + p_cspr->current_frame++; + p_cspr->current_frame %= spr.sprite->frame_count; + spr.sprite->elapsed = 0; + } } } } @@ -2062,15 +2071,15 @@ void camera_update_system(Scene_t* scene) float v = data->camera.current_vel.x - target_vel.x; float F = data->camera.k * x - data->camera.c * v; // Kinematics update - const float dt = DELTA_T; + const float dt = scene->delta_time; float a_dt = F * dt / data->camera.mass; data->camera.cam.target.x += (data->camera.current_vel.x + a_dt * 0.5) * dt; data->camera.current_vel.x += a_dt; // Simple lerp for y direction - float dy = data->camera.target_pos.y - data->camera.cam.target.y; - data->camera.cam.target.y += dy * 0.1; + float dy = (data->camera.target_pos.y - data->camera.cam.target.y); + data->camera.cam.target.y += dy * 0.1f; Vector2 max = GetWorldToScreen2D( (Vector2){ @@ -2160,10 +2169,10 @@ bool check_in_water(const ParticleEmitter_t* emitter) void simple_particle_system_update(Particle_t* part, void* user_data) { - LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data; - TileGrid_t tilemap = lvl_data->tilemap; + LevelScene_t* scene = (LevelScene_t*)user_data; + TileGrid_t tilemap = scene->data.tilemap; - float delta_time = DELTA_T; // TODO: Will need to think about delta time handling + float delta_time = scene->scene.delta_time; part->velocity = Vector2Add( part->velocity, @@ -2203,10 +2212,10 @@ void simple_particle_system_update(Particle_t* part, void* user_data) void simple_float_particle_system_update(Particle_t* part, void* user_data) { - LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data; - TileGrid_t tilemap = lvl_data->tilemap; + LevelScene_t* scene = (LevelScene_t*)user_data; + TileGrid_t tilemap = scene->data.tilemap; - float delta_time = DELTA_T; // TODO: Will need to think about delta time handling + float delta_time = scene->scene.delta_time; part->position = Vector2Add( part->position, Vector2Scale(part->velocity, delta_time) @@ -2233,8 +2242,8 @@ void floating_particle_system_update(Particle_t* part, void* user_data) { simple_float_particle_system_update(part, user_data); - LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data; - TileGrid_t tilemap = lvl_data->tilemap; + LevelScene_t* scene = (LevelScene_t*)user_data; + TileGrid_t tilemap = scene->data.tilemap; Vector2 center = Vector2AddValue( part->position, diff --git a/scenes/items_ent.c b/scenes/items_ent.c index abe718c..0d5afb0 100644 --- a/scenes/items_ent.c +++ b/scenes/items_ent.c @@ -44,7 +44,7 @@ Entity_t* create_crate(EntityManager_t* ent_manager, bool metal, ContainerItem_t p_bbox->fragile = false; CTransform_t* p_ctransform = add_component(p_crate, CTRANSFORM_COMP_T); - p_ctransform->grav_delay = 7; + p_ctransform->grav_delay = 0.20f; p_ctransform->shape_factor = metal ? (Vector2){0.7,0.7} : (Vector2){0.8,0.8} ; add_component(p_crate, CMOVEMENTSTATE_T); @@ -87,7 +87,7 @@ Entity_t* create_boulder(EntityManager_t* ent_manager) p_bbox->fragile = false; CTransform_t* p_ctransform = add_component(p_boulder, CTRANSFORM_COMP_T); - p_ctransform->grav_delay = 5; + p_ctransform->grav_delay = 1.0f/12; p_ctransform->active = true; p_ctransform->shape_factor = (Vector2){0.6, 0.6}; CMovementState_t* p_move = add_component(p_boulder, CMOVEMENTSTATE_T); @@ -95,7 +95,7 @@ Entity_t* create_boulder(EntityManager_t* ent_manager) add_component(p_boulder, CTILECOORD_COMP_T); CMoveable_t* p_cmove = add_component(p_boulder, CMOVEABLE_T); - p_cmove->move_speed = 8; + p_cmove->move_speed = 480; CHurtbox_t* p_hurtbox = add_component(p_boulder, CHURTBOX_T); p_hurtbox->size = p_bbox->size; p_hurtbox->def = 2; @@ -219,7 +219,7 @@ Entity_t* create_explosion(EntityManager_t* ent_manager) p_cspr->current_idx = 17; CLifeTimer_t* p_clifetimer = add_component(p_explosion, CLIFETIMER_T); - p_clifetimer->life_time = 3; + p_clifetimer->life_time = 0.05f; return p_explosion; } @@ -234,7 +234,7 @@ Entity_t* create_chest(EntityManager_t* ent_manager) p_bbox->fragile = true; CTransform_t* p_ctransform = add_component(p_chest, CTRANSFORM_COMP_T); - p_ctransform->grav_delay = 7; + p_ctransform->grav_delay = 0.3f; p_ctransform->shape_factor = (Vector2){0.7,0.7}; add_component(p_chest, CMOVEMENTSTATE_T); add_component(p_chest, CTILECOORD_COMP_T); diff --git a/scenes/water_flow.c b/scenes/water_flow.c index a1cd71b..697a8b6 100644 --- a/scenes/water_flow.c +++ b/scenes/water_flow.c @@ -289,6 +289,11 @@ void update_water_runner_system(Scene_t* scene) break; case SCANLINE_FILL: { + const float FILL_RATE = 1.0f/24; + p_crunner->fractional += scene->delta_time; + if (p_crunner->fractional < FILL_RATE) break; + + p_crunner->fractional -= FILL_RATE; // Unsigned usage here is okay unsigned int start_tile = (p_crunner->current_tile / p_crunner->bfs_tilemap.width) * p_crunner->bfs_tilemap.width; diff --git a/water_test.c b/water_test.c index 1e5a6bc..82b0273 100644 --- a/water_test.c +++ b/water_test.c @@ -451,10 +451,14 @@ int main(void) sc_map_put_64(&scene.scene.action_map, KEY_P, ACTION_METAL_TOGGLE); + const float DT = 1.0f/60.0f; while(true) { + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + process_inputs(&engine, &scene.scene); - update_scene(&scene.scene); + update_scene(&scene.scene, delta_time); update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta render_scene(&scene.scene);