From 3e6a53b0975208fe05106234154fc769c5a6d0c4 Mon Sep 17 00:00:00 2001 From: En Yi Date: Mon, 12 Dec 2022 20:29:51 +0800 Subject: [PATCH] Fix incorrect player input processing Changelog: - Store player dir input in LevelScene Data instead of pointer, to avoid use-after-free (non-fatal as mempool is used, but can cause unintended behaviour) - Only process player movement in system update. This is done in the movement update system - Normalise before apply acceleration, duh --- scene_impl.c | 27 ++++++++++++++++++--------- scene_impl.h | 2 +- scene_test.c | 5 ++--- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/scene_impl.c b/scene_impl.c index ae57a8f..0a6191c 100644 --- a/scene_impl.c +++ b/scene_impl.c @@ -17,6 +17,19 @@ static void level_scene_render_func(Scene_t* scene) static void movement_update_system(Scene_t* scene) { + LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data; + float mag = Vector2Length(data->player_dir); + mag = (mag == 0)? 1 : mag; + Entity_t * p_player; + sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) + { + CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_player, CTRANSFORM_COMP_T); + p_ctransform->accel.x = data->player_dir.x * 200 * 1.0 / mag; + p_ctransform->accel.y = data->player_dir.y * 200 * 1.0 / mag; + } + data->player_dir.x = 0; + data->player_dir.y = 0; + float delta_time = GetFrameTime(); CTransform_t * p_ctransform; sc_map_foreach_value(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], p_ctransform) @@ -61,28 +74,24 @@ static void screen_bounce_system(Scene_t *scene) void level_do_action(Scene_t *scene, ActionType_t action, bool pressed) { LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data; - CTransform_t *p_ctransform = get_component(&scene->ent_manager, data->player, CTRANSFORM_COMP_T); - Vector2 dir = {0, 0}; if (pressed) { switch(action) { case ACTION_UP: - dir.y -= 1; + data->player_dir.y = -1; break; case ACTION_DOWN: - dir.y += 1; + data->player_dir.y = 1; break; case ACTION_LEFT: - dir.x -= 1; + data->player_dir.x = -1; break; case ACTION_RIGHT: - dir.x += 1; + data->player_dir.x = 1; break; } } - p_ctransform->accel.x = dir.x * 500; - p_ctransform->accel.y = dir.y * 500; } @@ -90,7 +99,7 @@ void init_level_scene(LevelScene_t *scene) { init_scene(&scene->scene, LEVEL_SCENE, &level_scene_render_func, &level_do_action); scene->scene.scene_data = &scene->data; - scene->data.player = NULL; + memset(&scene->data.player_dir, 0, sizeof(Vector2)); // insert level scene systems sc_array_add(&scene->scene.systems, &movement_update_system); diff --git a/scene_impl.h b/scene_impl.h index 3d05d35..00d7544 100644 --- a/scene_impl.h +++ b/scene_impl.h @@ -20,7 +20,7 @@ typedef struct TileGrid typedef struct LevelSceneData { - Entity_t * player; + Vector2 player_dir; TileGrid_t tilemap; }LevelSceneData_t; diff --git a/scene_test.c b/scene_test.c index 28ad45e..57afc9c 100644 --- a/scene_test.c +++ b/scene_test.c @@ -19,14 +19,14 @@ int main(void) LevelScene_t scene; init_level_scene(&scene); Entity_t *p_ent = add_entity(&scene.scene.ent_manager, PLAYER_ENT_TAG); - scene.data.player = p_ent; CBBox_t *p_bbox = add_component(&scene.scene.ent_manager, p_ent, CBBOX_COMP_T); p_bbox->size.x = 30; p_bbox->size.y = 30; add_component(&scene.scene.ent_manager, p_ent, CTRANSFORM_COMP_T); update_entity_manager(&scene.scene.ent_manager); - for (size_t step = 0; step < 6000; step++) + //for (size_t step = 0; step < 6000; step++) + while(true) { // This entire key processing relies on the assumption that a pressed key will @@ -68,7 +68,6 @@ int main(void) next_keybuf = tmp; } - printf("Step %lu\n", step); update_scene(&scene.scene); // This is needed to advance time delta BeginDrawing();