From 3e3d33296752ea2eeccd3e8368ca2bc39d9419f2 Mon Sep 17 00:00:00 2001 From: yuki Date: Mon, 10 Nov 2025 01:02:09 -0300 Subject: [PATCH] exercise 44 --- def/Object.d.lua | 2 +- def/Timer.d.lua | 2 +- main.lua | 50 ++++++++++++++++++++++++++++++----------- obj/Circle.lua | 21 +++++++++++++++++ obj/Polygon.lua | 17 ++++++++++++++ obj/Rectangle.lua | 23 +++++++++++++++++++ rooms/CircleRoom.lua | 29 ++++++++++++++++++++++++ rooms/PolygonRoom.lua | 27 ++++++++++++++++++++++ rooms/RectangleRoom.lua | 27 ++++++++++++++++++++++ 9 files changed, 183 insertions(+), 15 deletions(-) create mode 100644 obj/Circle.lua create mode 100644 obj/Polygon.lua create mode 100644 obj/Rectangle.lua create mode 100644 rooms/CircleRoom.lua create mode 100644 rooms/PolygonRoom.lua create mode 100644 rooms/RectangleRoom.lua diff --git a/def/Object.d.lua b/def/Object.d.lua index 881f492..17ee45a 100644 --- a/def/Object.d.lua +++ b/def/Object.d.lua @@ -1,8 +1,8 @@ ----@diagnostic disable: undefined-field ---@meta ---@module 'classic' ---@class Object +---@field super Object|nil # Parent class methods (for inheritance) local Object = {} ---Create a new instance of the class. diff --git a/def/Timer.d.lua b/def/Timer.d.lua index 2b693a8..b50b8c5 100644 --- a/def/Timer.d.lua +++ b/def/Timer.d.lua @@ -30,7 +30,7 @@ function Timer:every(interval, func, ...) end ---@param duration number ---@param subject table ---@param target table ----@param easing? function +---@param easing? string ---@param after? function ---@return function cancel_function function Timer:tween(duration, subject, target, easing, after) end diff --git a/main.lua b/main.lua index bc4a35e..13a5ec2 100644 --- a/main.lua +++ b/main.lua @@ -1,7 +1,8 @@ --- debug +-- debug -- if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then + DEBUG = true require("lldebugger").start() -end +else DEBUG = false end -- libraries -- ---@type Object @@ -13,6 +14,9 @@ Timer = require 'lib/hump/timer' -- objects -- Room = require 'obj/Room' +Circle = require 'obj/Circle' +Rectangle = require 'obj/Rectangle' +Polygon = require 'obj/Polygon' function love.load() ---@type Room|nil @@ -20,8 +24,10 @@ function love.load() -- load rooms local room_files = {} + print('loading rooms:') recursiveEnumerate('rooms', room_files) - requireFiles(room_files) + for _,v in ipairs(room_files) do print('',v) end + requireFiles(room_files, true) -- load input input = Baton.new { @@ -30,7 +36,8 @@ function love.load() right = {'key:right', 'key:d'}, up = {'key:up', 'key:w'}, down = {'key:down', 'key:s'}, - action = {'key:z', 'key:space'} + action = {'key:z', 'key:space'}, + f1 = {'key:f1'}, f2 = {'key:f2'}, f3 = {'key:f3'} }, pairs = { move = {'left', 'right', 'up', 'down'} @@ -41,6 +48,9 @@ end function love.update(dt) input:update(dt) if current_room then current_room:update(dt) end + if input:pressed('f1') then gotoRoom('CircleRoom') end + if input:pressed('f2') then gotoRoom('RectangleRoom') end + if input:pressed('f3') then gotoRoom('PolygonRoom') end end function love.draw() @@ -54,22 +64,29 @@ function recursiveEnumerate(folder, file_list) local items = love.filesystem.getDirectoryItems(folder) for _, item in ipairs(items) do local file = folder .. '/' .. item ----@diagnostic disable-next-line: undefined-field - if love.filesystem.isFile(file) then - table.insert(file_list, file) ----@diagnostic disable-next-line: undefined-field - elseif love.filesystem.isDirectory(file) then - recursiveEnumerate(file, file_list) + local info = love.filesystem.getInfo(file) + + if info then -- exists (covers both files and directories) + if info.type == "file" then + table.insert(file_list, file) + elseif info.type == "directory" then + recursiveEnumerate(file, file_list) + end end end end ---Load files table as lua modules. ---@param files table table containing files to be loaded -function requireFiles(files) +---@param should_return boolean|nil whether required files return a table/object +function requireFiles(files, should_return) + local returns = should_return or false for _, file in ipairs(files) do - local file = file:sub(1, -5) - require(file) + local module = file:sub(1, -5) + if not returns then require(module) else + local filename = module:match("([^/]+)$") + _G[filename] = require(module) + end end end @@ -77,5 +94,12 @@ end ---@param room_type string the name of the room as registered ---@param ... any arguments passed to the room constructor function gotoRoom(room_type, ...) + local Class = _G[room_type] + if not Class then + error("room '"..room_type.."' not found in _G") + end + if type(Class) ~= "table" and type(Class) ~= "function" then + error("room '"..room_type.."' is not callable (got "..type(Class)..", does room return itself?)") + end current_room = _G[room_type](...) end diff --git a/obj/Circle.lua b/obj/Circle.lua new file mode 100644 index 0000000..dc8c91a --- /dev/null +++ b/obj/Circle.lua @@ -0,0 +1,21 @@ +---@class Circle:Object circle object +---@field x number horizontal position of circle +---@field y number vertical position of circle +---@field radius number radius of circle +---@field mode string drawing mode of circle +local Circle = Object:extend() + +function Circle:new(config) + self.x = config.x or 400 + self.y = config.y or 300 + self.radius = config.radius or 50 + self.mode = config.mode or "fill" +end + +function Circle:update(dt) end + +function Circle:draw() + love.graphics.circle(self.mode, self.x, self.y, self.radius) +end + +return Circle diff --git a/obj/Polygon.lua b/obj/Polygon.lua new file mode 100644 index 0000000..cd748ce --- /dev/null +++ b/obj/Polygon.lua @@ -0,0 +1,17 @@ +---@class Polygon:Object Polygon object +---@field mode string drawing mode of Polygon +---@field points any points of Polygon +local Polygon = Object:extend() + +function Polygon:new(mode, ...) + self.mode = mode or "fill" + self.points = {...} or {100,100, 200,100, 150,200} +end + +function Polygon:update(dt) end + +function Polygon:draw() + love.graphics.polygon(self.mode, self.points) +end + +return Polygon diff --git a/obj/Rectangle.lua b/obj/Rectangle.lua new file mode 100644 index 0000000..85b81b6 --- /dev/null +++ b/obj/Rectangle.lua @@ -0,0 +1,23 @@ +---@class Rectangle:Object Rectangle object +---@field x number horizontal position of Rectangle +---@field y number vertical position of Rectangle +---@field mode string drawing mode of Rectangle +---@field width number width of Rectangle +---@field height number height of Rectangle +local Rectangle = Object:extend() + +function Rectangle:new(config) + self.x = config.x or 400 + self.y = config.y or 300 + self.mode = config.mode or "fill" + self.width = config.width or 100 + self.height = config.height or 60 +end + +function Rectangle:update(dt) end + +function Rectangle:draw() + love.graphics.rectangle(self.mode, self.x, self.y, self.width, self.height) +end + +return Rectangle diff --git a/rooms/CircleRoom.lua b/rooms/CircleRoom.lua new file mode 100644 index 0000000..352f5c6 --- /dev/null +++ b/rooms/CircleRoom.lua @@ -0,0 +1,29 @@ +---@class CircleRoom:Room +---@field circle Circle +---@field super Room +---@field radtween number +---@field timer Timer +local CircleRoom = Room:extend() + +function CircleRoom:new() + CircleRoom.super.new(self) + self.radtween = 50 + self.circle = Circle{radius = self.radtween} + self.timer = Timer() +end + +function CircleRoom:update(dt) + CircleRoom.super.update(self, dt) + if input:pressed('action') then + self.timer:tween(1, self.circle, {radius = 100}, 'in-out-cubic') + end + self.circle:update(dt) + self.timer:update(dt) +end + +function CircleRoom:draw() + CircleRoom.super.draw(self) + self.circle:draw() +end + +return CircleRoom diff --git a/rooms/PolygonRoom.lua b/rooms/PolygonRoom.lua new file mode 100644 index 0000000..1b7f6d1 --- /dev/null +++ b/rooms/PolygonRoom.lua @@ -0,0 +1,27 @@ +---@class PolygonRoom:Room +---@field polygon Polygon +---@field super Room +---@field timer Timer +local PolygonRoom = Room:extend() + +function PolygonRoom:new() + PolygonRoom.super.new(self) + self.polygon = Polygon('fill', 100,100, 200,100, 150,200) + self.timer = Timer() +end + +function PolygonRoom:update(dt) + PolygonRoom.super.update(self, dt) + if input:pressed('action') then + self.polygon.mode = 'line' + end + self.polygon:update(dt) + self.timer:update(dt) +end + +function PolygonRoom:draw() + PolygonRoom.super.draw(self) + self.polygon:draw() +end + +return PolygonRoom diff --git a/rooms/RectangleRoom.lua b/rooms/RectangleRoom.lua new file mode 100644 index 0000000..215288c --- /dev/null +++ b/rooms/RectangleRoom.lua @@ -0,0 +1,27 @@ +---@class RectangleRoom:Room +---@field rectangle Rectangle +---@field super Room +---@field timer Timer +local RectangleRoom = Room:extend() + +function RectangleRoom:new() + RectangleRoom.super.new(self) + self.rectangle = Rectangle{} + self.timer = Timer() +end + +function RectangleRoom:update(dt) + RectangleRoom.super.update(self, dt) + if input:pressed('action') then + self.timer:tween(1, self.rectangle, {width = 50}, 'in-out-cubic') + end + self.rectangle:update(dt) + self.timer:update(dt) +end + +function RectangleRoom:draw() + RectangleRoom.super.draw(self) + self.rectangle:draw() +end + +return RectangleRoom