234 lines
6.2 KiB
Lua
234 lines
6.2 KiB
Lua
love.graphics.setDefaultFilter("linear", "nearest")
|
|
|
|
local utf8 = require("utf8")
|
|
class = require "libs/middleclass"
|
|
Timer = require "libs/hump/timer"
|
|
sfxr = require "libs/sfxrlua/sfxr"
|
|
require "libs/TSerial"
|
|
require "_debug_helpers"
|
|
require "_helpers"
|
|
require "input"
|
|
require "color"
|
|
require "room"
|
|
require "world"
|
|
require "world_seed"
|
|
require "shaders"
|
|
require "level_editor/editor"
|
|
|
|
-- Ink dialogue: ship the pre-parsed book (LÖVE has no lpeg to parse .ink at
|
|
-- runtime; the narrator parser degrades to false without it, runtime is fine).
|
|
package.path = package.path .. ";libs/narrator/?.lua"
|
|
narrator = require "narrator.narrator"
|
|
startSignBook = require "stories.start_sign"
|
|
|
|
function love.load()
|
|
globalAssetProperties = {} -- rebuilt from the filesystem (art/ + .meta) by getAllAssets
|
|
|
|
_initDefaults()
|
|
_initGridVars()
|
|
_initSounds()
|
|
_initGlobalColors()
|
|
gameWorld = World:new()
|
|
_initLevelEditor()
|
|
|
|
_initCanvases()
|
|
|
|
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",
|
|
runtime = true
|
|
}
|
|
gameWorld:setLastRoom(currentRoom.name)
|
|
setEditorRoomName(currentRoom.name)
|
|
|
|
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()
|
|
else
|
|
local repeatedMove = Input:handler(dt)
|
|
if repeatedMove and not Dialogue.isOpen() then currentRoom:movePlayer(repeatedMove) end
|
|
end
|
|
currentRoom:update(dt)
|
|
|
|
-- if love.keyboard.isDown("w") then worldSha = worldSha + 1 end
|
|
-- if love.keyboard.isDown("s") then worldSha = worldSha - 1 end
|
|
end
|
|
|
|
function love.draw()
|
|
love.graphics.setCanvas(gameCanvas)
|
|
love.graphics.clear()
|
|
love.graphics.setBlendMode("screen")
|
|
if editorView == "world" then
|
|
gameWorld:draw()
|
|
else
|
|
currentRoom:draw()
|
|
end
|
|
|
|
love.graphics.setCanvas(finalCanvas)
|
|
love.graphics.clear()
|
|
|
|
local scaleCoefficient = .93
|
|
local samples = 7
|
|
|
|
love.graphics.push()
|
|
|
|
for i = 1, samples do
|
|
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)
|
|
love.graphics.draw(gameCanvas, 0, 0)
|
|
end
|
|
|
|
love.graphics.pop()
|
|
love.graphics.setColor(1, 1, 1)
|
|
love.graphics.draw(gameCanvas, 0, 0)
|
|
love.graphics.setCanvas()
|
|
|
|
love.graphics.setCanvas(sideBarCanvas)
|
|
love.graphics.clear()
|
|
editorDraw()
|
|
love.graphics.setCanvas()
|
|
|
|
love.graphics.setBlendMode("alpha")
|
|
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)
|
|
|
|
Dialogue.draw()
|
|
end
|
|
|
|
function love.keypressed(key)
|
|
-- Talking to a sign captures input: navigate/choose, don't move the player.
|
|
if Dialogue.isOpen() then
|
|
Dialogue.keypressed(key)
|
|
return
|
|
end
|
|
|
|
if editorView ~= "world" and Input.isPlayerMove(key) then
|
|
Input:beginMove(key)
|
|
currentRoom:movePlayer(key)
|
|
elseif editorView ~= "world" and Input.isPlayerSwitch(key) then
|
|
local c = Input.playerColor(key)
|
|
currentRoom:switchPlayerColor(c)
|
|
end
|
|
|
|
-- if key == "w" then
|
|
-- worldSha = worldSha + 1
|
|
-- end
|
|
-- if key == "s" then
|
|
-- worldSha = worldSha - 1
|
|
-- end
|
|
|
|
if key == "return" then
|
|
response = ""
|
|
editorCompleteResponse()
|
|
elseif key == "backspace" then
|
|
local byteoffset = utf8.offset(response, -1)
|
|
|
|
if byteoffset then
|
|
-- remove the last UTF-8 character.
|
|
-- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(response, 1, -2).
|
|
response = string.sub(response, 1, byteoffset - 1)
|
|
editorTextHandler(response)
|
|
end
|
|
end
|
|
end
|
|
|
|
function love.mousepressed(x, y, button)
|
|
if editorView == "room" and button == 2 then
|
|
currentRoom:attemptDelete(x, y, selectedColor)
|
|
end
|
|
editorMouseHandler(x, y, button)
|
|
end
|
|
|
|
function love.textinput(t)
|
|
response = response .. t
|
|
editorTextHandler(response)
|
|
end
|
|
|
|
function love.resize(w, h)
|
|
_computeDimensions()
|
|
drawScale = width / gridWidth / 16
|
|
_initCanvases()
|
|
end
|
|
|
|
function _initDefaults()
|
|
--set filter
|
|
love.graphics.setDefaultFilter("linear", "nearest")
|
|
love.filesystem.createDirectory("rooms")
|
|
|
|
--set global width / height / sidebar variables
|
|
_computeDimensions()
|
|
|
|
--set randomseed
|
|
math.randomseed(os.time())
|
|
|
|
--font
|
|
font = love.graphics.newFont("font/LCD_Solid.ttf", 16)
|
|
love.graphics.setFont(font)
|
|
end
|
|
|
|
-- Derive the square play area (side = smaller window dimension) and the
|
|
-- sidebar that fills the remaining horizontal space. Safe to call any time
|
|
-- the window size changes.
|
|
function _computeDimensions()
|
|
width = love.graphics.getWidth()
|
|
height = love.graphics.getHeight()
|
|
if width > height then
|
|
width = height
|
|
else
|
|
height = width
|
|
end
|
|
|
|
sideBarBox = {x = width, y = 0, w = love.graphics.getWidth() - width, h = height}
|
|
end
|
|
|
|
-- (Re)create the render targets at the current window size.
|
|
function _initCanvases()
|
|
gameCanvas = love.graphics.newCanvas()
|
|
finalCanvas = love.graphics.newCanvas()
|
|
sideBarCanvas = love.graphics.newCanvas(math.max(1, sideBarBox.w), math.max(1, sideBarBox.h))
|
|
end
|
|
|
|
function _initGridVars()
|
|
gridWidth, gridHeight = 11, 11
|
|
drawScale = width / gridWidth / 16
|
|
|
|
worldSha = 1
|
|
end
|
|
|
|
function _initGlobalColors()
|
|
gColor = {}
|
|
gColor.red, gColor.green, gColor.blue, gColor.white = Color:new("red"), Color:new("green"), Color:new("blue"), Color:new("white")
|
|
end
|
|
|
|
function _initSounds()
|
|
staticWave = sfxr.newSound()
|
|
staticWave.wavetype = 3
|
|
staticWave.frequency.start = .1
|
|
staticWave.envelope.release = 0
|
|
staticWave.envelope.sustain = 1
|
|
staticWave.envelope.decay = 0
|
|
static = love.audio.newSource((staticWave:generateSoundData()))
|
|
static:setLooping(true)
|
|
static:setVolume(.15)
|
|
static:play()
|
|
end
|