4
0

state to window

This commit is contained in:
2025-12-09 18:45:51 +01:00
parent 90192cb6a7
commit d52d7a0cf1

View File

@@ -43,26 +43,26 @@ local Config = {
} }
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Game States -- Game Windows
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local GAME_STATE_SPLASH = 0 local WINDOW_SPLASH = 0
local GAME_STATE_INTRO = 1 local WINDOW_INTRO = 1
local GAME_STATE_MENU = 2 local WINDOW_MENU = 2
local GAME_STATE_GAME = 3 local WINDOW_GAME = 3
local GAME_STATE_POPUP = 4 local WINDOW_POPUP = 4
local GAME_STATE_INVENTORY = 5 local WINDOW_INVENTORY = 5
local GAME_STATE_INVENTORY_ACTION = 6 local WINDOW_INVENTORY_ACTION = 6
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Modules -- Modules
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- State Modules (in GAME_STATE order) -- Window Modules (in WINDOW order)
local SplashState = {} local SplashWindow = {}
local IntroState = {} local IntroWindow = {}
local MenuState = {} local MenuWindow = {}
local GameState = {} local GameWindow = {}
local PopupState = {} -- Manages popups for GAME_STATE_POPUP and GAME_STATE_INVENTORY_ACTION local PopupWindow = {} -- Manages popups for WINDOW_POPUP and WINDOW_INVENTORY_ACTION
local InventoryState = {} -- Used for GAME_STATE_INVENTORY local InventoryWindow = {} -- Used for WINDOW_INVENTORY
-- Other Modules -- Other Modules
local UI = {} local UI = {}
@@ -73,10 +73,10 @@ local MenuActions = {}
local Player = {} local Player = {}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Game State -- Game Window
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local Context = { local Context = {
game_state = GAME_STATE_SPLASH, active_window = WINDOW_SPLASH,
inventory = {}, inventory = {},
intro = { intro = {
y = Config.screen.height, y = Config.screen.height,
@@ -340,7 +340,7 @@ local Context = {
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Inventory Module -- Inventory Module
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function InventoryState.draw() function InventoryWindow.draw()
UI.draw_top_bar("Inventory") UI.draw_top_bar("Inventory")
if #Context.inventory == 0 then if #Context.inventory == 0 then
@@ -357,21 +357,21 @@ function InventoryState.draw()
end end
end end
function InventoryState.update() function InventoryWindow.update()
Context.selected_inventory_item = UI.update_menu(Context.inventory, Context.selected_inventory_item) Context.selected_inventory_item = UI.update_menu(Context.inventory, Context.selected_inventory_item)
if Input.menu_confirm() and #Context.inventory > 0 then if Input.menu_confirm() and #Context.inventory > 0 then
local selected_item = Context.inventory[Context.selected_inventory_item] local selected_item = Context.inventory[Context.selected_inventory_item]
PopupState.show_menu_dialog(selected_item, { PopupWindow.show_menu_dialog(selected_item, {
{label = "Use", action = ItemActions.use}, {label = "Use", action = ItemActions.use},
{label = "Drop", action = ItemActions.drop}, {label = "Drop", action = ItemActions.drop},
{label = "Look at", action = ItemActions.look_at}, {label = "Look at", action = ItemActions.look_at},
{label = "Go back", action = ItemActions.go_back_from_inventory_action} {label = "Go back", action = ItemActions.go_back_from_inventory_action}
}, GAME_STATE_INVENTORY_ACTION) }, WINDOW_INVENTORY_ACTION)
end end
if Input.menu_back() then if Input.menu_back() then
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
end end
@@ -386,7 +386,7 @@ function MenuActions.play()
Context.player.vy = 0 Context.player.vy = 0
Context.player.jumps = 0 Context.player.jumps = 0
Context.current_screen = 1 Context.current_screen = 1
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
function MenuActions.exit() function MenuActions.exit()
@@ -405,15 +405,15 @@ Context.menu_items = {
function NpcActions.talk_to() function NpcActions.talk_to()
local npc = Context.dialog.active_entity local npc = Context.dialog.active_entity
if npc.dialog and npc.dialog.start then if npc.dialog and npc.dialog.start then
PopupState.set_dialog_node("start") PopupWindow.set_dialog_node("start")
else else
-- if no dialog, go back -- if no dialog, go back
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
end end
function NpcActions.fight() end function NpcActions.fight() end
function NpcActions.go_back() function NpcActions.go_back()
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -421,10 +421,10 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function ItemActions.use() function ItemActions.use()
print("Used item: " .. Context.dialog.active_entity.name) print("Used item: " .. Context.dialog.active_entity.name)
GameState.set_state(GAME_STATE_INVENTORY) GameWindow.set_state(WINDOW_INVENTORY)
end end
function ItemActions.look_at() function ItemActions.look_at()
PopupState.show_description_dialog(Context.dialog.active_entity, Context.dialog.active_entity.desc) PopupWindow.show_description_dialog(Context.dialog.active_entity, Context.dialog.active_entity.desc)
end end
function ItemActions.put_away() function ItemActions.put_away()
-- Add item to inventory -- Add item to inventory
@@ -440,14 +440,14 @@ function ItemActions.put_away()
end end
-- Go back to game -- Go back to game
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
function ItemActions.go_back_from_item_dialog() function ItemActions.go_back_from_item_dialog()
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
function ItemActions.go_back_from_inventory_action() function ItemActions.go_back_from_inventory_action()
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
function ItemActions.drop() function ItemActions.drop()
@@ -466,7 +466,7 @@ function ItemActions.drop()
table.insert(currentScreenData.items, Context.dialog.active_entity) table.insert(currentScreenData.items, Context.dialog.active_entity)
-- Go back to inventory -- Go back to inventory
GameState.set_state(GAME_STATE_INVENTORY) GameWindow.set_state(WINDOW_INVENTORY)
end end
@@ -491,10 +491,10 @@ function UI.draw_top_bar(title)
end end
function UI.draw_dialog() function UI.draw_dialog()
PopupState.draw() PopupWindow.draw()
end end
function PopupState.draw() function PopupWindow.draw()
rect(40, 40, 160, 80, Config.colors.black) rect(40, 40, 160, 80, Config.colors.black)
rectb(40, 40, 160, 80, Config.colors.green) rectb(40, 40, 160, 80, Config.colors.green)
@@ -593,27 +593,27 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Splash Module -- Splash Module
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function SplashState.draw() function SplashWindow.draw()
print("Mr. Anderson's", 78, 60, Config.colors.green) print("Mr. Anderson's", 78, 60, Config.colors.green)
print("Addventure", 90, 70, Config.colors.green) print("Addventure", 90, 70, Config.colors.green)
end end
function SplashState.update() function SplashWindow.update()
Context.splash_timer = Context.splash_timer - 1 Context.splash_timer = Context.splash_timer - 1
if Context.splash_timer <= 0 or Input.menu_confirm() then if Context.splash_timer <= 0 or Input.menu_confirm() then
GameState.set_state(GAME_STATE_INTRO) GameWindow.set_state(WINDOW_INTRO)
end end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Intro Module -- Intro Module
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function IntroState.draw() function IntroWindow.draw()
local x = (Config.screen.width - 132) / 2 -- Centered text local x = (Config.screen.width - 132) / 2 -- Centered text
print(Context.intro.text, x, Context.intro.y, Config.colors.green) print(Context.intro.text, x, Context.intro.y, Config.colors.green)
end end
function IntroState.update() function IntroWindow.update()
Context.intro.y = Context.intro.y - Context.intro.speed Context.intro.y = Context.intro.y - Context.intro.speed
-- Count lines in intro text to determine when scrolling is done -- Count lines in intro text to determine when scrolling is done
@@ -624,24 +624,24 @@ function IntroState.update()
-- When text is off-screen, go to menu -- When text is off-screen, go to menu
if Context.intro.y < -lines * 8 then if Context.intro.y < -lines * 8 then
GameState.set_state(GAME_STATE_MENU) GameWindow.set_state(WINDOW_MENU)
end end
-- Skip intro by pressing A -- Skip intro by pressing A
if Input.menu_confirm() then if Input.menu_confirm() then
GameState.set_state(GAME_STATE_MENU) GameWindow.set_state(WINDOW_MENU)
end end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Menu Module -- Menu Module
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function MenuState.draw() function MenuWindow.draw()
UI.draw_top_bar("Main Menu") UI.draw_top_bar("Main Menu")
UI.draw_menu(Context.menu_items, Context.selected_menu_item, 108, 70) UI.draw_menu(Context.menu_items, Context.selected_menu_item, 108, 70)
end end
function MenuState.update() function MenuWindow.update()
Context.selected_menu_item = UI.update_menu(Context.menu_items, Context.selected_menu_item) Context.selected_menu_item = UI.update_menu(Context.menu_items, Context.selected_menu_item)
if Input.menu_confirm() then if Input.menu_confirm() then
@@ -655,7 +655,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Game Module -- Game Module
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function GameState.draw() function GameWindow.draw()
local currentScreenData = Context.screens[Context.current_screen] local currentScreenData = Context.screens[Context.current_screen]
UI.draw_top_bar(currentScreenData.name) UI.draw_top_bar(currentScreenData.name)
@@ -748,11 +748,11 @@ function Player.update()
-- NPC interaction -- NPC interaction
for _, npc in ipairs(currentScreenData.npcs) do for _, npc in ipairs(currentScreenData.npcs) do
if math.abs(Context.player.x - npc.x) < Config.physics.interaction_radius_npc and math.abs(Context.player.y - npc.y) < Config.physics.interaction_radius_npc then if math.abs(Context.player.x - npc.x) < Config.physics.interaction_radius_npc and math.abs(Context.player.y - npc.y) < Config.physics.interaction_radius_npc then
PopupState.show_menu_dialog(npc, { PopupWindow.show_menu_dialog(npc, {
{label = "Talk to", action = NpcActions.talk_to}, {label = "Talk to", action = NpcActions.talk_to},
{label = "Fight", action = NpcActions.fight}, {label = "Fight", action = NpcActions.fight},
{label = "Go back", action = NpcActions.go_back} {label = "Go back", action = NpcActions.go_back}
}, GAME_STATE_POPUP) }, WINDOW_POPUP)
interaction_found = true interaction_found = true
break break
end end
@@ -762,12 +762,12 @@ function Player.update()
-- Item interaction -- Item interaction
for _, item in ipairs(currentScreenData.items) do for _, item in ipairs(currentScreenData.items) do
if math.abs(Context.player.x - item.x) < Config.physics.interaction_radius_item and math.abs(Context.player.y - item.y) < Config.physics.interaction_radius_item then if math.abs(Context.player.x - item.x) < Config.physics.interaction_radius_item and math.abs(Context.player.y - item.y) < Config.physics.interaction_radius_item then
PopupState.show_menu_dialog(item, { PopupWindow.show_menu_dialog(item, {
{label = "Use", action = ItemActions.use}, {label = "Use", action = ItemActions.use},
{label = "Look at", action = ItemActions.look_at}, {label = "Look at", action = ItemActions.look_at},
{label = "Put away", action = ItemActions.put_away}, {label = "Put away", action = ItemActions.put_away},
{label = "Go back", action = ItemActions.go_back_from_item_dialog} {label = "Go back", action = ItemActions.go_back_from_item_dialog}
}, GAME_STATE_POPUP) }, WINDOW_POPUP)
interaction_found = true interaction_found = true
break break
end end
@@ -776,30 +776,30 @@ function Player.update()
-- If no interaction happened, open inventory -- If no interaction happened, open inventory
if not interaction_found then if not interaction_found then
GameState.set_state(GAME_STATE_INVENTORY) GameWindow.set_state(WINDOW_INVENTORY)
end end
end end
end end
function GameState.update() function GameWindow.update()
Player.update() -- Call the encapsulated player update logic Player.update() -- Call the encapsulated player update logic
end end
function GameState.set_state(new_state) function GameWindow.set_state(new_state)
Context.game_state = new_state Context.active_window = new_state
-- Add any state-specific initialization/cleanup here later if needed -- Add any state-specific initialization/cleanup here later if needed
end end
function PopupState.set_dialog_node(node_key) function PopupWindow.set_dialog_node(node_key)
local npc = Context.dialog.active_entity local npc = Context.dialog.active_entity
local node = npc.dialog[node_key] local node = npc.dialog[node_key]
if not node then if not node then
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
return return
end end
@@ -812,7 +812,7 @@ function PopupState.set_dialog_node(node_key)
table.insert(menu_items, { table.insert(menu_items, {
label = option.label, label = option.label,
action = function() action = function()
PopupState.set_dialog_node(option.next_node) PopupWindow.set_dialog_node(option.next_node)
end end
}) })
end end
@@ -822,22 +822,22 @@ function PopupState.set_dialog_node(node_key)
if #menu_items == 0 then if #menu_items == 0 then
table.insert(menu_items, { table.insert(menu_items, {
label = "Go back", label = "Go back",
action = function() GameState.set_state(GAME_STATE_GAME) end action = function() GameWindow.set_state(WINDOW_GAME) end
}) })
end end
Context.dialog.menu_items = menu_items Context.dialog.menu_items = menu_items
Context.dialog.selected_menu_item = 1 Context.dialog.selected_menu_item = 1
Context.dialog.showing_description = false Context.dialog.showing_description = false
GameState.set_state(GAME_STATE_POPUP) GameWindow.set_state(WINDOW_POPUP)
end end
function PopupState.update() function PopupWindow.update()
if Context.dialog.showing_description then if Context.dialog.showing_description then
if Input.menu_confirm() or Input.menu_back() then if Input.menu_confirm() or Input.menu_back() then
Context.dialog.showing_description = false Context.dialog.showing_description = false
Context.dialog.text = "" -- Clear the description text Context.dialog.text = "" -- Clear the description text
-- No need to change game_state, as it remains in GAME_STATE_POPUP or GAME_STATE_INVENTORY_ACTION -- No need to change active_window, as it remains in WINDOW_POPUP or WINDOW_INVENTORY_ACTION
end end
else else
Context.dialog.selected_menu_item = UI.update_menu(Context.dialog.menu_items, Context.dialog.selected_menu_item) Context.dialog.selected_menu_item = UI.update_menu(Context.dialog.menu_items, Context.dialog.selected_menu_item)
@@ -850,24 +850,24 @@ function PopupState.update()
end end
if Input.menu_back() then if Input.menu_back() then
GameState.set_state(GAME_STATE_GAME) GameWindow.set_state(WINDOW_GAME)
end end
end end
end end
function PopupState.show_menu_dialog(entity, menu_items, dialog_game_state) function PopupWindow.show_menu_dialog(entity, menu_items, dialog_active_window)
Context.dialog.active_entity = entity Context.dialog.active_entity = entity
Context.dialog.text = "" -- Initial dialog text is empty, name is title Context.dialog.text = "" -- Initial dialog text is empty, name is title
GameState.set_state(dialog_game_state or GAME_STATE_POPUP) GameWindow.set_state(dialog_active_window or WINDOW_POPUP)
Context.dialog.showing_description = false Context.dialog.showing_description = false
Context.dialog.menu_items = menu_items Context.dialog.menu_items = menu_items
Context.dialog.selected_menu_item = 1 Context.dialog.selected_menu_item = 1
end end
function PopupState.show_description_dialog(entity, description_text) function PopupWindow.show_description_dialog(entity, description_text)
Context.dialog.active_entity = entity Context.dialog.active_entity = entity
Context.dialog.text = description_text Context.dialog.text = description_text
GameState.set_state(GAME_STATE_POPUP) GameWindow.set_state(WINDOW_POPUP)
Context.dialog.showing_description = true Context.dialog.showing_description = true
-- No menu items needed for description dialog -- No menu items needed for description dialog
end end
@@ -876,41 +876,41 @@ end
-- Main Game Loop -- Main Game Loop
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local STATE_HANDLERS = { local STATE_HANDLERS = {
[GAME_STATE_SPLASH] = function() [WINDOW_SPLASH] = function()
SplashState.update() SplashWindow.update()
SplashState.draw() SplashWindow.draw()
end, end,
[GAME_STATE_INTRO] = function() [WINDOW_INTRO] = function()
IntroState.update() IntroWindow.update()
IntroState.draw() IntroWindow.draw()
end, end,
[GAME_STATE_MENU] = function() [WINDOW_MENU] = function()
MenuState.update() MenuWindow.update()
MenuState.draw() MenuWindow.draw()
end, end,
[GAME_STATE_GAME] = function() [WINDOW_GAME] = function()
GameState.update() GameWindow.update()
GameState.draw() GameWindow.draw()
end, end,
[GAME_STATE_POPUP] = function() [WINDOW_POPUP] = function()
GameState.draw() -- Draw game behind dialog GameWindow.draw() -- Draw game behind dialog
PopupState.draw() PopupWindow.draw()
PopupState.update() PopupWindow.update()
end, end,
[GAME_STATE_INVENTORY] = function() [WINDOW_INVENTORY] = function()
InventoryState.update() InventoryWindow.update()
InventoryState.draw() InventoryWindow.draw()
end, end,
[GAME_STATE_INVENTORY_ACTION] = function() [WINDOW_INVENTORY_ACTION] = function()
InventoryState.draw() -- Draw inventory behind dialog InventoryWindow.draw() -- Draw inventory behind dialog
PopupState.draw() PopupWindow.draw()
PopupState.update() PopupWindow.update()
end, end,
} }
function TIC() function TIC()
cls(Config.colors.black) cls(Config.colors.black)
local handler = STATE_HANDLERS[Context.game_state] local handler = STATE_HANDLERS[Context.active_window]
if handler then if handler then
handler() handler()
end end