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
scene_man
En Yi 2024-04-23 22:44:52 +08:00
parent 55ba03f2d6
commit 0a6e7b4ddc
16 changed files with 135 additions and 71 deletions

View File

@ -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 {

View File

@ -18,5 +18,6 @@ typedef enum ActionType
ACTION_PREVLEVEL,
ACTION_TOGGLE_GRID,
ACTION_SET_SPAWNPOINT,
ACTION_TOGGLE_TIMESLOW,
}ActionType_t;
#endif // __ACTIONS_H

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -6,6 +6,7 @@
#include "assets_loader.h"
#include <stdio.h>
#include <unistd.h>
#include <math.h>
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);

8
main.c
View File

@ -4,6 +4,7 @@
#include "ent_impl.h"
#include "mempool.h"
#include <stdio.h>
#include <math.h>
#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);

View File

@ -2,10 +2,12 @@
#include "scene_impl.h"
#include <stdio.h>
#include <unistd.h>
#include <math.h>
// 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();

View File

@ -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);

View File

@ -3,6 +3,7 @@
#include "assets_loader.h"
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);