diff --git a/inc/system/system.print.lua b/inc/system/system.print.lua index b38b67d..ffbeba1 100644 --- a/inc/system/system.print.lua +++ b/inc/system/system.print.lua @@ -10,7 +10,7 @@ function Print.text(text, x, y, color, fixed, scale) local shadow_color = Config.colors.black if color == shadow_color then shadow_color = Config.colors.light_grey end scale = scale or 1 - print(text, x + 1, y + 1, shadow_color, fixed, scale) + print(text, x + scale, y + scale, shadow_color, fixed, scale) print(text, x, y, color, fixed, scale) end @@ -24,7 +24,7 @@ end --- @param[opt] scale number The scaling factor.
function Print.text_center(text, x, y, color, fixed, scale) scale = scale or 1 - local text_width = print(text, 0, -6, 0, fixed, scale) + local text_width = print(text, 0, -6 * scale, 0, fixed, scale) local centered_x = x - (text_width / 2) Print.text(text, centered_x, y, color, fixed, scale) end diff --git a/inc/window/window.menu.lua b/inc/window/window.menu.lua index 6199db6..62afbf1 100644 --- a/inc/window/window.menu.lua +++ b/inc/window/window.menu.lua @@ -1,19 +1,62 @@ --- @section MenuWindow local _menu_items = {} local _click_timer = 0 +local _anim = 0 +local _menu_max_w = 0 +local ANIM_SPEED = 2.5 +local HEADER_H = 28 + +--- Calculates the animated x position of the menu block. +--- @within MenuWindow +--- @return number x The left edge x coordinate for the menu. +function MenuWindow.calc_menu_x() + local center_start = Config.screen.width / 2 + local center_end = Config.screen.width * 0.72 + local center = center_start + _anim * (center_end - center_start) + return math.floor(center - _menu_max_w / 2) +end + +--- Draws the header with title and separator. +--- @within MenuWindow +function MenuWindow.draw_header() + rect(0, 0, Config.screen.width, HEADER_H, Config.colors.dark_grey) + rect(0, HEADER_H - 2, Config.screen.width, 2, Config.colors.light_blue) + + local cx = Config.screen.width / 2 + local subtitle = "Definitely not an" + if Context.test_mode then subtitle = subtitle .. " [TEST]" end + local sub_w = print(subtitle, 0, -6, 0, false, 1, true) + print(subtitle, math.floor(cx - sub_w / 2) + 1, 5, Config.colors.dark_grey, false, 1, true) + print(subtitle, math.floor(cx - sub_w / 2), 4, Config.colors.light_grey, false, 1, true) + + Print.text_center("IMPOSTOR", cx, 12, Config.colors.item, false, 2) +end + +--- Draws the 4x scaled Norman sprite on the left side of the screen. +--- @within MenuWindow +function MenuWindow.draw_norman() + local nx = math.floor(Config.screen.width * 0.45 / 2) - 32 + local ny = HEADER_H + math.floor((Config.screen.height - HEADER_H - 96) / 2) + spr(272, nx, ny, 0, 4) + spr(273, nx + 32, ny, 0, 4) + spr(288, nx, ny + 32, 0, 4) + spr(289, nx + 32, ny + 32, 0, 4) + spr(304, nx, ny + 64, 0, 4) + spr(305, nx + 32, ny + 64, 0, 4) +end --- Draws the menu window. --- @within MenuWindow function MenuWindow.draw() - local title = "Definitely not an Impostor" - if Context.test_mode then - title = title .. " (TEST MODE)" + MenuWindow.draw_header() + + if _anim > 0 then + MenuWindow.draw_norman() end - UI.draw_top_bar(title) local menu_h = #_menu_items * 10 - local y = 10 + (Config.screen.height - 10 - 10 - menu_h) / 2 - UI.draw_menu(_menu_items, Context.current_menu_item, 0, y, true) + local y = HEADER_H + math.floor((Config.screen.height - HEADER_H - 10 - menu_h) / 2) + UI.draw_menu(_menu_items, Context.current_menu_item, MenuWindow.calc_menu_x(), y, false) local ttg_text = "TTG" local ttg_w = print(ttg_text, 0, -10, 0, false, 1, false) @@ -23,8 +66,12 @@ end --- Updates the menu window logic. --- @within MenuWindow function MenuWindow.update() + if _anim < 1 then + _anim = math.min(1, _anim + ANIM_SPEED * Context.delta_time) + end + local menu_h = #_menu_items * 10 - local y = 10 + (Config.screen.height - 10 - 10 - menu_h) / 2 + local y = HEADER_H + math.floor((Config.screen.height - HEADER_H - 10 - menu_h) / 2) if _click_timer > 0 then _click_timer = _click_timer - Context.delta_time @@ -38,7 +85,7 @@ function MenuWindow.update() return end - local new_item, mouse_confirmed = UI.update_menu(_menu_items, Context.current_menu_item, 0, y, true) + local new_item, mouse_confirmed = UI.update_menu(_menu_items, Context.current_menu_item, MenuWindow.calc_menu_x(), y, false) Context.current_menu_item = new_item if mouse_confirmed then @@ -104,7 +151,7 @@ function MenuWindow.continued() GameWindow.set_state("continued") end ---- Opens the minigame ddr test menu. +--- Opens the DDR minigame test. --- @within MenuWindow function MenuWindow.ddr_test() AudioTestWindow.init() @@ -112,27 +159,34 @@ function MenuWindow.ddr_test() MinigameDDRWindow.start("menu", "generated", { special_mode = "only_nothing" }) end ---- Refreshes menu items. +--- Refreshes the list of menu items based on current game state. --- @within MenuWindow function MenuWindow.refresh_menu_items() _menu_items = {} if Context.game_in_progress then table.insert(_menu_items, {label = "Resume Game", decision = MenuWindow.resume_game}) - table.insert(_menu_items, {label = "Save Game", decision = MenuWindow.save_game}) + table.insert(_menu_items, {label = "Save Game", decision = MenuWindow.save_game}) end - table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game}) + table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game}) table.insert(_menu_items, {label = "Load Game", decision = MenuWindow.load_game}) - table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls}) + table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls}) if Context.test_mode then - table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test}) + table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test}) table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued}) - table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test}) + table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test}) end table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit}) + _menu_max_w = 0 + for _, item in ipairs(_menu_items) do + local w = print(item.label, 0, -10, 0, false, 1, false) + if w > _menu_max_w then _menu_max_w = w end + end + Context.current_menu_item = 1 _click_timer = 0 + _anim = 0 end