Formatted files
This commit is contained in:
4
conf.lua
4
conf.lua
@@ -1,7 +1,7 @@
|
||||
function love.conf(t)
|
||||
-- t.identity = nil -- The name of the save directory (string)
|
||||
-- t.appendidentity = false -- Search files in source directory before save directory (boolean)
|
||||
t.version = "11.4" -- The LÖVE version this game was made for (string)
|
||||
t.version = '11.4' -- The LÖVE version this game was made for (string)
|
||||
t.console = true -- Attach a console (boolean, Windows only)
|
||||
-- t.accelerometerjoystick = true -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
|
||||
-- t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean)
|
||||
@@ -10,7 +10,7 @@ function love.conf(t)
|
||||
-- t.audio.mic = false -- Request and use microphone capabilities in Android (boolean)
|
||||
-- t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only)
|
||||
|
||||
t.window.title = "Maize Walker" -- The window title (string)
|
||||
t.window.title = 'Maize Walker' -- The window title (string)
|
||||
-- t.window.icon = 'assets/icon.png' -- Filepath to an image to use as the window's icon (string)
|
||||
-- t.window.width = 800 -- The window width (number)
|
||||
-- t.window.height = 600 -- The window height (number)
|
||||
|
||||
8
main.lua
8
main.lua
@@ -1,5 +1,5 @@
|
||||
local Display = require "src.display"
|
||||
local GameCore = require "src.core.game_core"
|
||||
local Display = require 'src.display'
|
||||
local GameCore = require 'src.core.game_core'
|
||||
|
||||
|
||||
local VIRTUAL_WIDTH, VIRTUAL_HEIGHT = 640, 360
|
||||
@@ -21,7 +21,7 @@ function love.update(dt)
|
||||
end
|
||||
|
||||
function love.draw()
|
||||
display:draw(function()
|
||||
display:draw(function ()
|
||||
core:draw()
|
||||
end)
|
||||
end
|
||||
@@ -33,5 +33,5 @@ end
|
||||
|
||||
function love.keypressed(key)
|
||||
if key == 'f11' then display:toggleFullscreen() end
|
||||
if key == "escape" then love.event.quit() end
|
||||
if key == 'escape' then love.event.quit() end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
--
|
||||
|
||||
-- Modified badr:isMouseInside to work with resolution_solution
|
||||
local rs = require "packages.resolution_solution"
|
||||
local rs = require 'packages.resolution_solution'
|
||||
|
||||
local badr = {}
|
||||
badr.__index = badr
|
||||
@@ -32,7 +32,7 @@ function badr:new(t)
|
||||
end
|
||||
|
||||
function badr.__add(self, component)
|
||||
if type(component) ~= "table" or component == nil then return end
|
||||
if type(component) ~= 'table' or component == nil then return end
|
||||
|
||||
component.parent = self
|
||||
component.x = self.x + component.x
|
||||
@@ -87,7 +87,7 @@ end
|
||||
|
||||
-- Returns child with specific id
|
||||
function badr.__mod(self, id)
|
||||
assert(type(id) == "string", 'Badar; Provided id must be a string.')
|
||||
assert(type(id) == 'string', 'Badar; Provided id must be a string.')
|
||||
for _, child in ipairs(self.children) do
|
||||
if child.id == id then
|
||||
return child
|
||||
@@ -136,7 +136,7 @@ function badr:update()
|
||||
end
|
||||
|
||||
return setmetatable({ new = badr.new }, {
|
||||
__call = function(t, ...)
|
||||
__call = function (t, ...)
|
||||
return badr:new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -31,7 +31,7 @@ local bump = {
|
||||
------------------------------------------
|
||||
-- Auxiliary functions
|
||||
------------------------------------------
|
||||
local DELTA = 1e-10 -- floating-point margin of error
|
||||
local DELTA = 1e-10 -- floating-point margin of error
|
||||
|
||||
local abs, floor, ceil, min, max = math.abs, math.floor, math.ceil, math.min, math.max
|
||||
|
||||
@@ -64,7 +64,7 @@ local function assertIsRect(x, y, w, h)
|
||||
assertIsPositiveNumber(h, 'h')
|
||||
end
|
||||
|
||||
local defaultFilter = function()
|
||||
local defaultFilter = function ()
|
||||
return 'slide'
|
||||
end
|
||||
|
||||
@@ -89,13 +89,13 @@ local function rect_getSegmentIntersectionIndices(x, y, w, h, x1, y1, x2, y2, ti
|
||||
|
||||
for side = 1, 4 do
|
||||
if side == 1 then
|
||||
nx, ny, p, q = -1, 0, -dx, x1 - x -- left
|
||||
nx, ny, p, q = -1, 0, -dx, x1 - x -- left
|
||||
elseif side == 2 then
|
||||
nx, ny, p, q = 1, 0, dx, x + w - x1 -- right
|
||||
nx, ny, p, q = 1, 0, dx, x + w - x1 -- right
|
||||
elseif side == 3 then
|
||||
nx, ny, p, q = 0, -1, -dy, y1 - y -- top
|
||||
nx, ny, p, q = 0, -1, -dy, y1 - y -- top
|
||||
else
|
||||
nx, ny, p, q = 0, 1, dy, y + h - y1 -- bottom
|
||||
nx, ny, p, q = 0, 1, dy, y + h - y1 -- bottom
|
||||
end
|
||||
|
||||
if p == 0 then
|
||||
@@ -146,18 +146,18 @@ local function rect_getSquareDistance(x1, y1, w1, h1, x2, y2, w2, h2)
|
||||
end
|
||||
|
||||
local function rect_detectCollision(x1, y1, w1, h1, x2, y2, w2, h2, goalX, goalY)
|
||||
goalX = goalX or x1
|
||||
goalY = goalY or y1
|
||||
goalX = goalX or x1
|
||||
goalY = goalY or y1
|
||||
|
||||
local dx, dy = goalX - x1, goalY - y1
|
||||
local dx, dy = goalX - x1, goalY - y1
|
||||
local x, y, w, h = rect_getDiff(x1, y1, w1, h1, x2, y2, w2, h2)
|
||||
|
||||
local overlaps, ti, nx, ny
|
||||
|
||||
if rect_containsPoint(x, y, w, h, 0, 0) then -- item was intersecting other
|
||||
if rect_containsPoint(x, y, w, h, 0, 0) then -- item was intersecting other
|
||||
local px, py = rect_getNearestCorner(x, y, w, h, 0, 0)
|
||||
local wi, hi = min(w1, abs(px)), min(h1, abs(py)) -- area of intersection
|
||||
ti = -wi * hi -- ti is the negative area of intersection
|
||||
local wi, hi = min(w1, abs(px)), min(h1, abs(py)) -- area of intersection
|
||||
ti = -wi * hi -- ti is the negative area of intersection
|
||||
overlaps = true
|
||||
else
|
||||
local ti1, ti2, nx1, ny1 = rect_getSegmentIntersectionIndices(x, y, w, h, 0, 0, dx, dy, -math.huge, math.huge)
|
||||
@@ -273,16 +273,16 @@ end
|
||||
-- Responses
|
||||
------------------------------------------
|
||||
|
||||
local touch = function(world, col, x, y, w, h, goalX, goalY, filter)
|
||||
local touch = function (world, col, x, y, w, h, goalX, goalY, filter)
|
||||
return col.touch.x, col.touch.y, {}, 0
|
||||
end
|
||||
|
||||
local cross = function(world, col, x, y, w, h, goalX, goalY, filter)
|
||||
local cross = function (world, col, x, y, w, h, goalX, goalY, filter)
|
||||
local cols, len = world:project(col.item, x, y, w, h, goalX, goalY, filter)
|
||||
return goalX, goalY, cols, len
|
||||
end
|
||||
|
||||
local slide = function(world, col, x, y, w, h, goalX, goalY, filter)
|
||||
local slide = function (world, col, x, y, w, h, goalX, goalY, filter)
|
||||
goalX = goalX or x
|
||||
goalY = goalY or y
|
||||
|
||||
@@ -302,7 +302,7 @@ local slide = function(world, col, x, y, w, h, goalX, goalY, filter)
|
||||
return goalX, goalY, cols, len
|
||||
end
|
||||
|
||||
local bounce = function(world, col, x, y, w, h, goalX, goalY, filter)
|
||||
local bounce = function (world, col, x, y, w, h, goalX, goalY, filter)
|
||||
goalX = goalX or x
|
||||
goalY = goalY or y
|
||||
|
||||
@@ -393,7 +393,7 @@ end
|
||||
local function getCellsTouchedBySegment(self, x1, y1, x2, y2)
|
||||
local cells, cellsLen, visited = {}, 0, {}
|
||||
|
||||
grid_traverse(self.cellSize, x1, y1, x2, y2, function(cx, cy)
|
||||
grid_traverse(self.cellSize, x1, y1, x2, y2, function (cx, cy)
|
||||
local row = self.rows[cy]
|
||||
if not row then return end
|
||||
local cell = row[cx]
|
||||
@@ -417,14 +417,14 @@ local function getInfoAboutItemsTouchedBySegment(self, x1, y1, x2, y2, filter)
|
||||
if not visited[item] then
|
||||
visited[item] = true
|
||||
if (not filter or filter(item)) then
|
||||
rect = self.rects[item]
|
||||
rect = self.rects[item]
|
||||
l, t, w, h = rect.x, rect.y, rect.w, rect.h
|
||||
|
||||
ti1, ti2 = rect_getSegmentIntersectionIndices(l, t, w, h, x1, y1, x2, y2, 0, 1)
|
||||
ti1, ti2 = rect_getSegmentIntersectionIndices(l, t, w, h, x1, y1, x2, y2, 0, 1)
|
||||
if ti1 and ((0 < ti1 and ti1 < 1) or (0 < ti2 and ti2 < 1)) then
|
||||
-- the sorting is according to the t of an infinite line, not the segment
|
||||
tii0, tii1 = rect_getSegmentIntersectionIndices(l, t, w, h, x1, y1, x2, y2, -math
|
||||
.huge, math.huge)
|
||||
.huge, math.huge)
|
||||
itemInfoLen = itemInfoLen + 1
|
||||
itemInfo[itemInfoLen] = { item = item, ti1 = ti1, ti2 = ti2, weight = min(tii0, tii1) }
|
||||
end
|
||||
@@ -480,7 +480,7 @@ function World:project(item, x, y, w, h, goalX, goalY, filter)
|
||||
local responseName = filter(item, other)
|
||||
if responseName then
|
||||
local ox, oy, ow, oh = self:getRect(other)
|
||||
local col = rect_detectCollision(x, y, w, h, ox, oy, ow, oh, goalX, goalY)
|
||||
local col = rect_detectCollision(x, y, w, h, ox, oy, ow, oh, goalX, goalY)
|
||||
|
||||
if col then
|
||||
col.other = other
|
||||
@@ -532,8 +532,8 @@ function World:getRect(item)
|
||||
local rect = self.rects[item]
|
||||
if not rect then
|
||||
error('Item ' ..
|
||||
tostring(item) ..
|
||||
' must be added to the world before getting its rect. Use world:add(item, x,y,w,h) to add it first.')
|
||||
tostring(item) ..
|
||||
' must be added to the world before getting its rect. Use world:add(item, x,y,w,h) to add it first.')
|
||||
end
|
||||
return rect.x, rect.y, rect.w, rect.h
|
||||
end
|
||||
@@ -701,7 +701,7 @@ function World:check(item, goalX, goalY, filter)
|
||||
filter = filter or defaultFilter
|
||||
|
||||
local visited = { [item] = true }
|
||||
local visitedFilter = function(itm, other)
|
||||
local visitedFilter = function (itm, other)
|
||||
if visited[other] then return false end
|
||||
return filter(itm, other)
|
||||
end
|
||||
@@ -735,7 +735,7 @@ end
|
||||
|
||||
-- Public library functions
|
||||
|
||||
bump.newWorld = function(cellSize)
|
||||
bump.newWorld = function (cellSize)
|
||||
cellSize = cellSize or 64
|
||||
assertIsPositiveNumber(cellSize, 'cellSize')
|
||||
local world = setmetatable({
|
||||
|
||||
@@ -19,21 +19,21 @@ end
|
||||
|
||||
local function checkNumber(value, name)
|
||||
if type(value) ~= 'number' then
|
||||
error(name .. " must be a number (was: " .. tostring(value) .. ")")
|
||||
error(name .. ' must be a number (was: ' .. tostring(value) .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
local function checkPositiveNumber(value, name)
|
||||
if type(value) ~= 'number' or value <= 0 then
|
||||
error(name .. " must be a positive number (was: " .. tostring(value) .. ")")
|
||||
error(name .. ' must be a positive number (was: ' .. tostring(value) .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
local function checkAABB(l, t, w, h)
|
||||
checkNumber(l, "l")
|
||||
checkNumber(t, "t")
|
||||
checkPositiveNumber(w, "w")
|
||||
checkPositiveNumber(h, "h")
|
||||
checkNumber(l, 'l')
|
||||
checkNumber(t, 't')
|
||||
checkPositiveNumber(w, 'w')
|
||||
checkPositiveNumber(h, 'h')
|
||||
end
|
||||
|
||||
local function getVisibleArea(self, scale)
|
||||
@@ -53,23 +53,24 @@ end
|
||||
|
||||
local function adjustPosition(self)
|
||||
local wl, wt, ww, wh = self.wl, self.wt, self.ww, self.wh
|
||||
local w, h = getVisibleArea(self)
|
||||
local w2, h2 = w * 0.5, h * 0.5
|
||||
local w, h = getVisibleArea(self)
|
||||
local w2, h2 = w * 0.5, h * 0.5
|
||||
|
||||
local left, right = wl + w2, wl + ww - w2
|
||||
local top, bottom = wt + h2, wt + wh - h2
|
||||
local left, right = wl + w2, wl + ww - w2
|
||||
local top, bottom = wt + h2, wt + wh - h2
|
||||
|
||||
self.x, self.y = clamp(self.x, left, right), clamp(self.y, top, bottom)
|
||||
self.x, self.y = clamp(self.x, left, right), clamp(self.y, top, bottom)
|
||||
end
|
||||
|
||||
local function adjustScale(self)
|
||||
local w, h, ww, wh = self.w, self.h, self.ww, self.wh
|
||||
local rw, rh = getVisibleArea(self, 1) -- rotated frame: area around the window, rotated without scaling
|
||||
local sx, sy = rw / ww,
|
||||
rh / wh -- vert/horiz scale: minimun scales that the window needs to occupy the world
|
||||
local rscale = max(sx, sy)
|
||||
local rw, rh = getVisibleArea(self, 1) -- rotated frame: area around the window, rotated without scaling
|
||||
local sx, sy = rw / ww,
|
||||
rh /
|
||||
wh -- vert/horiz scale: minimun scales that the window needs to occupy the world
|
||||
local rscale = max(sx, sy)
|
||||
|
||||
self.scale = max(self.scale, rscale)
|
||||
self.scale = max(self.scale, rscale)
|
||||
end
|
||||
|
||||
-- Public interface
|
||||
@@ -114,8 +115,8 @@ function gamera:setWindow(l, t, w, h)
|
||||
end
|
||||
|
||||
function gamera:setPosition(x, y)
|
||||
checkNumber(x, "x")
|
||||
checkNumber(y, "y")
|
||||
checkNumber(x, 'x')
|
||||
checkNumber(y, 'y')
|
||||
|
||||
self.x, self.y = x, y
|
||||
|
||||
@@ -123,7 +124,7 @@ function gamera:setPosition(x, y)
|
||||
end
|
||||
|
||||
function gamera:setScale(scale)
|
||||
checkNumber(scale, "scale")
|
||||
checkNumber(scale, 'scale')
|
||||
|
||||
self.scale = scale
|
||||
|
||||
@@ -132,7 +133,7 @@ function gamera:setScale(scale)
|
||||
end
|
||||
|
||||
function gamera:setAngle(angle)
|
||||
checkNumber(angle, "angle")
|
||||
checkNumber(angle, 'angle')
|
||||
|
||||
self.angle = angle
|
||||
self.cos, self.sin = math.cos(angle), math.sin(angle)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---@class ResolutionSolution
|
||||
--- @class ResolutionSolution
|
||||
local rs = {
|
||||
_URL = "https://github.com/Vovkiv/resolution_solution",
|
||||
_URL = 'https://github.com/Vovkiv/resolution_solution',
|
||||
-- All functionality of this library documented here.
|
||||
_DOCUMENTATION = "https://github.com/Vovkiv/resolution_solution/blob/main/resolution_solution_documentation.pdf",
|
||||
_DOCUMENTATION = 'https://github.com/Vovkiv/resolution_solution/blob/main/resolution_solution_documentation.pdf',
|
||||
_VERSION = 3004,
|
||||
-- love2d version for which this library designed.
|
||||
_LOVE = 11.5,
|
||||
_DESCRIPTION = "Yet another scaling library.",
|
||||
_NAME = "Resolution Solution",
|
||||
_LICENSE = "The Unlicense",
|
||||
_DESCRIPTION = 'Yet another scaling library.',
|
||||
_NAME = 'Resolution Solution',
|
||||
_LICENSE = 'The Unlicense',
|
||||
_LICENSE_TEXT = [[
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
@@ -83,23 +83,23 @@ rs.game_zone = {
|
||||
--- scale_mode = rs.PIXEL_PERFECT_MODE
|
||||
--- })
|
||||
--- ```
|
||||
---@param options table?
|
||||
rs.conf = function(options)
|
||||
--- @param options table?
|
||||
rs.conf = function (options)
|
||||
-- Sanitize.
|
||||
if type(options) == "nil" then
|
||||
if type(options) == 'nil' then
|
||||
options = {}
|
||||
elseif type(options) ~= "table" then
|
||||
error(".conf: 1st argument should be table or nil. You passed: " .. type(options) .. ".", 2)
|
||||
elseif type(options) ~= 'table' then
|
||||
error('.conf: 1st argument should be table or nil. You passed: ' .. type(options) .. '.', 2)
|
||||
end
|
||||
|
||||
|
||||
if options.game_width then
|
||||
if type(options.game_width) ~= "number" then
|
||||
error(".conf: field \'game_width\' should be number. You passed: " .. type(options.game_width) .. ".", 2)
|
||||
if type(options.game_width) ~= 'number' then
|
||||
error('.conf: field \'game_width\' should be number. You passed: ' .. type(options.game_width) .. '.', 2)
|
||||
end
|
||||
|
||||
if options.game_width < 0 then
|
||||
error(".conf: field \'game_width\' should be 0 or more. You passed: " .. tostring(options.game_width) .. ".",
|
||||
error('.conf: field \'game_width\' should be 0 or more. You passed: ' .. tostring(options.game_width) .. '.',
|
||||
2)
|
||||
end
|
||||
|
||||
@@ -107,25 +107,25 @@ rs.conf = function(options)
|
||||
end
|
||||
|
||||
if options.game_height then
|
||||
if type(options.game_height) ~= "number" then
|
||||
error(".conf: \'game_height\' should be number. You passed: " .. type(options.game_height) .. ".", 2)
|
||||
if type(options.game_height) ~= 'number' then
|
||||
error('.conf: \'game_height\' should be number. You passed: ' .. type(options.game_height) .. '.', 2)
|
||||
end
|
||||
|
||||
if options.game_height < 0 then
|
||||
error(".conf: \'game_height\' should be 0 or more. You passed: " .. tostring(options.game_height) .. ".", 2)
|
||||
error('.conf: \'game_height\' should be 0 or more. You passed: ' .. tostring(options.game_height) .. '.', 2)
|
||||
end
|
||||
|
||||
rs.game_height = options.game_height
|
||||
end
|
||||
|
||||
if options.scale_mode then
|
||||
if type(options.scale_mode) ~= "number" then
|
||||
error(".conf: field \'scale_mode\' should be number. You passed: " .. type(options.scale_mode) .. ".", 2)
|
||||
if type(options.scale_mode) ~= 'number' then
|
||||
error('.conf: field \'scale_mode\' should be number. You passed: ' .. type(options.scale_mode) .. '.', 2)
|
||||
end
|
||||
|
||||
if options.scale_mode > 4 or options.scale_mode < 1 then
|
||||
error("conf: field \'scale_mode\' can be only 1, 2, 3 and 4. You passed: " ..
|
||||
tostring(options.scale_mode) .. ".")
|
||||
error('conf: field \'scale_mode\' can be only 1, 2, 3 and 4. You passed: ' ..
|
||||
tostring(options.scale_mode) .. '.')
|
||||
end
|
||||
|
||||
rs.scale_mode = options.scale_mode
|
||||
@@ -163,7 +163,7 @@ end
|
||||
--- rs.pop()
|
||||
--- end
|
||||
--- ```
|
||||
rs.push = function()
|
||||
rs.push = function ()
|
||||
love.graphics.push()
|
||||
love.graphics.origin()
|
||||
love.graphics.translate(rs.x_offset, rs.y_offset)
|
||||
@@ -198,7 +198,7 @@ end
|
||||
--- rs.pop()
|
||||
--- end
|
||||
--- ```
|
||||
rs.pop = function()
|
||||
rs.pop = function ()
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
@@ -223,22 +223,22 @@ end
|
||||
--- rs.resize()
|
||||
--- end
|
||||
--- ```
|
||||
---@param window_width number?
|
||||
---@param window_height number?
|
||||
rs.resize = function(window_width, window_height)
|
||||
--- @param window_width number?
|
||||
--- @param window_height number?
|
||||
rs.resize = function (window_width, window_height)
|
||||
-- Sanitize.
|
||||
-- Window width.
|
||||
if type(window_width) == "nil" then
|
||||
if type(window_width) == 'nil' then
|
||||
window_width = love.graphics.getWidth()
|
||||
elseif type(window_width) ~= "number" then
|
||||
error(".resize: 1st argument should be nil or number. You passed: " .. type(window_width) .. ".")
|
||||
elseif type(window_width) ~= 'number' then
|
||||
error('.resize: 1st argument should be nil or number. You passed: ' .. type(window_width) .. '.')
|
||||
end
|
||||
|
||||
-- Window height.
|
||||
if type(window_height) == "nil" then
|
||||
if type(window_height) == 'nil' then
|
||||
window_height = love.graphics.getHeight()
|
||||
elseif type(window_height) ~= "number" then
|
||||
error(".resize: 2nd argument should be nil or number. You passed: " .. type(window_height) .. ".")
|
||||
elseif type(window_height) ~= 'number' then
|
||||
error('.resize: 2nd argument should be nil or number. You passed: ' .. type(window_height) .. '.')
|
||||
end
|
||||
|
||||
local scale_width, scale_height = 0, 0
|
||||
@@ -323,7 +323,7 @@ end
|
||||
--- rs.pop()
|
||||
--- end
|
||||
--- ```
|
||||
rs.resize_callback = function() end
|
||||
rs.resize_callback = function () end
|
||||
|
||||
--- This is a function to help you debug. It shows information about the library states. You can
|
||||
--- display these states on the screen to help you troubleshoot. Calling rs.debug_info() without
|
||||
@@ -340,9 +340,9 @@ rs.resize_callback = function() end
|
||||
--- - rs.scale_mode
|
||||
--- - rs.x_offset
|
||||
--- - rs.y_offset
|
||||
---@param debug_x number? If you pass nothing or nil, then it will same as if you pass 0.
|
||||
---@param debug_y number? If you pass nothing or nil, then it will same as if you pass 0.
|
||||
rs.debug_info = function(debug_x, debug_y)
|
||||
--- @param debug_x number? If you pass nothing or nil, then it will same as if you pass 0.
|
||||
--- @param debug_y number? If you pass nothing or nil, then it will same as if you pass 0.
|
||||
rs.debug_info = function (debug_x, debug_y)
|
||||
-- Set width and height for debug "window".
|
||||
local debug_width, debug_height = 215, 120
|
||||
|
||||
@@ -351,12 +351,12 @@ rs.debug_info = function(debug_x, debug_y)
|
||||
debug_y = debug_y or 0
|
||||
|
||||
-- Do sanity check for input arguments.
|
||||
if type(debug_x) ~= "number" then
|
||||
error(".debug_info: 1st argument should be number or nil. You passed: " .. type(debug_x) .. ".", 2)
|
||||
if type(debug_x) ~= 'number' then
|
||||
error('.debug_info: 1st argument should be number or nil. You passed: ' .. type(debug_x) .. '.', 2)
|
||||
end
|
||||
|
||||
if type(debug_y) ~= "number" then
|
||||
error(".debug_info: 2nd argument should be number or nil. You passed: " .. type(debug_y) .. ".", 2)
|
||||
if type(debug_y) ~= 'number' then
|
||||
error('.debug_info: 2nd argument should be number or nil. You passed: ' .. type(debug_y) .. '.', 2)
|
||||
end
|
||||
|
||||
-- Save color that was used before debug function.
|
||||
@@ -369,7 +369,7 @@ rs.debug_info = function(debug_x, debug_y)
|
||||
love.graphics.setColor(0, 0, 0, 0.5)
|
||||
|
||||
-- Place debug info on screen according to user input.
|
||||
love.graphics.rectangle("fill", debug_x, debug_y, debug_width, debug_height)
|
||||
love.graphics.rectangle('fill', debug_x, debug_y, debug_width, debug_height)
|
||||
|
||||
-- Set color.
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
@@ -379,14 +379,14 @@ rs.debug_info = function(debug_x, debug_y)
|
||||
|
||||
-- Print data.
|
||||
love.graphics.printf(
|
||||
rs._NAME .. " v." .. tostring(rs._VERSION) .. "\n" ..
|
||||
"game_width: " .. tostring(rs.game_width) .. "\n" ..
|
||||
"game_height: " .. tostring(rs.game_height) .. "\n" ..
|
||||
"scale_width: " .. tostring(rs.scale_width) .. "\n" ..
|
||||
"scale_height: " .. tostring(rs.scale_height) .. "\n" ..
|
||||
"scale_mode: " .. tostring(rs.scale_mode) .. "\n" ..
|
||||
"x_offset: " .. tostring(rs.x_offset) .. "\n" ..
|
||||
"y_offset: " .. tostring(rs.y_offset) .. "\n",
|
||||
rs._NAME .. ' v.' .. tostring(rs._VERSION) .. '\n' ..
|
||||
'game_width: ' .. tostring(rs.game_width) .. '\n' ..
|
||||
'game_height: ' .. tostring(rs.game_height) .. '\n' ..
|
||||
'scale_width: ' .. tostring(rs.scale_width) .. '\n' ..
|
||||
'scale_height: ' .. tostring(rs.scale_height) .. '\n' ..
|
||||
'scale_mode: ' .. tostring(rs.scale_mode) .. '\n' ..
|
||||
'x_offset: ' .. tostring(rs.x_offset) .. '\n' ..
|
||||
'y_offset: ' .. tostring(rs.y_offset) .. '\n',
|
||||
debug_x, debug_y, debug_width)
|
||||
|
||||
-- Return previous color.
|
||||
@@ -404,11 +404,11 @@ end
|
||||
--- local x, y, w, h = rs.get_game_zone()
|
||||
--- ```
|
||||
---
|
||||
---@return number game_zone.x
|
||||
---@return number game_zone.y
|
||||
---@return number game_zone.w
|
||||
---@return number game_zone.h
|
||||
rs.get_game_zone = function()
|
||||
--- @return number game_zone.x
|
||||
--- @return number game_zone.y
|
||||
--- @return number game_zone.w
|
||||
--- @return number game_zone.h
|
||||
rs.get_game_zone = function ()
|
||||
local game_zone = rs.game_zone
|
||||
return game_zone.x, game_zone.y, game_zone.w, game_zone.h
|
||||
end
|
||||
@@ -421,9 +421,9 @@ end
|
||||
--- -- Basic usage.
|
||||
--- local game_width, game_height = rs.get_game_size()
|
||||
--- ```
|
||||
---@return number rs.game_width
|
||||
---@return number rs.game_height
|
||||
rs.get_game_size = function()
|
||||
--- @return number rs.game_width
|
||||
--- @return number rs.game_height
|
||||
rs.get_game_size = function ()
|
||||
return rs.game_width, rs.game_height
|
||||
end
|
||||
|
||||
@@ -486,16 +486,16 @@ end
|
||||
--- rs.pop()
|
||||
--- end
|
||||
--- ```
|
||||
---@param it_x number
|
||||
---@param it_y number
|
||||
rs.is_it_inside = function(it_x, it_y)
|
||||
--- @param it_x number
|
||||
--- @param it_y number
|
||||
rs.is_it_inside = function (it_x, it_y)
|
||||
-- Input sanitizing.
|
||||
if type(it_x) ~= "number" then
|
||||
error(".is_it_inside: Argument #1 should be number. You passed: " .. type(it_x) .. ".", 2)
|
||||
if type(it_x) ~= 'number' then
|
||||
error('.is_it_inside: Argument #1 should be number. You passed: ' .. type(it_x) .. '.', 2)
|
||||
end
|
||||
|
||||
if type(it_y) ~= "number" then
|
||||
error(".is_it_inside: Argument #2 should be number. You passed: " .. type(it_y) .. ".", 2)
|
||||
if type(it_y) ~= 'number' then
|
||||
error('.is_it_inside: Argument #2 should be number. You passed: ' .. type(it_y) .. '.', 2)
|
||||
end
|
||||
|
||||
-- If we in Stretch or No Scaling mode - then we always inside.
|
||||
@@ -506,10 +506,10 @@ rs.is_it_inside = function(it_x, it_y)
|
||||
local x, y, w, h = rs.game_zone.x, rs.game_zone.y, rs.game_zone.w, rs.game_zone.h
|
||||
|
||||
-- Check if it inside game zone.
|
||||
if it_x >= x and -- left
|
||||
it_y >= y and -- top
|
||||
it_x <= x + w and -- right
|
||||
it_y <= y + h then -- bottom
|
||||
if it_x >= x and -- left
|
||||
it_y >= y and -- top
|
||||
it_x <= x + w and -- right
|
||||
it_y <= y + h then -- bottom
|
||||
-- It inside game zone.
|
||||
return true
|
||||
end
|
||||
@@ -525,9 +525,9 @@ end
|
||||
--- -- Basic usage.
|
||||
--- local x_scale, y_scale = rs.get_both_scales()
|
||||
--- ```
|
||||
---@return number rs.scale_width
|
||||
---@return number rs.scale_height
|
||||
rs.get_both_scales = function()
|
||||
--- @return number rs.scale_width
|
||||
--- @return number rs.scale_height
|
||||
rs.get_both_scales = function ()
|
||||
return rs.scale_width, rs.scale_height
|
||||
end
|
||||
|
||||
@@ -570,26 +570,26 @@ end
|
||||
--- end
|
||||
--- end
|
||||
--- ```
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@return number|nil ScaledGameX
|
||||
---@return number|nil ScaledGameY
|
||||
rs.to_game = function(x, y)
|
||||
--- @param x number
|
||||
--- @param y number
|
||||
--- @return number|nil ScaledGameX
|
||||
--- @return number|nil ScaledGameY
|
||||
rs.to_game = function (x, y)
|
||||
-- User passed only x.
|
||||
if type(x) == "number" and type(y) == "nil" then
|
||||
if type(x) == 'number' and type(y) == 'nil' then
|
||||
return (x - rs.x_offset) / rs.scale_width
|
||||
|
||||
-- User passed only y.
|
||||
elseif type(x) == "nil" and type(y) == "number" then
|
||||
elseif type(x) == 'nil' and type(y) == 'number' then
|
||||
return (y - rs.y_offset) / rs.scale_height
|
||||
|
||||
-- User passed both X and Y.
|
||||
elseif type(x) == "number" and type(y) == "number" then
|
||||
elseif type(x) == 'number' and type(y) == 'number' then
|
||||
return (x - rs.x_offset) / rs.scale_width, (y - rs.y_offset) / rs.scale_height
|
||||
|
||||
-- User passed wrong arguments.
|
||||
else
|
||||
error(".to_game: At least 1 argument should be number. You passed: " .. type(x) .. " and " .. type(y), 2)
|
||||
error('.to_game: At least 1 argument should be number. You passed: ' .. type(x) .. ' and ' .. type(y), 2)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -643,26 +643,26 @@ end
|
||||
--- rs.pop()
|
||||
--- end
|
||||
--- ```
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@return number|nil ScaledWindowX
|
||||
---@return number|nil ScaledWindowY
|
||||
rs.to_window = function(x, y)
|
||||
--- @param x number
|
||||
--- @param y number
|
||||
--- @return number|nil ScaledWindowX
|
||||
--- @return number|nil ScaledWindowY
|
||||
rs.to_window = function (x, y)
|
||||
-- User passed only X.
|
||||
if type(x) == "number" and type(y) == "nil" then
|
||||
if type(x) == 'number' and type(y) == 'nil' then
|
||||
return (x * rs.scale_width) + rs.x_offset
|
||||
|
||||
-- User passed only Y.
|
||||
elseif type(x) == "nil" and type(y) == "number" then
|
||||
elseif type(x) == 'nil' and type(y) == 'number' then
|
||||
return (y * rs.scale_height) + rs.y_offset
|
||||
|
||||
-- User passed both X and Y.
|
||||
elseif type(x) == "number" and type(y) == "number" then
|
||||
elseif type(x) == 'number' and type(y) == 'number' then
|
||||
return (x * rs.scale_width) + rs.x_offset, (y * rs.scale_height) + rs.y_offset
|
||||
|
||||
-- User passed wrong arguments.
|
||||
else
|
||||
error(".to_window: At least 1 argument should be number. You passed: " .. type(x) .. " and " .. type(y), 2)
|
||||
error('.to_window: At least 1 argument should be number. You passed: ' .. type(x) .. ' and ' .. type(y), 2)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -690,13 +690,13 @@ end
|
||||
--- rs.setMode(rs.get_game_size(), select(3, love.window.getMode()))
|
||||
-- -- Done, now we initialized game with 800x600 game size and resized window to be same as game width and height.
|
||||
--- ```
|
||||
---@param width number
|
||||
---@param height number
|
||||
---@param flags table
|
||||
rs.setMode = function(width, height, flags)
|
||||
--- @param width number
|
||||
--- @param height number
|
||||
--- @param flags table
|
||||
rs.setMode = function (width, height, flags)
|
||||
local okay, errorMessage = pcall(love.window.setMode, width, height, flags)
|
||||
if not okay then
|
||||
error(".setMode: Error: " .. errorMessage, 2)
|
||||
error('.setMode: Error: ' .. errorMessage, 2)
|
||||
end
|
||||
|
||||
rs.resize()
|
||||
@@ -729,13 +729,13 @@ end
|
||||
--- -- Done, now we initialized game with 800x600 game size and resized window to
|
||||
--- be same as game width and height.
|
||||
--- ```
|
||||
---@param width number
|
||||
---@param height number
|
||||
---@param flags table
|
||||
rs.updateMode = function(width, height, flags)
|
||||
--- @param width number
|
||||
--- @param height number
|
||||
--- @param flags table
|
||||
rs.updateMode = function (width, height, flags)
|
||||
local okay, errorMessage = pcall(love.window.updateMode, width, height, flags)
|
||||
if not okay then
|
||||
error(".updateMode: Error: " .. errorMessage, 2)
|
||||
error('.updateMode: Error: ' .. errorMessage, 2)
|
||||
end
|
||||
|
||||
rs.resize()
|
||||
|
||||
@@ -21,78 +21,78 @@
|
||||
indent is a first indentation (optional).
|
||||
--]]
|
||||
function table.show(t, name, indent)
|
||||
local cart -- a container
|
||||
local autoref -- for self references
|
||||
|
||||
--[[ counts the number of elements in a table
|
||||
local cart -- a container
|
||||
local autoref -- for self references
|
||||
|
||||
--[[ counts the number of elements in a table
|
||||
local function tablecount(t)
|
||||
local n = 0
|
||||
for _, _ in pairs(t) do n = n+1 end
|
||||
return n
|
||||
end
|
||||
]]
|
||||
-- (RiciLake) returns true if the table is empty
|
||||
local function isemptytable(t) return next(t) == nil end
|
||||
|
||||
local function basicSerialize (o)
|
||||
local so = tostring(o)
|
||||
if type(o) == "function" then
|
||||
local info = debug.getinfo(o, "S")
|
||||
-- info.name is nil because o is not a calling level
|
||||
if info.what == "C" then
|
||||
return string.format("%q", so .. ", C function")
|
||||
else
|
||||
-- the information is defined through lines
|
||||
return string.format("%q", so .. ", defined in (" ..
|
||||
info.linedefined .. "-" .. info.lastlinedefined ..
|
||||
")" .. info.source)
|
||||
end
|
||||
elseif type(o) == "number" or type(o) == "boolean" then
|
||||
return so
|
||||
else
|
||||
return string.format("%q", so)
|
||||
end
|
||||
end
|
||||
|
||||
local function addtocart (value, name, indent, saved, field)
|
||||
indent = indent or ""
|
||||
saved = saved or {}
|
||||
field = field or name
|
||||
|
||||
cart = cart .. indent .. field
|
||||
|
||||
if type(value) ~= "table" then
|
||||
cart = cart .. " = " .. basicSerialize(value) .. ";\n"
|
||||
else
|
||||
if saved[value] then
|
||||
cart = cart .. " = {}; -- " .. saved[value]
|
||||
.. " (self reference)\n"
|
||||
autoref = autoref .. name .. " = " .. saved[value] .. ";\n"
|
||||
else
|
||||
saved[value] = name
|
||||
--if tablecount(value) == 0 then
|
||||
if isemptytable(value) then
|
||||
cart = cart .. " = {};\n"
|
||||
else
|
||||
cart = cart .. " = {\n"
|
||||
for k, v in pairs(value) do
|
||||
k = basicSerialize(k)
|
||||
local fname = string.format("%s[%s]", name, k)
|
||||
field = string.format("[%s]", k)
|
||||
-- three spaces between levels
|
||||
addtocart(v, fname, indent .. " ", saved, field)
|
||||
end
|
||||
cart = cart .. indent .. "};\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
name = name or "__unnamed__"
|
||||
if type(t) ~= "table" then
|
||||
return name .. " = " .. basicSerialize(t)
|
||||
end
|
||||
cart, autoref = "", ""
|
||||
addtocart(t, name, indent)
|
||||
return cart .. autoref
|
||||
end
|
||||
-- (RiciLake) returns true if the table is empty
|
||||
local function isemptytable(t) return next(t) == nil end
|
||||
|
||||
local function basicSerialize(o)
|
||||
local so = tostring(o)
|
||||
if type(o) == 'function' then
|
||||
local info = debug.getinfo(o, 'S')
|
||||
-- info.name is nil because o is not a calling level
|
||||
if info.what == 'C' then
|
||||
return string.format('%q', so .. ', C function')
|
||||
else
|
||||
-- the information is defined through lines
|
||||
return string.format('%q', so .. ', defined in (' ..
|
||||
info.linedefined .. '-' .. info.lastlinedefined ..
|
||||
')' .. info.source)
|
||||
end
|
||||
elseif type(o) == 'number' or type(o) == 'boolean' then
|
||||
return so
|
||||
else
|
||||
return string.format('%q', so)
|
||||
end
|
||||
end
|
||||
|
||||
local function addtocart(value, name, indent, saved, field)
|
||||
indent = indent or ''
|
||||
saved = saved or {}
|
||||
field = field or name
|
||||
|
||||
cart = cart .. indent .. field
|
||||
|
||||
if type(value) ~= 'table' then
|
||||
cart = cart .. ' = ' .. basicSerialize(value) .. ';\n'
|
||||
else
|
||||
if saved[value] then
|
||||
cart = cart .. ' = {}; -- ' .. saved[value]
|
||||
.. ' (self reference)\n'
|
||||
autoref = autoref .. name .. ' = ' .. saved[value] .. ';\n'
|
||||
else
|
||||
saved[value] = name
|
||||
-- if tablecount(value) == 0 then
|
||||
if isemptytable(value) then
|
||||
cart = cart .. ' = {};\n'
|
||||
else
|
||||
cart = cart .. ' = {\n'
|
||||
for k, v in pairs(value) do
|
||||
k = basicSerialize(k)
|
||||
local fname = string.format('%s[%s]', name, k)
|
||||
field = string.format('[%s]', k)
|
||||
-- three spaces between levels
|
||||
addtocart(v, fname, indent .. ' ', saved, field)
|
||||
end
|
||||
cart = cart .. indent .. '};\n'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
name = name or '__unnamed__'
|
||||
if type(t) ~= 'table' then
|
||||
return name .. ' = ' .. basicSerialize(t)
|
||||
end
|
||||
cart, autoref = '', ''
|
||||
addtocart(t, name, indent)
|
||||
return cart .. autoref
|
||||
end
|
||||
|
||||
@@ -25,8 +25,8 @@ THE SOFTWARE.
|
||||
]] --
|
||||
|
||||
local Registry = {}
|
||||
Registry.__index = function(self, key)
|
||||
return Registry[key] or (function()
|
||||
Registry.__index = function (self, key)
|
||||
return Registry[key] or (function ()
|
||||
local t = {}
|
||||
rawset(self, key, t)
|
||||
return t
|
||||
@@ -94,8 +94,8 @@ local default = Registry.new()
|
||||
-- module forwards calls to default instance
|
||||
local module = {}
|
||||
for k in pairs(Registry) do
|
||||
if k ~= "__index" then
|
||||
module[k] = function(...) return default[k](default, ...) end
|
||||
if k ~= '__index' then
|
||||
module[k] = function (...) return default[k](default, ...) end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -22,115 +22,115 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
]]--
|
||||
]] --
|
||||
|
||||
local sqrt, cos, sin, atan2 = math.sqrt, math.cos, math.sin, math.atan2
|
||||
|
||||
local function str(x,y)
|
||||
return "("..tonumber(x)..","..tonumber(y)..")"
|
||||
local function str(x, y)
|
||||
return '(' .. tonumber(x) .. ',' .. tonumber(y) .. ')'
|
||||
end
|
||||
|
||||
local function mul(s, x,y)
|
||||
return s*x, s*y
|
||||
local function mul(s, x, y)
|
||||
return s * x, s * y
|
||||
end
|
||||
|
||||
local function div(s, x,y)
|
||||
return x/s, y/s
|
||||
local function div(s, x, y)
|
||||
return x / s, y / s
|
||||
end
|
||||
|
||||
local function add(x1,y1, x2,y2)
|
||||
return x1+x2, y1+y2
|
||||
local function add(x1, y1, x2, y2)
|
||||
return x1 + x2, y1 + y2
|
||||
end
|
||||
|
||||
local function sub(x1,y1, x2,y2)
|
||||
return x1-x2, y1-y2
|
||||
local function sub(x1, y1, x2, y2)
|
||||
return x1 - x2, y1 - y2
|
||||
end
|
||||
|
||||
local function permul(x1,y1, x2,y2)
|
||||
return x1*x2, y1*y2
|
||||
local function permul(x1, y1, x2, y2)
|
||||
return x1 * x2, y1 * y2
|
||||
end
|
||||
|
||||
local function dot(x1,y1, x2,y2)
|
||||
return x1*x2 + y1*y2
|
||||
local function dot(x1, y1, x2, y2)
|
||||
return x1 * x2 + y1 * y2
|
||||
end
|
||||
|
||||
local function det(x1,y1, x2,y2)
|
||||
return x1*y2 - y1*x2
|
||||
local function det(x1, y1, x2, y2)
|
||||
return x1 * y2 - y1 * x2
|
||||
end
|
||||
|
||||
local function eq(x1,y1, x2,y2)
|
||||
local function eq(x1, y1, x2, y2)
|
||||
return x1 == x2 and y1 == y2
|
||||
end
|
||||
|
||||
local function lt(x1,y1, x2,y2)
|
||||
local function lt(x1, y1, x2, y2)
|
||||
return x1 < x2 or (x1 == x2 and y1 < y2)
|
||||
end
|
||||
|
||||
local function le(x1,y1, x2,y2)
|
||||
local function le(x1, y1, x2, y2)
|
||||
return x1 <= x2 and y1 <= y2
|
||||
end
|
||||
|
||||
local function len2(x,y)
|
||||
return x*x + y*y
|
||||
local function len2(x, y)
|
||||
return x * x + y * y
|
||||
end
|
||||
|
||||
local function len(x,y)
|
||||
return sqrt(x*x + y*y)
|
||||
local function len(x, y)
|
||||
return sqrt(x * x + y * y)
|
||||
end
|
||||
|
||||
local function fromPolar(angle, radius)
|
||||
radius = radius or 1
|
||||
return cos(angle)*radius, sin(angle)*radius
|
||||
return cos(angle) * radius, sin(angle) * radius
|
||||
end
|
||||
|
||||
local function randomDirection(len_min, len_max)
|
||||
len_min = len_min or 1
|
||||
len_max = len_max or len_min
|
||||
|
||||
assert(len_max > 0, "len_max must be greater than zero")
|
||||
assert(len_max >= len_min, "len_max must be greater than or equal to len_min")
|
||||
assert(len_max > 0, 'len_max must be greater than zero')
|
||||
assert(len_max >= len_min, 'len_max must be greater than or equal to len_min')
|
||||
|
||||
return fromPolar(math.random()*2*math.pi,
|
||||
math.random() * (len_max-len_min) + len_min)
|
||||
return fromPolar(math.random() * 2 * math.pi,
|
||||
math.random() * (len_max - len_min) + len_min)
|
||||
end
|
||||
|
||||
local function toPolar(x, y)
|
||||
return atan2(y,x), len(x,y)
|
||||
return atan2(y, x), len(x, y)
|
||||
end
|
||||
|
||||
local function dist2(x1,y1, x2,y2)
|
||||
return len2(x1-x2, y1-y2)
|
||||
local function dist2(x1, y1, x2, y2)
|
||||
return len2(x1 - x2, y1 - y2)
|
||||
end
|
||||
|
||||
local function dist(x1,y1, x2,y2)
|
||||
return len(x1-x2, y1-y2)
|
||||
local function dist(x1, y1, x2, y2)
|
||||
return len(x1 - x2, y1 - y2)
|
||||
end
|
||||
|
||||
local function normalize(x,y)
|
||||
local l = len(x,y)
|
||||
local function normalize(x, y)
|
||||
local l = len(x, y)
|
||||
if l > 0 then
|
||||
return x/l, y/l
|
||||
return x / l, y / l
|
||||
end
|
||||
return x,y
|
||||
return x, y
|
||||
end
|
||||
|
||||
local function rotate(phi, x,y)
|
||||
local function rotate(phi, x, y)
|
||||
local c, s = cos(phi), sin(phi)
|
||||
return c*x - s*y, s*x + c*y
|
||||
return c * x - s * y, s * x + c * y
|
||||
end
|
||||
|
||||
local function perpendicular(x,y)
|
||||
local function perpendicular(x, y)
|
||||
return -y, x
|
||||
end
|
||||
|
||||
local function project(x,y, u,v)
|
||||
local s = (x*u + y*v) / (u*u + v*v)
|
||||
return s*u, s*v
|
||||
local function project(x, y, u, v)
|
||||
local s = (x * u + y * v) / (u * u + v * v)
|
||||
return s * u, s * v
|
||||
end
|
||||
|
||||
local function mirror(x,y, u,v)
|
||||
local s = 2 * (x*u + y*v) / (u*u + v*v)
|
||||
return s*u - x, s*v - y
|
||||
local function mirror(x, y, u, v)
|
||||
local s = 2 * (x * u + y * v) / (u * u + v * v)
|
||||
return s * u - x, s * v - y
|
||||
end
|
||||
|
||||
-- ref.: http://blog.signalsondisplay.com/?p=336
|
||||
@@ -140,7 +140,7 @@ local function trim(maxLen, x, y)
|
||||
return x * s, y * s
|
||||
end
|
||||
|
||||
local function angleTo(x,y, u,v)
|
||||
local function angleTo(x, y, u, v)
|
||||
if u and v then
|
||||
return atan2(y, x) - atan2(v, u)
|
||||
end
|
||||
@@ -149,38 +149,38 @@ end
|
||||
|
||||
-- the module
|
||||
return {
|
||||
str = str,
|
||||
str = str,
|
||||
|
||||
fromPolar = fromPolar,
|
||||
toPolar = toPolar,
|
||||
randomDirection = randomDirection,
|
||||
|
||||
-- arithmetic
|
||||
mul = mul,
|
||||
div = div,
|
||||
idiv = idiv,
|
||||
add = add,
|
||||
sub = sub,
|
||||
permul = permul,
|
||||
dot = dot,
|
||||
det = det,
|
||||
cross = det,
|
||||
mul = mul,
|
||||
div = div,
|
||||
idiv = idiv,
|
||||
add = add,
|
||||
sub = sub,
|
||||
permul = permul,
|
||||
dot = dot,
|
||||
det = det,
|
||||
cross = det,
|
||||
|
||||
-- relation
|
||||
eq = eq,
|
||||
lt = lt,
|
||||
le = le,
|
||||
eq = eq,
|
||||
lt = lt,
|
||||
le = le,
|
||||
|
||||
-- misc operations
|
||||
len2 = len2,
|
||||
len = len,
|
||||
dist2 = dist2,
|
||||
dist = dist,
|
||||
normalize = normalize,
|
||||
rotate = rotate,
|
||||
perpendicular = perpendicular,
|
||||
project = project,
|
||||
mirror = mirror,
|
||||
trim = trim,
|
||||
angleTo = angleTo,
|
||||
len2 = len2,
|
||||
len = len,
|
||||
dist2 = dist2,
|
||||
dist = dist,
|
||||
normalize = normalize,
|
||||
rotate = rotate,
|
||||
perpendicular = perpendicular,
|
||||
project = project,
|
||||
mirror = mirror,
|
||||
trim = trim,
|
||||
angleTo = angleTo,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local LoveNode = require "src.utils.love_node"
|
||||
local MainMenu = require "src.core.states.main_menu"
|
||||
local Game = require "src.core.states.game"
|
||||
local PauseMenu = require "src.core.states.pause_menu"
|
||||
local LoveNode = require 'src.utils.love_node'
|
||||
local MainMenu = require 'src.core.states.main_menu'
|
||||
local Game = require 'src.core.states.game'
|
||||
local PauseMenu = require 'src.core.states.pause_menu'
|
||||
|
||||
local GameCore = {}
|
||||
GameCore.__index = GameCore
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
-- https://love2d.org/forums/viewtopic.php?t=78729
|
||||
|
||||
local LoveNode = require "src.utils.love_node"
|
||||
local baton = require "packages.baton"
|
||||
local Camera = require "src.display.camera"
|
||||
local input = require "src.input_maps"
|
||||
local vector = require "packages.vector-light"
|
||||
local LoveNode = require 'src.utils.love_node'
|
||||
local baton = require 'packages.baton'
|
||||
local Camera = require 'src.display.camera'
|
||||
local input = require 'src.input_maps'
|
||||
local vector = require 'packages.vector-light'
|
||||
local mazegen = require 'src.maze_generation.prims'
|
||||
local mazeutils = require 'src.maze_generation.utils'
|
||||
local bump = require 'packages.bump'
|
||||
local crtshader = require "src.display.shaders.crt"
|
||||
local lightshader = require "src.display.shaders.light"
|
||||
local crtshader = require 'src.display.shaders.crt'
|
||||
local lightshader = require 'src.display.shaders.light'
|
||||
|
||||
|
||||
local TILE_SIZE = 16
|
||||
@@ -41,7 +41,7 @@ local function initPlayer(startX, startY)
|
||||
player.input.x = 0
|
||||
player.input.y = 0
|
||||
|
||||
player.texture = love.graphics.newImage("assets/player.png")
|
||||
player.texture = love.graphics.newImage('assets/player.png')
|
||||
|
||||
player.size = {}
|
||||
player.size.w, player.size.h = 12, 12 --player.texture:getDimensions()
|
||||
@@ -55,7 +55,7 @@ local function initMaze(world)
|
||||
local function createWall(x, y)
|
||||
local wall = {}
|
||||
|
||||
wall.texture = love.graphics.newImage("assets/wall.png")
|
||||
wall.texture = love.graphics.newImage('assets/wall.png')
|
||||
|
||||
wall.size = {}
|
||||
wall.size.w, wall.size.h = wall.texture:getDimensions()
|
||||
@@ -70,7 +70,7 @@ local function initMaze(world)
|
||||
local maze = mazegen(MAZE_SIZE, MAZE_SIZE)
|
||||
for y = 1, MAZE_SIZE do
|
||||
for x = 1, MAZE_SIZE do
|
||||
if maze[y][x] == "wall" then
|
||||
if maze[y][x] == 'wall' then
|
||||
local wall = createWall(x - 1, y - 1)
|
||||
|
||||
world:add(
|
||||
@@ -98,11 +98,11 @@ function Game.new(core)
|
||||
|
||||
self.shaders = {}
|
||||
self.shaders.crt = love.graphics.newShader(crtshader)
|
||||
self.shaders.crt:send("resolution", { love.graphics.getWidth(), love.graphics.getHeight() })
|
||||
self.shaders.crt:send("warp", 0.0)
|
||||
self.shaders.crt:send("scan", 1.1)
|
||||
self.shaders.crt:send('resolution', { love.graphics.getWidth(), love.graphics.getHeight() })
|
||||
self.shaders.crt:send('warp', 0.0)
|
||||
self.shaders.crt:send('scan', 1.1)
|
||||
self.shaders.light = love.graphics.newShader(lightshader)
|
||||
self.shaders.light:send("light_radius", 30)
|
||||
self.shaders.light:send('light_radius', 30)
|
||||
|
||||
self.env = {}
|
||||
self.env.startPos = {}
|
||||
@@ -155,7 +155,7 @@ function Game:update(dt)
|
||||
self.player,
|
||||
futurePosX + futureVelX,
|
||||
futurePosY + futureVelY,
|
||||
function(item, other)
|
||||
function (item, other)
|
||||
if other.isEndPos then
|
||||
return 'cross'
|
||||
end
|
||||
@@ -185,7 +185,7 @@ function Game:draw()
|
||||
love.graphics.setShader(self.shaders.light)
|
||||
|
||||
-- Draw Camera view
|
||||
self.camera:draw(function(l, t, w, h)
|
||||
self.camera:draw(function (l, t, w, h)
|
||||
-- Walls
|
||||
for _, wall in ipairs(self.env.walls) do
|
||||
love.graphics.draw(wall.texture, wall.pos.x, wall.pos.y)
|
||||
@@ -193,12 +193,12 @@ function Game:draw()
|
||||
|
||||
-- End
|
||||
love.graphics.setColor(0.88, 0.22, 0.22)
|
||||
love.graphics.rectangle("fill", self.env.endPos.x, self.env.endPos.y, TILE_SIZE, TILE_SIZE)
|
||||
love.graphics.rectangle('fill', self.env.endPos.x, self.env.endPos.y, TILE_SIZE, TILE_SIZE)
|
||||
|
||||
-- Player
|
||||
-- love.graphics.draw(self.player.texture, self.player.pos.x, self.player.pos.y)
|
||||
love.graphics.setColor(0.31, 0.61, 0.76)
|
||||
love.graphics.rectangle("fill", self.player.pos.x, self.player.pos.y, self.player.size.w, self.player.size.h)
|
||||
love.graphics.rectangle('fill', self.player.pos.x, self.player.pos.y, self.player.size.w, self.player.size.h)
|
||||
end)
|
||||
|
||||
-- Draw HUD view
|
||||
@@ -207,12 +207,12 @@ function Game:draw()
|
||||
end
|
||||
|
||||
function Game:resize(w, h)
|
||||
self.shaders.crt:send("resolution", { w, h })
|
||||
self.shaders.crt:send('resolution', { w, h })
|
||||
end
|
||||
|
||||
function Game:_updateLightShader()
|
||||
self.shaders.light:send(
|
||||
"player_pos",
|
||||
'player_pos',
|
||||
{
|
||||
self.camera:toScreen(
|
||||
self.player.pos.x + (self.player.size.w / 2),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local LoveNode = require "src.utils.love_node"
|
||||
local LoveNode = require 'src.utils.love_node'
|
||||
local component = require 'packages.badr'
|
||||
local button = require 'src.display.components.button'
|
||||
local label = require 'src.display.components.label'
|
||||
@@ -57,10 +57,10 @@ end
|
||||
|
||||
function MainMenu:_createMain(settings, credits)
|
||||
local main = component { column = true, gap = 10 }
|
||||
+ button { text = 'New game', width = 200, onClick = function() self.core:switchState(self.core.states.game) end }
|
||||
+ button { text = 'Settings', width = 200, onClick = function() self:_pushScreen(settings) end }
|
||||
+ button { text = 'Credits', width = 200, onClick = function() self:_pushScreen(credits) end }
|
||||
+ button { text = 'Quit', width = 200, onClick = function() love.event.quit() end }
|
||||
+ button { text = 'New game', width = 200, onClick = function () self.core:switchState(self.core.states.game) end }
|
||||
+ button { text = 'Settings', width = 200, onClick = function () self:_pushScreen(settings) end }
|
||||
+ button { text = 'Credits', width = 200, onClick = function () self:_pushScreen(credits) end }
|
||||
+ button { text = 'Quit', width = 200, onClick = function () love.event.quit() end }
|
||||
main:updatePosition(
|
||||
love.graphics.getWidth() * 0.5 - main.width * 0.5,
|
||||
love.graphics.getHeight() * 0.5 - main.height * 0.5
|
||||
@@ -72,7 +72,7 @@ end
|
||||
function MainMenu:_createSettings()
|
||||
local settings = component { column = true, gap = 10 }
|
||||
+ label { text = 'Settings' }
|
||||
+ button { text = 'Back', width = 200, onClick = function() self:_popScreen() end }
|
||||
+ button { text = 'Back', width = 200, onClick = function () self:_popScreen() end }
|
||||
settings:updatePosition(
|
||||
love.graphics.getWidth() * 0.5 - settings.width * 0.5,
|
||||
love.graphics.getHeight() * 0.5 - settings.height * 0.5
|
||||
@@ -84,7 +84,7 @@ end
|
||||
function MainMenu:_createCredits()
|
||||
local credits = component { column = true, gap = 10 }
|
||||
+ label { text = 'Credits' }
|
||||
+ button { text = 'Back', width = 200, onClick = function() self:_popScreen() end }
|
||||
+ button { text = 'Back', width = 200, onClick = function () self:_popScreen() end }
|
||||
credits:updatePosition(
|
||||
love.graphics.getWidth() * 0.5 - credits.width * 0.5,
|
||||
love.graphics.getHeight() * 0.5 - credits.height * 0.5
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local LoveNode = require "src.utils.love_node"
|
||||
local LoveNode = require 'src.utils.love_node'
|
||||
|
||||
|
||||
local PauseMenu = {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local gamera = require "packages.gamera"
|
||||
local gamera = require 'packages.gamera'
|
||||
|
||||
local Camera = {}
|
||||
Camera.__index = Camera
|
||||
|
||||
@@ -9,7 +9,7 @@ local function Hex(hex, value)
|
||||
value or 1 }
|
||||
end
|
||||
|
||||
return function(props)
|
||||
return function (props)
|
||||
local font = props.font or love.graphics.getFont()
|
||||
local padding = {
|
||||
horizontal = (props.leftPadding or 12) + (props.rightPadding or 12),
|
||||
@@ -47,7 +47,7 @@ return function(props)
|
||||
onHover = props.onHover,
|
||||
disabled = props.disabled or false,
|
||||
hoverCalled = false,
|
||||
onUpdate = function(self)
|
||||
onUpdate = function (self)
|
||||
if love.mouse.isDown(1) then
|
||||
if self.mousePressed == false and self:isMouseInside() and self.parent.visible then
|
||||
self.mousePressed = true
|
||||
@@ -58,7 +58,7 @@ return function(props)
|
||||
end
|
||||
end,
|
||||
--
|
||||
draw = function(self)
|
||||
draw = function (self)
|
||||
if not self.visible then return love.mouse.setCursor() end
|
||||
love.graphics.push()
|
||||
love.graphics.rotate(self.angle)
|
||||
@@ -69,18 +69,18 @@ return function(props)
|
||||
love.graphics.setColor(self.borderColor)
|
||||
love.graphics.setLineWidth(self.borderWidth)
|
||||
love.graphics.rectangle('line', self.x, self.y, self.width, self.height, self.cornerRadius)
|
||||
love.graphics.setColor({ 0, 0, 0 })
|
||||
love.graphics.setColor { 0, 0, 0 }
|
||||
end
|
||||
--
|
||||
love.graphics.setColor({
|
||||
love.graphics.setColor {
|
||||
self.backgroundColor[1],
|
||||
self.backgroundColor[2],
|
||||
self.backgroundColor[3],
|
||||
self.opacity })
|
||||
self.opacity }
|
||||
-- hover
|
||||
if self:isMouseInside() then
|
||||
if self.onHover and not self.hoverCalled then
|
||||
--* onHover return a 'clean up' callback
|
||||
-- * onHover return a 'clean up' callback
|
||||
self.onMouseExit = self.onHover(self)
|
||||
self.hoverCalled = true
|
||||
end
|
||||
@@ -99,7 +99,7 @@ return function(props)
|
||||
love.graphics.setColor(self.textColor[1], self.textColor[2], self.textColor[3], self.opacity)
|
||||
love.graphics.printf(self.text, self.x + self.leftPadding, self.y + self.topPadding,
|
||||
self.width - padding.horizontal, 'center')
|
||||
love.graphics.setColor({ 1, 1, 1 })
|
||||
love.graphics.setColor { 1, 1, 1 }
|
||||
love.graphics.pop()
|
||||
end
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ local function label(options)
|
||||
height = _font:getHeight(),
|
||||
onClick = options.onClick or nil,
|
||||
font = _font,
|
||||
draw = function(self)
|
||||
draw = function (self)
|
||||
if not self.visible then return end
|
||||
love.graphics.setFont(self.font)
|
||||
love.graphics.setColor({
|
||||
love.graphics.setColor {
|
||||
color[1], color[2], color[3], options.opacity
|
||||
})
|
||||
}
|
||||
love.graphics.print(self.text, self.x, self.y)
|
||||
love.graphics.setColor({ 1, 1, 1 })
|
||||
love.graphics.setColor { 1, 1, 1 }
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local rs = require "packages.resolution_solution"
|
||||
local rs = require 'packages.resolution_solution'
|
||||
|
||||
local Display = {}
|
||||
Display.__index = Display
|
||||
@@ -12,26 +12,26 @@ function Display.new(virtualWidth, virtualHeight)
|
||||
self.virtualWidth = virtualWidth
|
||||
self.virtualHeight = virtualHeight
|
||||
|
||||
love.graphics.setDefaultFilter("nearest", "nearest")
|
||||
love.graphics.setDefaultFilter('nearest', 'nearest')
|
||||
|
||||
rs.conf({
|
||||
rs.conf {
|
||||
game_width = virtualWidth,
|
||||
game_height = virtualHeight,
|
||||
scale_mode = rs.PIXEL_PERFECT_MODE
|
||||
})
|
||||
}
|
||||
rs.setMode(rs.game_width, rs.game_height, { resizable = true })
|
||||
|
||||
self.gameCanvas = love.graphics.newCanvas(rs.get_game_size())
|
||||
|
||||
self.isFullscreen = false
|
||||
love.window.setFullscreen(self.isFullscreen, "desktop")
|
||||
love.window.setFullscreen(self.isFullscreen, 'desktop')
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Display:toggleFullscreen()
|
||||
self.isFullscreen = not self.isFullscreen
|
||||
love.window.setFullscreen(self.isFullscreen, "desktop")
|
||||
love.window.setFullscreen(self.isFullscreen, 'desktop')
|
||||
end
|
||||
|
||||
--- Resizes the game resolution.
|
||||
|
||||
@@ -18,7 +18,7 @@ local function initialize_grid(width, height)
|
||||
for y = 1, height do
|
||||
grid[y] = {}
|
||||
for x = 1, width do
|
||||
grid[y][x] = "wall"
|
||||
grid[y][x] = 'wall'
|
||||
end
|
||||
end
|
||||
return grid
|
||||
@@ -45,8 +45,8 @@ local function generate_maze(width, height)
|
||||
local wall_list = {}
|
||||
|
||||
-- Choose a random starting cell within the inner grid and mark it as a passage
|
||||
local start_x, start_y = 2, 2 --math.random(2, width - 1), math.random(2, height - 1)
|
||||
grid[start_y][start_x] = "passage"
|
||||
local start_x, start_y = 2, 2 -- math.random(2, width - 1), math.random(2, height - 1)
|
||||
grid[start_y][start_x] = 'passage'
|
||||
|
||||
-- Add its neighboring walls to the wall list
|
||||
for _, neighbor in ipairs(get_neighbors(start_x, start_y, width, height)) do
|
||||
@@ -63,10 +63,10 @@ local function generate_maze(width, height)
|
||||
local nx, ny = 2 * wall.x - wall.wx, 2 * wall.y - wall.wy
|
||||
|
||||
-- Check if the opposite cell is within inner grid bounds and is a wall
|
||||
if nx > 1 and nx < width and ny > 1 and ny < height and grid[ny][nx] == "wall" then
|
||||
if nx > 1 and nx < width and ny > 1 and ny < height and grid[ny][nx] == 'wall' then
|
||||
-- Make the wall a passage
|
||||
grid[wall.y][wall.x] = "passage"
|
||||
grid[ny][nx] = "passage"
|
||||
grid[wall.y][wall.x] = 'passage'
|
||||
grid[ny][nx] = 'passage'
|
||||
|
||||
-- Add the neighboring walls of the newly added cell to the wall list
|
||||
for _, neighbor in ipairs(get_neighbors(nx, ny, width, height)) do
|
||||
|
||||
@@ -3,7 +3,7 @@ local mazeutils = {}
|
||||
function mazeutils.getStartingPosition(maze)
|
||||
for y = 1, #maze do
|
||||
for x = 1, #maze[1] do
|
||||
if maze[y][x] == "passage" then
|
||||
if maze[y][x] == 'passage' then
|
||||
return x, y
|
||||
end
|
||||
end
|
||||
@@ -13,7 +13,7 @@ end
|
||||
function mazeutils.getEndingPosition(maze)
|
||||
for y = #maze, 1, -1 do
|
||||
for x = #maze[1], 1, -1 do
|
||||
if maze[y][x] == "passage" then
|
||||
if maze[y][x] == 'passage' then
|
||||
return x, y
|
||||
end
|
||||
end
|
||||
|
||||
7
todo.md
7
todo.md
@@ -1,9 +1,14 @@
|
||||
# backlog
|
||||
|
||||
- [x] Replace physics with Bump
|
||||
- [ ] Yield maze generation steps using coroutines
|
||||
- [ ] Speed up maze generation
|
||||
|
||||
# in progress
|
||||
|
||||
- [ ] Make light shader grow and shrink by player action
|
||||
|
||||
# complete
|
||||
|
||||
- [x] Set up Lua formatter
|
||||
- [x] Replace physics with Bump
|
||||
- [x] Light shader
|
||||
|
||||
Reference in New Issue
Block a user