fix state thigns and port to love11

This commit is contained in:
Your Name 2026-08-07 20:56:42 -04:00
parent ff5abf6bcd
commit c92c0f6ff7
11 changed files with 130 additions and 96 deletions

View file

@ -58,7 +58,8 @@ function clearRuntimeSaveData(roomName)
end
local function removeTree(path)
if love.filesystem.isDirectory(path) then
local info = love.filesystem.getInfo(path)
if info and info.type == "directory" then
for _, child in ipairs(love.filesystem.getDirectoryItems(path)) do
removeTree(path .. "/" .. child)
end
@ -109,16 +110,18 @@ function cellShapeFromBox(box)
return cells
end
-- Which 16x16 cells of a sprite are non-empty, for multi-cell collision shapes.
function getCellsFromSprite(sprite)
local w, h = sprite:getWidth(), sprite:getHeight()
-- Which 16x16 cells of an image are non-empty, for multi-cell collision
-- shapes. LÖVE 11 no longer exposes Image:getData(), so inspect ImageData
-- directly instead of creating a GPU Image first.
function getCellsFromSprite(spritePath)
local img = love.image.newImageData(spritePath)
local w, h = img:getWidth(), img:getHeight()
local box = {w = w / 16, h = h / 16}
local boxCells = cellShapeFromBox(box)
if box.w < 1 or box.h < 1 then
return boxCells
end
local img = sprite:getData()
local cellsToRemove = {}
for _, cell in pairs(boxCells) do

View file

@ -4,10 +4,11 @@
Color = class("Color")
Color.static.list = {
red = {r = 255, g = 0, b = 0, a = 255},
green = {r = 0, g = 255, b = 0, a = 255},
blue = {r = 0, g = 0, b = 255, a = 255},
white = {r = 255, g = 255, b = 255, a = 255}
-- LÖVE 11 represents color components as normalized floats, not bytes.
red = {r = 1, g = 0, b = 0, a = 1},
green = {r = 0, g = 1, b = 0, a = 1},
blue = {r = 0, g = 0, b = 1, a = 1},
white = {r = 1, g = 1, b = 1, a = 1}
}
function Color:initialize(inColor)
@ -27,4 +28,4 @@ end
function randomColor()
local colors = {"red", "green", "blue"}
return colors[math.random(1, 3)]
end
end

View file

@ -1,8 +1,12 @@
function love.conf(t)
-- This project uses the normalized-color and ImageData APIs introduced in
-- LÖVE 11. Pinning the intended runtime also gives a useful warning when a
-- player tries to launch it with an older installation.
t.version = "11.5"
t.window.width = 900
t.window.height = 640
t.window.title = "CHROMA SOLSTICE"
t.window.resizable = true
t.window.minwidth = 700
t.window.minheight = 500
end
end

View file

@ -136,14 +136,14 @@ local function drawWorldSidebar()
love.graphics.rectangle("line", worldSearchBox.x, worldSearchBox.y, worldSearchBox.w, worldSearchBox.h)
love.graphics.printf("SEARCH: " .. worldSearchText, worldSearchBox.x + 6, worldSearchBox.y + 7, worldSearchBox.w - 12, "left")
for _, button in ipairs(worldRoomButtons) do
love.graphics.setColor(button.name == selectedRoom and 255 or 100, button.name == selectedRoom and 255 or 100, button.name == selectedRoom and 255 or 100, 255)
love.graphics.setColor(button.name == selectedRoom and 1 or 100 / 255, button.name == selectedRoom and 1 or 100 / 255, button.name == selectedRoom and 1 or 100 / 255, 1)
love.graphics.rectangle("line", button.x, button.y, button.w, button.h)
gameWorld:drawRoomPreview(button.name, button.x + 4, button.y + 4, button.h - 8)
love.graphics.setColor(gColor.white:set())
love.graphics.printf(button.name, button.x + button.h + 4, button.y + 21, button.w - button.h - 8, "left")
end
for _, control in ipairs(worldControls) do
love.graphics.setColor(255, 255, 255, 255)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.rectangle("line", control.x, control.y, control.w, control.h)
love.graphics.printf(control.text, control.x, control.y + 9, control.w, "center")
end

View file

@ -1,6 +1,6 @@
GUI = class("level_editor/gui")
GUI.static.pressSound = love.audio.newSource("sounds/ui/button.wav")
GUI.static.pressSound = love.audio.newSource("sounds/ui/button.wav", "static")
GUI.static.defaultCallbac = function() print("this button has not been configured") end

View file

@ -34,7 +34,7 @@ function getAllAssets()
-- class comes from a <name>.meta sitting next to the art
-- (authoritative); default to immoveable if none exists
local metaPath = topFolder .. "/" .. folder .. "/" .. name .. ".meta"
if love.filesystem.exists(metaPath) then
if love.filesystem.getInfo(metaPath, "file") then
globalAssetProperties[name].class = TSerial.unpack(love.filesystem.read(metaPath)).class
elseif not globalAssetProperties[name].class then
globalAssetProperties[name].class = "immoveable"
@ -45,7 +45,7 @@ function getAllAssets()
if not globalAssetProperties[name].cells or reanalyzeCells then
globalAssetProperties[name].cells = {}
globalAssetProperties[name].cells[color] = getCellsFromSprite(love.graphics.newImage(sprite))
globalAssetProperties[name].cells[color] = getCellsFromSprite(sprite)
end
end
end
@ -54,4 +54,4 @@ function getAllAssets()
end
return globalAssetProperties
end
end

View file

@ -29,8 +29,12 @@ function love.load()
inputTimer = Timer.new()
-- Resume the game: prefer the runtime autosave so the last saved position is
-- restored, falling back to the authored source level. Editor room-opens go
-- through their own (source-only) load path, so this only affects resume.
currentRoom = Room:new{
name = gameWorld.lastRoom or "start"
name = gameWorld.lastRoom or "start",
runtime = true
}
gameWorld:setLastRoom(currentRoom.name)
setEditorRoomName(currentRoom.name)
@ -38,6 +42,15 @@ function love.load()
response = ""
end
-- Autosave on close so a position reached by moving within a room (short of a
-- room-to-room transition, which already autosaves in nextRoom) survives.
function love.quit()
if currentRoom then
currentRoom:save()
if gameWorld then gameWorld:setLastRoom(currentRoom.name) end
end
end
function love.update(dt)
if editorView == "world" then
Input:stopMoveRepeat()
@ -70,7 +83,7 @@ function love.draw()
love.graphics.push()
for i = 1, samples do
local c = 65 / (i * 1.75)
local c = 65 / 255 / (i * 1.75)
love.graphics.setColor(c, c, c)
love.graphics.scale(scaleCoefficient, scaleCoefficient)
love.graphics.translate((width / 2 - (width * scaleCoefficient) / 2) + 2, (width / 2 - (height * scaleCoefficient) / 2) + 2)
@ -78,7 +91,7 @@ function love.draw()
end
love.graphics.pop()
love.graphics.setColor(255, 255, 255)
love.graphics.setColor(1, 1, 1)
love.graphics.draw(gameCanvas, 0, 0)
love.graphics.setCanvas()
@ -88,7 +101,7 @@ function love.draw()
love.graphics.setCanvas()
love.graphics.setBlendMode("alpha")
love.graphics.setColor(255, 255, 255, 255)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(finalCanvas, 0, 0)
love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y)
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)

View file

@ -3,8 +3,8 @@ require "entity"
Player = class("Player", Entity)
Player.static.sounds = {
switchFail = love.audio.newSource("sounds/switch_fail.wav"),
switchSuccess = love.audio.newSource("sounds/switch_success.wav")
switchFail = love.audio.newSource("sounds/switch_fail.wav", "static"),
switchSuccess = love.audio.newSource("sounds/switch_success.wav", "static")
}
function Player:initialize(x, y, color)

View file

@ -130,7 +130,7 @@ function Room:draw()
-- npcs (old "sages") are markers for now: a "?" tinted to the player's channels
local cellW, cellH = width / gridWidth, height / gridHeight
love.graphics.setColor(has.red and 255 or 0, has.green and 255 or 0, has.blue and 255 or 0)
love.graphics.setColor(has.red and 1 or 0, has.green and 1 or 0, has.blue and 1 or 0)
for _, npc in ipairs(self.npcs) do
love.graphics.print("?", (npc.x - 1) * cellW + cellW * 0.3, (npc.y - 1) * cellH + cellH * 0.1, 0, 2, 2)
end
@ -698,6 +698,12 @@ end
function Room:deserialize(saveTable)
for _, obj in ipairs(saveTable.objects or {}) do
self:createEntity(obj.class, obj.color, obj.x, obj.y)
-- createEntity turns every loaded player on; honour a saved active flag so
-- copies that were off at save time stay off (older savs lack the field and
-- keep the old all-on behaviour).
if obj.class == "player" and obj.active ~= nil then
self:setActiveColor(obj.color, obj.active)
end
end
end
@ -752,7 +758,14 @@ function Room:serialize(includePlayers)
if includePlayers ~= false then
for color, player in pairs(self.player) do
emit("player", color, player)
local pos = player:getGridPos()
-- Persist which copies were active so a resume restores exactly the
-- channels that were on at save time. A colour deactivated during play
-- (see playerJoinCheck) must come back as an inactive copy, not turn on.
table.insert(objects, {
class = "player", color = color, x = pos.x, y = pos.y,
active = self.activeColors[color] and true or false,
})
end
end

View file

@ -1,152 +1,152 @@
{
width=18,
height=18,
rooms={
{
x=9,
name="start",
y=11
y=11,
x=9
},
{
x=10,
name="3",
y=10
y=10,
x=10
},
{
x=11,
name="4",
y=10
},
{
x=12,
name="5",
y=10
y=10,
x=12
},
{
x=12,
name="village_1",
y=9
y=9,
x=12
},
{
x=12,
name="village_2",
y=8
y=8,
x=12
},
{
x=13,
name="village_3",
y=8
y=8,
x=13
},
{
x=11,
name="village_4",
y=8
y=8,
x=11
},
{
x=11,
name="yellow_1",
y=7
y=7,
x=11
},
{
x=11,
name="yellow_3",
y=6
y=6,
x=11
},
{
x=12,
name="yellow_2",
y=7
y=7,
x=12
},
{
x=11,
name="yellow_4",
y=5
y=5,
x=11
},
{
x=11,
name="yellow_5",
y=4
y=4,
x=11
},
{
x=10,
name="yellow_6",
y=5
y=5,
x=10
},
{
x=1,
name="default",
y=1
y=1,
x=1
},
{
x=3,
name="old_yellow_3",
y=1
y=1,
x=3
},
{
x=5,
name="test_patt",
y=1
y=1,
x=5
},
{
x=7,
name="test_patt_update",
y=1
y=1,
x=7
},
{
x=9,
name="white_asymmetrical",
y=1
y=1,
x=9
},
{
x=11,
name="white_ok",
y=1
y=1,
x=11
},
{
x=13,
name="white_primary",
y=1
y=1,
x=13
},
{
x=15,
name="yellow_arches",
y=1
y=1,
x=15
},
{
x=17,
name="yellow_asymmetrical",
y=1
y=1,
x=17
},
{
x=1,
name="yellow_cc_moustache",
y=3
y=3,
x=1
},
{
x=3,
name="yellow_color_changing_levvel_1",
y=3
y=3,
x=3
},
{
x=5,
name="yellow_skull",
y=3
},
{
x=7,
name="yellow_smile",
y=3
y=3,
x=7
},
{
x=9,
name="2",
y=10
y=10,
x=9
},
{
x=11,
name="room_11_09",
y=9
y=9,
x=11
},
{
name="4",
y=3,
x=5
},
{
name="yellow_skull",
y=3,
x=9
}
},
lastRoom="yellow_skull"
}
lastRoom="start",
width=18,
height=18
}

View file

@ -156,7 +156,7 @@ function World:drawRoomPreview(name, x, y, size)
love.graphics.setScissor(x, y, size, size)
for _, object in ipairs(room.objects or {}) do
if object.class == "npc" then
love.graphics.setColor(255, 255, 255, 255)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.print("?", x + (object.x - 1) * 16 * scale, y + (object.y - 1) * 16 * scale, 0, scale, scale)
else
local props = globalAssetProperties[object.class]
@ -182,14 +182,14 @@ end
function World:draw()
local cell = width / self.width
love.graphics.setColor(12, 12, 20, 255)
love.graphics.setColor(12 / 255, 12 / 255, 20 / 255, 1)
love.graphics.rectangle("fill", 0, 0, width, height)
for y = 1, self.height do
for x = 1, self.width do
local screenX, screenY = (x - 1) * cell, (y - 1) * cell
local name = self:roomAt(x, y)
if name then self:drawRoomPreview(name, screenX, screenY, cell) end
love.graphics.setColor(name and 255 or 70, name and 255 or 70, name and 255 or 90, 255)
love.graphics.setColor(name and 1 or 70 / 255, name and 1 or 70 / 255, name and 1 or 90 / 255, 1)
love.graphics.rectangle("line", screenX, screenY, cell, cell)
end
end