diff --git a/Makefile b/Makefile index 04e6907..edacc7a 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,6 @@ $(OUTPUT): $(SRC) $(ORDER) @echo "==> Building $(OUTPUT)..." @rm -f $(OUTPUT) @while read f; do \ - echo "-- FILE: $$f" >> $(OUTPUT); \ cat "$(SRC_DIR)/$$f" >> $(OUTPUT); \ echo "\n" >> $(OUTPUT); \ done < $(ORDER) diff --git a/inc/actions.menu.lua b/inc/actions.menu.lua deleted file mode 100644 index fcf2142..0000000 --- a/inc/actions.menu.lua +++ /dev/null @@ -1,23 +0,0 @@ --------------------------------------------------------------------------------- --- Menu Actions --------------------------------------------------------------------------------- -function MenuActions.play() - -- Reset player state and screen for a new game - Context.player.x = Config.player.start_x - Context.player.y = Config.player.start_y - Context.player.vx = 0 - Context.player.vy = 0 - Context.player.jumps = 0 - Context.current_screen = 1 - GameWindow.set_state(WINDOW_GAME) -end - -function MenuActions.exit() - exit() -end - --- Initialize menu items after actions are defined -Context.menu_items = { - {label = "Play", action = MenuActions.play}, - {label = "Exit", action = MenuActions.exit} -} diff --git a/inc/actions.npc.lua b/inc/actions.npc.lua deleted file mode 100644 index 4d7b829..0000000 --- a/inc/actions.npc.lua +++ /dev/null @@ -1,16 +0,0 @@ --------------------------------------------------------------------------------- --- NPC Actions --------------------------------------------------------------------------------- -function NpcActions.talk_to() - local npc = Context.dialog.active_entity - if npc.dialog and npc.dialog.start then - PopupWindow.set_dialog_node("start") - else - -- if no dialog, go back - GameWindow.set_state(WINDOW_GAME) - end -end -function NpcActions.fight() end -function NpcActions.go_back() - GameWindow.set_state(WINDOW_GAME) -end diff --git a/inc/actions.inventory.lua b/inc/entity.item.lua similarity index 75% rename from inc/actions.inventory.lua rename to inc/entity.item.lua index d9b8075..d6f0a33 100644 --- a/inc/actions.inventory.lua +++ b/inc/entity.item.lua @@ -1,14 +1,11 @@ --------------------------------------------------------------------------------- --- Item Actions --------------------------------------------------------------------------------- -function ItemActions.use() +function Item.use() print("Used item: " .. Context.dialog.active_entity.name) GameWindow.set_state(WINDOW_INVENTORY) end -function ItemActions.look_at() +function Item.look_at() PopupWindow.show_description_dialog(Context.dialog.active_entity, Context.dialog.active_entity.desc) end -function ItemActions.put_away() +function Item.put_away() -- Add item to inventory table.insert(Context.inventory, Context.dialog.active_entity) @@ -24,15 +21,15 @@ function ItemActions.put_away() -- Go back to game GameWindow.set_state(WINDOW_GAME) end -function ItemActions.go_back_from_item_dialog() +function Item.go_back_from_item_dialog() GameWindow.set_state(WINDOW_GAME) end -function ItemActions.go_back_from_inventory_action() +function Item.go_back_from_inventory_action() GameWindow.set_state(WINDOW_GAME) end -function ItemActions.drop() +function Item.drop() -- Remove item from inventory for i, item in ipairs(Context.inventory) do if item == Context.dialog.active_entity then diff --git a/inc/entity.npc.lua b/inc/entity.npc.lua new file mode 100644 index 0000000..c4a90e2 --- /dev/null +++ b/inc/entity.npc.lua @@ -0,0 +1,13 @@ +function NPC.talk_to() + local npc = Context.dialog.active_entity + if npc.dialog and npc.dialog.start then + PopupWindow.set_dialog_node("start") + else + -- if no dialog, go back + GameWindow.set_state(WINDOW_GAME) + end +end +function NPC.fight() end +function NPC.go_back() + GameWindow.set_state(WINDOW_GAME) +end diff --git a/inc/entity.player.lua b/inc/entity.player.lua index bd93c59..e9df37d 100644 --- a/inc/entity.player.lua +++ b/inc/entity.player.lua @@ -65,9 +65,9 @@ function Player.update() 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 PopupWindow.show_menu_dialog(npc, { - {label = "Talk to", action = NpcActions.talk_to}, - {label = "Fight", action = NpcActions.fight}, - {label = "Go back", action = NpcActions.go_back} + {label = "Talk to", action = NPC.talk_to}, + {label = "Fight", action = NPC.fight}, + {label = "Go back", action = NPC.go_back} }, WINDOW_POPUP) interaction_found = true break @@ -79,10 +79,10 @@ function Player.update() 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 PopupWindow.show_menu_dialog(item, { - {label = "Use", action = ItemActions.use}, - {label = "Look at", action = ItemActions.look_at}, - {label = "Put away", action = ItemActions.put_away}, - {label = "Go back", action = ItemActions.go_back_from_item_dialog} + {label = "Use", action = Item.use}, + {label = "Look at", action = Item.look_at}, + {label = "Put away", action = Item.put_away}, + {label = "Go back", action = Item.go_back_from_item_dialog} }, WINDOW_POPUP) interaction_found = true break diff --git a/inc/init.config.lua b/inc/init.config.lua index af74633..e8dbebc 100644 --- a/inc/init.config.lua +++ b/inc/init.config.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Game Configuration --------------------------------------------------------------------------------- local Config = { screen = { width = 240, @@ -26,10 +23,10 @@ local Config = { jump_power = -5, move_speed = 1.5, max_jumps = 2, - interaction_radius_npc = 12, -- New constant - interaction_radius_item = 8 -- New constant + interaction_radius_npc = 12, + interaction_radius_item = 8 }, timing = { - splash_duration = 120 -- 2 seconds at 60fps + splash_duration = 120 } } diff --git a/inc/init.context.lua b/inc/init.context.lua index 2a2cd45..1b71c2a 100644 --- a/inc/init.context.lua +++ b/inc/init.context.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Game Window --------------------------------------------------------------------------------- local Context = { active_window = WINDOW_SPLASH, inventory = {}, diff --git a/inc/init.modules.lua b/inc/init.modules.lua index 3ebc5ee..d9b4f56 100644 --- a/inc/init.modules.lua +++ b/inc/init.modules.lua @@ -1,18 +1,12 @@ --------------------------------------------------------------------------------- --- Modules --------------------------------------------------------------------------------- --- Window Modules (in WINDOW order) local SplashWindow = {} local IntroWindow = {} local MenuWindow = {} local GameWindow = {} -local PopupWindow = {} -- Manages popups for WINDOW_POPUP and WINDOW_INVENTORY_ACTION -local InventoryWindow = {} -- Used for WINDOW_INVENTORY +local PopupWindow = {} +local InventoryWindow = {} --- Other Modules local UI = {} local Input = {} -local NpcActions = {} -local ItemActions = {} -local MenuActions = {} +local NPC = {} +local Item = {} local Player = {} diff --git a/inc/init.windows.lua b/inc/init.windows.lua index 137df0e..a4e71f0 100644 --- a/inc/init.windows.lua +++ b/inc/init.windows.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Game Windows --------------------------------------------------------------------------------- local WINDOW_SPLASH = 0 local WINDOW_INTRO = 1 local WINDOW_MENU = 2 diff --git a/inc/system.input.lua b/inc/system.input.lua index d567081..2d6b403 100644 --- a/inc/system.input.lua +++ b/inc/system.input.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Input Module --------------------------------------------------------------------------------- function Input.up() return btnp(0) end function Input.down() return btnp(1) end function Input.left() return btn(2) end diff --git a/inc/system.main.lua b/inc/system.main.lua index 15b19f7..306bd8b 100644 --- a/inc/system.main.lua +++ b/inc/system.main.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Main Game Loop --------------------------------------------------------------------------------- local STATE_HANDLERS = { [WINDOW_SPLASH] = function() SplashWindow.update() @@ -19,7 +16,7 @@ local STATE_HANDLERS = { GameWindow.draw() end, [WINDOW_POPUP] = function() - GameWindow.draw() -- Draw game behind dialog + GameWindow.draw() PopupWindow.update() PopupWindow.draw() end, @@ -28,7 +25,7 @@ local STATE_HANDLERS = { InventoryWindow.draw() end, [WINDOW_INVENTORY_ACTION] = function() - InventoryWindow.draw() -- Draw inventory behind dialog + InventoryWindow.draw() PopupWindow.draw() PopupWindow.update() end, diff --git a/inc/system.ui.lua b/inc/system.ui.lua index 102eb06..c1a6c9e 100644 --- a/inc/system.ui.lua +++ b/inc/system.ui.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- UI Module --------------------------------------------------------------------------------- function UI.draw_top_bar(title) rect(0, 0, Config.screen.width, 10, Config.colors.dark_grey) print(title, 3, 2, Config.colors.green) @@ -10,35 +7,6 @@ function UI.draw_dialog() PopupWindow.draw() end -function PopupWindow.draw() - rect(40, 40, 160, 80, Config.colors.black) - rectb(40, 40, 160, 80, Config.colors.green) - - -- Display the entity's name as the dialog title - if Context.dialog.active_entity and Context.dialog.active_entity.name then - print(Context.dialog.active_entity.name, 120 - #Context.dialog.active_entity.name * 2, 45, Config.colors.green) - end - - -- Display the dialog content (description for "look at", or initial name/dialog for others) - local wrapped_lines = UI.word_wrap(Context.dialog.text, 25) -- Max 25 chars per line - local current_y = 55 -- Starting Y position for the first line of content - for _, line in ipairs(wrapped_lines) do - print(line, 50, current_y, Config.colors.light_grey) - current_y = current_y + 8 -- Move to the next line (8 pixels for default font height + padding) - end - - -- Adjust menu position based on the number of wrapped lines - if not Context.dialog.showing_description then - UI.draw_menu(Context.dialog.menu_items, Context.dialog.selected_menu_item, 50, current_y + 2) - else - -- If description is showing, provide a "Go back" option automatically, or close dialog on action - -- For now, let's just make it implicitly wait for Input.menu_confirm() or Input.menu_back() to close - -- Or we can add a specific "Back" option here. - -- Let's add a "Back" option for explicit return from description. - print("[A] Go Back", 50, current_y + 10, Config.colors.green) - end -end - function UI.draw_menu(items, selected_item, x, y) for i, item in ipairs(items) do local current_y = y + (i-1)*10 diff --git a/inc/window.game.lua b/inc/window.game.lua index 8a06897..651bd05 100644 --- a/inc/window.game.lua +++ b/inc/window.game.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Game Module --------------------------------------------------------------------------------- function GameWindow.draw() local currentScreenData = Context.screens[Context.current_screen] @@ -28,105 +25,6 @@ function GameWindow.draw() Player.draw() end -function Player.draw() - spr(Context.player.sprite_id, Context.player.x, Context.player.y, 0) -end - -function Player.update() - -- Handle input - if Input.left() then - Context.player.vx = -Config.physics.move_speed - elseif Input.right() then - Context.player.vx = Config.physics.move_speed - else - Context.player.vx = 0 - end - - if Input.player_jump() and Context.player.jumps < Config.physics.max_jumps then - Context.player.vy = Config.physics.jump_power - Context.player.jumps = Context.player.jumps + 1 - end - - -- Update player position - Context.player.x = Context.player.x + Context.player.vx - Context.player.y = Context.player.y + Context.player.vy - - -- Screen transition - if Context.player.x > Config.screen.width - Context.player.w then - if Context.current_screen < #Context.screens then - Context.current_screen = Context.current_screen + 1 - Context.player.x = 0 - else - Context.player.x = Config.screen.width - Context.player.w - end - elseif Context.player.x < 0 then - if Context.current_screen > 1 then - Context.current_screen = Context.current_screen - 1 - Context.player.x = Config.screen.width - Context.player.w - else - Context.player.x = 0 - end - end - - -- Apply gravity - Context.player.vy = Context.player.vy + Config.physics.gravity - - local currentScreenData = Context.screens[Context.current_screen] - -- Collision detection with platforms - for _, p in ipairs(currentScreenData.platforms) do - if Context.player.vy > 0 and Context.player.y + Context.player.h >= p.y and Context.player.y + Context.player.h <= p.y + p.h and Context.player.x + Context.player.w > p.x and Context.player.x < p.x + p.w then - Context.player.y = p.y - Context.player.h - Context.player.vy = 0 - Context.player.jumps = 0 - end - end - - -- Collision detection with ground - if Context.player.y + Context.player.h > Context.ground.y then - Context.player.y = Context.ground.y - Context.player.h - Context.player.vy = 0 - Context.player.jumps = 0 - end - - -- Entity interaction - if Input.player_interact() then - local interaction_found = false - -- NPC interaction - 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 - PopupWindow.show_menu_dialog(npc, { - {label = "Talk to", action = NpcActions.talk_to}, - {label = "Fight", action = NpcActions.fight}, - {label = "Go back", action = NpcActions.go_back} - }, WINDOW_POPUP) - interaction_found = true - break - end - end - - if not interaction_found then - -- Item interaction - 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 - PopupWindow.show_menu_dialog(item, { - {label = "Use", action = ItemActions.use}, - {label = "Look at", action = ItemActions.look_at}, - {label = "Put away", action = ItemActions.put_away}, - {label = "Go back", action = ItemActions.go_back_from_item_dialog} - }, WINDOW_POPUP) - interaction_found = true - break - end - end - end - - -- If no interaction happened, open inventory - if not interaction_found then - GameWindow.set_state(WINDOW_INVENTORY) - end - end -end - function GameWindow.update() Player.update() -- Call the encapsulated player update logic end diff --git a/inc/window.intro.lua b/inc/window.intro.lua index 38d30ab..4cccc5e 100644 --- a/inc/window.intro.lua +++ b/inc/window.intro.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Intro Module --------------------------------------------------------------------------------- function IntroWindow.draw() local x = (Config.screen.width - 132) / 2 -- Centered text print(Context.intro.text, x, Context.intro.y, Config.colors.green) diff --git a/inc/window.inventory.lua b/inc/window.inventory.lua index 843be1f..154b820 100644 --- a/inc/window.inventory.lua +++ b/inc/window.inventory.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Inventory Module --------------------------------------------------------------------------------- function InventoryWindow.draw() UI.draw_top_bar("Inventory") @@ -24,10 +21,10 @@ function InventoryWindow.update() if Input.menu_confirm() and #Context.inventory > 0 then local selected_item = Context.inventory[Context.selected_inventory_item] PopupWindow.show_menu_dialog(selected_item, { - {label = "Use", action = ItemActions.use}, - {label = "Drop", action = ItemActions.drop}, - {label = "Look at", action = ItemActions.look_at}, - {label = "Go back", action = ItemActions.go_back_from_inventory_action} + {label = "Use", action = Item.use}, + {label = "Drop", action = Item.drop}, + {label = "Look at", action = Item.look_at}, + {label = "Go back", action = Item.go_back_from_inventory_action} }, WINDOW_INVENTORY_ACTION) end diff --git a/inc/window.menu.lua b/inc/window.menu.lua index 74ae850..31d5886 100644 --- a/inc/window.menu.lua +++ b/inc/window.menu.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Menu Module --------------------------------------------------------------------------------- function MenuWindow.draw() UI.draw_top_bar("Main Menu") UI.draw_menu(Context.menu_items, Context.selected_menu_item, 108, 70) @@ -16,3 +13,24 @@ function MenuWindow.update() end end end + +function MenuWindow.play() + -- Reset player state and screen for a new game + Context.player.x = Config.player.start_x + Context.player.y = Config.player.start_y + Context.player.vx = 0 + Context.player.vy = 0 + Context.player.jumps = 0 + Context.current_screen = 1 + GameWindow.set_state(WINDOW_GAME) +end + +function MenuWindow.exit() + exit() +end + +-- Initialize menu items after actions are defined +Context.menu_items = { + {label = "Play", action = MenuWindow.play}, + {label = "Exit", action = MenuWindow.exit} +} diff --git a/inc/window.popup.lua b/inc/window.popup.lua index 1f7cdcc..d60a66d 100644 --- a/inc/window.popup.lua +++ b/inc/window.popup.lua @@ -75,3 +75,28 @@ function PopupWindow.show_description_dialog(entity, description_text) Context.dialog.showing_description = true -- No menu items needed for description dialog end + +function PopupWindow.draw() + rect(40, 40, 160, 80, Config.colors.black) + rectb(40, 40, 160, 80, Config.colors.green) + + -- Display the entity's name as the dialog title + if Context.dialog.active_entity and Context.dialog.active_entity.name then + print(Context.dialog.active_entity.name, 120 - #Context.dialog.active_entity.name * 2, 45, Config.colors.green) + end + + -- Display the dialog content (description for "look at", or initial name/dialog for others) + local wrapped_lines = UI.word_wrap(Context.dialog.text, 25) -- Max 25 chars per line + local current_y = 55 -- Starting Y position for the first line of content + for _, line in ipairs(wrapped_lines) do + print(line, 50, current_y, Config.colors.light_grey) + current_y = current_y + 8 -- Move to the next line (8 pixels for default font height + padding) + end + + -- Adjust menu position based on the number of wrapped lines + if not Context.dialog.showing_description then + UI.draw_menu(Context.dialog.menu_items, Context.dialog.selected_menu_item, 50, current_y + 2) + else + print("[A] Go Back", 50, current_y + 10, Config.colors.green) + end +end diff --git a/inc/window.splash.lua b/inc/window.splash.lua index 4ea927a..cfff23f 100644 --- a/inc/window.splash.lua +++ b/inc/window.splash.lua @@ -1,6 +1,3 @@ --------------------------------------------------------------------------------- --- Splash Module --------------------------------------------------------------------------------- function SplashWindow.draw() print("Mr. Anderson's", 78, 60, Config.colors.green) print("Addventure", 90, 70, Config.colors.green) diff --git a/mranderson.inc b/mranderson.inc index bde3037..ef5cfd0 100644 --- a/mranderson.inc +++ b/mranderson.inc @@ -3,16 +3,16 @@ init.config.lua init.windows.lua init.modules.lua init.context.lua -window.inventory.lua -actions.menu.lua -actions.npc.lua -actions.inventory.lua +entity.npc.lua +entity.item.lua +entity.player.lua system.input.lua system.ui.lua window.splash.lua window.intro.lua window.menu.lua -window.game.lua window.popup.lua +window.inventory.lua +window.game.lua system.main.lua meta.assets.lua