From 893fc1c73f29dc07da4886102d3cb2f47b4d4a63 Mon Sep 17 00:00:00 2001 From: En Yi Date: Tue, 2 Jul 2024 21:54:54 +0800 Subject: [PATCH] Add level select scene Just a render texture with simple scroll --- CMakeLists.txt | 12 ++++++ level_select_test.c | 64 ++++++++++++++++++++++++++++++ menu_test.c | 6 +-- scenes/CMakeLists.txt | 1 + scenes/level_select_scene.c | 77 +++++++++++++++++++++++++++++++++++++ scenes/scene_impl.h | 11 ++++++ 6 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 level_select_test.c create mode 100644 scenes/level_select_scene.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac5b9f..97f4f5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,18 @@ target_link_options(scene_man_test PRIVATE -fsanitize=address -gdwarf-4) target_link_libraries(scene_man_test ${GAME_LIBS} ) +add_executable(level_select_test + level_select_test.c +) +target_include_directories(level_select_test + PRIVATE + ${CMAKE_CURRENT_LIST_DIR} +) +target_compile_options(level_select_test PRIVATE -fsanitize=address -gdwarf-4) +target_link_options(level_select_test PRIVATE -fsanitize=address -gdwarf-4) +target_link_libraries(level_select_test + ${GAME_LIBS} +) if (BUILD_TESTING) find_package(cmocka 1.1.0 REQUIRED) diff --git a/level_select_test.c b/level_select_test.c new file mode 100644 index 0000000..a6db234 --- /dev/null +++ b/level_select_test.c @@ -0,0 +1,64 @@ +#include "mempool.h" +#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); + InitWindow(1280, 640, "raylib"); + SetTargetFPS(60); + init_memory_pools(); + LevelSelectScene_t scene; + init_level_select_scene(&scene); + scene.scene.bg_colour = RAYWHITE; + while(true) + { + + // This entire key processing relies on the assumption that a pressed key will + // appear in the polling of raylib + + unsigned int sz = sc_queue_size(&key_buffer); + // Process any existing pressed key + for (size_t i = 0; i < sz; i++) + { + int button = sc_queue_del_first(&key_buffer); + ActionType_t action = sc_map_get_64(&scene.scene.action_map, button); + if (IsKeyReleased(button)) + { + do_action(&scene.scene, action, false); + } + else + { + do_action(&scene.scene, action, true); + sc_queue_add_last(&key_buffer, button); + } + } + + // Detect new key presses + while(true) + { + int button = GetKeyPressed(); + if (button == 0) break; + ActionType_t action = sc_map_get_64(&scene.scene.action_map, button); + if (!sc_map_found(&scene.scene.action_map)) continue; + do_action(&scene.scene, action, true); + sc_queue_add_last(&key_buffer, button); + } + + float frame_time = GetFrameTime(); + float delta_time = fminf(frame_time, DT); + update_scene(&scene.scene, delta_time); + // This is needed to advance time delta + render_scene(&scene.scene); + if (WindowShouldClose()) break; + } + free_level_select_scene(&scene); + sc_queue_term(&key_buffer); + CloseWindow(); +} diff --git a/menu_test.c b/menu_test.c index a17b053..d5fa4a4 100644 --- a/menu_test.c +++ b/menu_test.c @@ -16,6 +16,7 @@ int main(void) init_memory_pools(); MenuScene_t scene; init_menu_scene(&scene); + scene.scene.bg_colour = RAYWHITE; while(true) { @@ -55,10 +56,7 @@ int main(void) update_scene(&scene.scene, delta_time); update_entity_manager(&scene.scene.ent_manager); // This is needed to advance time delta - BeginDrawing(); - render_scene(&scene.scene); - ClearBackground(RAYWHITE); - EndDrawing(); + render_scene(&scene.scene); if (WindowShouldClose()) break; } free_menu_scene(&scene); diff --git a/scenes/CMakeLists.txt b/scenes/CMakeLists.txt index 26a16d1..5239a74 100644 --- a/scenes/CMakeLists.txt +++ b/scenes/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(lib_scenes STATIC water_flow.c editor_scene.c menu_scene.c + level_select_scene.c game_scene.c game_systems.c scene_systems.c diff --git a/scenes/level_select_scene.c b/scenes/level_select_scene.c new file mode 100644 index 0000000..86ae542 --- /dev/null +++ b/scenes/level_select_scene.c @@ -0,0 +1,77 @@ +#include "scene_impl.h" +#include "raymath.h" +#include + +static void level_select_render_func(Scene_t* scene) +{ + LevelSelectSceneData_t* data = &(CONTAINER_OF(scene, LevelSelectScene_t, scene)->data); + BeginTextureMode(scene->layers.render_layers[0].layer_tex); + ClearBackground(RAYWHITE); + Rectangle draw_rec = (Rectangle){ + 0, data->scroll, + scene->layers.render_layers[0].render_area.width, + scene->layers.render_layers[0].render_area.height + }; + Vector2 draw_pos = {50, 50}; + draw_rec.height *= -1; + DrawTextureRec( + data->level_display.texture, + draw_rec, + draw_pos, + WHITE + ); + EndTextureMode(); +} + +static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pressed) +{ + LevelSelectSceneData_t* data = &(CONTAINER_OF(scene, LevelSelectScene_t, scene)->data); + switch(action) + { + case ACTION_UP: + if (pressed) + { + data->scroll += 3; + data->scroll = Clamp(data->scroll, 0, 400); + } + break; + case ACTION_DOWN: + if (pressed) + { + data->scroll -= 3; + data->scroll = Clamp(data->scroll, 0, 400); + } + break; + default: + break; + } +} + +void init_level_select_scene(LevelSelectScene_t* scene) +{ + init_scene(&scene->scene, &level_select_do_action); + add_scene_layer( + &scene->scene, 300, 400, + (Rectangle){0, 0, 300, 400} + ); + scene->data.scroll = 400; + scene->data.level_display = LoadRenderTexture(300, 800); + const unsigned int n_elems = 800 / (12+3); + BeginTextureMode(scene->data.level_display); + ClearBackground(GRAY); + for (unsigned int i = 0; i < n_elems; ++i) + { + char buf[32]; + sprintf(buf, "Level %u", i); + DrawText(buf, 0, (12+3) * i, 12, BLACK); + } + EndTextureMode(); + + sc_array_add(&scene->scene.systems, &level_select_render_func); + sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP); + sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); +} +void free_level_select_scene(LevelSelectScene_t* scene) +{ + free_scene(&scene->scene); +} diff --git a/scenes/scene_impl.h b/scenes/scene_impl.h index ea039d8..63b068a 100644 --- a/scenes/scene_impl.h +++ b/scenes/scene_impl.h @@ -86,7 +86,18 @@ typedef struct MenuScene { MenuSceneData_t data; } MenuScene_t; +typedef struct LevelSelectSceneData { + RenderTexture2D level_display; + float scroll; +} LevelSelectSceneData_t; + +typedef struct LevelSelectScene { + Scene_t scene; + LevelSelectSceneData_t data; +} LevelSelectScene_t; void init_menu_scene(MenuScene_t* scene); void free_menu_scene(MenuScene_t* scene); +void init_level_select_scene(LevelSelectScene_t* scene); +void free_level_select_scene(LevelSelectScene_t* scene); #endif // __SCENE_IMPL_H