From 451b099ec4bf7c90449e99980ee490b684846591 Mon Sep 17 00:00:00 2001 From: En Yi Date: Wed, 22 Jan 2025 22:24:19 +0800 Subject: [PATCH] Update level select scene --- engine/gui.c | 39 +++++++++++++++++++++++++++++-------- engine/gui.h | 5 +++++ scenes/level_select_scene.c | 30 ++++++++++++++-------------- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/engine/gui.c b/engine/gui.c index 97343a9..37379c1 100644 --- a/engine/gui.c +++ b/engine/gui.c @@ -1,4 +1,5 @@ #include "gui.h" +#include "raylib.h" #include #define RAYGUI_MAX_CONTROLS 16 // Maximum number of standard controls @@ -633,6 +634,7 @@ float UI_slider(const UIComp_t* comp, const char *textLeft, const char *textRigh void vert_scrollarea_init(VertScrollArea_t* scroll_area, Rectangle display_area, Vector2 canvas_dims) { + scroll_area->comp.font = GetFontDefault(); scroll_area->canvas = LoadRenderTexture(canvas_dims.x, canvas_dims.y); scroll_area->scroll_pos = canvas_dims.y - display_area.height; scroll_area->scroll_bounds = (Vector2){ @@ -661,14 +663,29 @@ void vert_scrollarea_set_item_dims(VertScrollArea_t* scroll_area, unsigned int i { scroll_area->item_height = item_height; scroll_area->item_padding = item_padding; - scroll_area->n_items = (scroll_area->canvas.texture.height - scroll_area->item_padding) / (scroll_area->item_height + scroll_area->item_padding); + scroll_area->max_items = (scroll_area->canvas.texture.height - scroll_area->item_padding) / (scroll_area->item_height + scroll_area->item_padding); +} + +bool vert_scrollarea_n_items(VertScrollArea_t* scroll_area, unsigned int n_items) { + if (n_items >= scroll_area->max_items) return false; + + //scroll_area->n_items = n_items; + //scroll_area->scroll_bounds.y = n_items * (scroll_area->item_height + scroll_area->item_padding); + //scroll_area->scroll_pos = + // (scroll_area->scroll_pos > scroll_area->scroll_bounds.y ) ? + // scroll_area->scroll_bounds.y : (scroll_area->scroll_pos; + return true; } void vert_scrollarea_insert_item(VertScrollArea_t* scroll_area, char* str, unsigned int item_idx) { - if (item_idx >= scroll_area->n_items) return; + if (item_idx >= scroll_area->max_items) return; - DrawText(str, 0, scroll_area->item_padding + (scroll_area->item_height + scroll_area->item_padding) * item_idx, scroll_area->item_height, BLACK); + DrawTextEx( + scroll_area->comp.font, + str, + (Vector2){0, scroll_area->item_padding + (scroll_area->item_height + scroll_area->item_padding) * item_idx} + , scroll_area->item_height, 0, BLACK); } unsigned int vert_scrollarea_set_pos(VertScrollArea_t* scroll_area, Vector2 pos) @@ -676,18 +693,22 @@ unsigned int vert_scrollarea_set_pos(VertScrollArea_t* scroll_area, Vector2 pos) float x = pos.x - scroll_area->display_area.x; float y = pos.y - scroll_area->display_area.y; - if (x >= scroll_area->display_area.width || x < 0) return scroll_area->n_items; - if (y >= scroll_area->display_area.height || y < 0) return scroll_area->n_items; + if (x >= scroll_area->display_area.width || x < 0) return scroll_area->max_items; + if (y >= scroll_area->display_area.height || y < 0) return scroll_area->max_items; + // How much have scroll down + float canvas_offset = (scroll_area->scroll_bounds.y - scroll_area->scroll_pos); - scroll_area->curr_selection = (y - scroll_area->item_padding + (scroll_area->scroll_bounds.y - scroll_area->scroll_pos)) / (scroll_area->item_height + scroll_area->item_padding); + scroll_area->curr_selection = (y + canvas_offset - scroll_area->item_padding) / (scroll_area->item_height + scroll_area->item_padding); return scroll_area->curr_selection; } void vert_scrollarea_refocus(VertScrollArea_t* scroll_area) { - float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding - (scroll_area->scroll_bounds.y - scroll_area->scroll_pos); + float canvas_offset = (scroll_area->scroll_bounds.y - scroll_area->scroll_pos); + // Reverse from item selection to y in display area + float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding - canvas_offset; // Auto adjust scroll based on selection if (selection_y < 0) @@ -717,7 +738,9 @@ void vert_scrollarea_render(VertScrollArea_t* scroll_area) scroll_area->display_area.width, scroll_area->display_area.height }; - float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding - (scroll_area->scroll_bounds.y - scroll_area->scroll_pos); + + float canvas_offset = (scroll_area->scroll_bounds.y - scroll_area->scroll_pos); + float selection_y = scroll_area->curr_selection * (scroll_area->item_height + scroll_area->item_padding) + scroll_area->item_padding - canvas_offset; DrawRectangle( scroll_area->display_area.x, diff --git a/engine/gui.h b/engine/gui.h index 039bfdf..f8bf14b 100644 --- a/engine/gui.h +++ b/engine/gui.h @@ -9,6 +9,7 @@ typedef struct UIComp { GuiState state; float alpha; bool pressed; + Font font; } UIComp_t; typedef struct VertScrollArea { @@ -18,12 +19,15 @@ typedef struct VertScrollArea { RenderTexture2D canvas; // Complete canvas unsigned int n_items; + unsigned int max_items; unsigned int curr_selection; unsigned int item_height; unsigned int item_padding; float scroll_pos; + float max_scroll_bounds; Vector2 scroll_bounds; + UIComp_t scroll_bar; } VertScrollArea_t; @@ -31,6 +35,7 @@ typedef struct VertScrollArea { void init_UI(void); void vert_scrollarea_init(VertScrollArea_t* scroll_area, Rectangle display_area, Vector2 canvas_dims); void vert_scrollarea_set_item_dims(VertScrollArea_t* scroll_area, unsigned int item_height, unsigned int item_padding); +bool vert_scrollarea_n_items(VertScrollArea_t* scroll_area, unsigned int n_items); void vert_scrollarea_insert_item(VertScrollArea_t* scroll_area, char* str, unsigned int item_idx); unsigned int vert_scrollarea_set_pos(VertScrollArea_t* scroll_area, Vector2 pos); void vert_scrollarea_refocus(VertScrollArea_t* scroll_area); diff --git a/scenes/level_select_scene.c b/scenes/level_select_scene.c index 289f83a..977df72 100644 --- a/scenes/level_select_scene.c +++ b/scenes/level_select_scene.c @@ -7,10 +7,10 @@ static void level_select_render_func(Scene_t* scene) { LevelSelectSceneData_t* data = &(CONTAINER_OF(scene, LevelSelectScene_t, scene)->data); - Sprite_t* spr = get_sprite(&scene->engine->assets, "bunny_spr1"); Sprite_t* level_board = get_sprite(&scene->engine->assets, "lvl_board"); Sprite_t* level_select = get_sprite(&scene->engine->assets, "lvl_select"); Sprite_t* preview = get_sprite(&scene->engine->assets, "lvlprvw"); + Font* menu_font = get_font(&scene->engine->assets, "MenuFont"); BeginTextureMode(scene->layers.render_layers[0].layer_tex); ClearBackground(BLANK); draw_sprite(level_select, 0, (Vector2){0,0},0, false); @@ -20,13 +20,8 @@ static void level_select_render_func(Scene_t* scene) level_select->frame_size.x + (level_board->frame_size.x - preview->frame_size.x) / 2, (level_board->frame_size.y - preview->frame_size.y) / 2, },0, false); - DrawText("Level Select", 10, 10, 40, BLACK); + DrawTextEx(*menu_font, "Level Select", (Vector2){60, 20}, 40, 4, BLACK); vert_scrollarea_render(&data->scroll_area); - draw_sprite( - spr, 0, (Vector2){ - scene->engine->intended_window_size.x / 2, - scene->engine->intended_window_size.y / 2, - }, 0, false); EndTextureMode(); } @@ -48,7 +43,7 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre case ACTION_DOWN: if (!pressed) { - if (data->scroll_area.curr_selection < data->scroll_area.n_items - 1) + if (data->scroll_area.curr_selection < data->level_pack->n_levels - 1) { data->scroll_area.curr_selection++; vert_scrollarea_refocus(&data->scroll_area); @@ -69,7 +64,7 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre { unsigned int prev_sel = data->scroll_area.curr_selection; // TODO: Add scene offset to scroll area calculation - if (vert_scrollarea_set_pos(&data->scroll_area, scene->mouse_pos) != data->scroll_area.n_items) + if (vert_scrollarea_set_pos(&data->scroll_area, scene->mouse_pos) != data->scroll_area.max_items) { vert_scrollarea_refocus(&data->scroll_area); @@ -107,10 +102,9 @@ static void level_select_do_action(Scene_t* scene, ActionType_t action, bool pre } } -#define FONT_SIZE 15 +#define FONT_SIZE 22 #define TEXT_PADDING 3 -#define DISPLAY_AREA_HEIGHT 400 -#define SCROLL_TOTAL_HEIGHT 400 +#define SCROLL_TOTAL_HEIGHT 800 void init_level_select_scene(LevelSelectScene_t* scene) { init_scene(&scene->scene, &level_select_do_action, 0); @@ -124,26 +118,32 @@ void init_level_select_scene(LevelSelectScene_t* scene) } ); scene->scene.bg_colour = BLACK; - vert_scrollarea_init(&scene->data.scroll_area, (Rectangle){50, 100, 150, DISPLAY_AREA_HEIGHT - 100}, (Vector2){150, SCROLL_TOTAL_HEIGHT}); + Sprite_t* level_select = get_sprite(&scene->scene.engine->assets, "lvl_select"); + vert_scrollarea_init(&scene->data.scroll_area, (Rectangle){50, 75, level_select->frame_size.x * 0.6, level_select->frame_size.y * 3 / 4}, (Vector2){level_select->frame_size.x * 0.6, SCROLL_TOTAL_HEIGHT}); vert_scrollarea_set_item_dims(&scene->data.scroll_area, FONT_SIZE, TEXT_PADDING); + Font* menu_font = get_font(&scene->scene.engine->assets, "MenuFont"); + if (menu_font != NULL) { + scene->data.scroll_area.comp.font = *menu_font; + } char buf[32]; ScrollAreaRenderBegin(&scene->data.scroll_area); ClearBackground(BLANK); if (scene->data.level_pack != NULL) { scene->data.scroll_area.n_items = scene->data.level_pack->n_levels; + //vert_scrollarea_n_items(&scene->data.scroll_area, scene->data.level_pack->n_levels); for (unsigned int i = 0; i < scene->data.level_pack->n_levels; ++i) { vert_scrollarea_insert_item(&scene->data.scroll_area, scene->data.level_pack->levels[i].level_name, i); } - for (unsigned int i = scene->data.level_pack->n_levels; i < scene->data.scroll_area.n_items; ++i) + for (unsigned int i = scene->data.level_pack->n_levels; i < scene->data.scroll_area.max_items; ++i) { vert_scrollarea_insert_item(&scene->data.scroll_area, "---", i); } } else { - for (unsigned int i = 0; i < scene->data.scroll_area.n_items; ++i) + for (unsigned int i = 0; i < scene->data.scroll_area.max_items; ++i) { sprintf(buf, "Level %u", i); vert_scrollarea_insert_item(&scene->data.scroll_area, buf, i);