Add level select scene

Just a render texture with simple scroll
level_select
En Yi 2024-07-02 21:54:54 +08:00
parent b158bee1e8
commit 893fc1c73f
6 changed files with 167 additions and 4 deletions

View File

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

View File

@ -0,0 +1,64 @@
#include "mempool.h"
#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);
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();
}

View File

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

View File

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

View File

@ -0,0 +1,77 @@
#include "scene_impl.h"
#include "raymath.h"
#include <stdio.h>
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);
}

View File

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