Compare commits

..

23 Commits

Author SHA1 Message Date
binarycat
577b7576cf added level in new format to repo 2022-03-16 14:21:35 -04:00
binarycat
fa4b2c86b5 somewhat kinda got things working again 2022-03-16 13:54:25 -04:00
binarycat
e8cef497d4 reworking level loading logic 2022-03-16 13:54:25 -04:00
binarycat
b3a12305da trying to do chunked level loading 2022-03-16 13:54:24 -04:00
lustlion
236e23177d function to improve entities moving on collisions and fixed accordingly
made math.round()
changed vector() and fixed accordingly
2022-03-16 18:50:10 +01:00
binarycat
4d94cc805d serialization function 2022-03-15 20:16:35 -04:00
lustlion
9c4b5431ee fix adjusting select to camera 2022-03-13 10:47:17 +01:00
lustlion
ba1c0f0c89 getPoints and getCoords 2022-03-13 10:43:07 +01:00
lustlion
ef632d50ee multiselecting entities! 2022-03-13 10:38:20 +01:00
lustlion
5bcf25a461 fix typos and functions 2022-03-13 10:36:19 +01:00
lustlion
1039479c47 Keybinds can be occupied (when being checked down) 2022-03-13 09:57:44 +01:00
lustlion
62555b4526 improvement to moveSpawns so it can move multiple spawns correctly 2022-03-13 09:42:35 +01:00
lustlion
a4af57ca6c cleanup useless function 2022-03-13 09:34:34 +01:00
binarycat
5189bef537 cleanup 2022-03-12 14:06:55 -05:00
binarycat
eab4cbbcdc use Rect:containsPoint in isThereObjectAt 2022-03-12 13:56:16 -05:00
binarycat
829963e080 add Rect, begin work on multiselect 2022-03-12 13:17:52 -05:00
binarycat
82246dc0c6 multiselect region can be drawn with the right mouse button 2022-03-12 13:16:39 -05:00
lustlion
3a5e0b395b fix indentation and cleaning 2022-03-12 18:28:35 +01:00
lustlion
feed65cf6d floored coords when adding or moving entity spawns 2022-03-12 18:20:25 +01:00
lustlion
1883bcd78b drawTextBox to use style table instead of a lot of arguments 2022-03-12 18:20:06 +01:00
lustlion
3c1746d914 particles time to be handled in frames instead of seconds optionally 2022-03-12 18:19:07 +01:00
binarycat
f091fba9f7 change editor_mode to editor.active, minor refactor, and start work on multiselect 2022-03-12 11:46:45 -05:00
binarycat
27f1dc71c0 added Rect class 2022-03-12 11:12:29 -05:00
29 changed files with 603 additions and 332 deletions

View File

@@ -77,3 +77,16 @@ function Camera:positionAt(x,y)
self.pos.y = math.floor((y/self.height)*self.height) self.pos.y = math.floor((y/self.height)*self.height)
end end
-- translate screen coordinates to game coordinates
function Camera:ptScreenToGame(pt)
return self.pos + pt
end
function Camera:mouseScreenPos()
return Point:new(love.mouse.getX(),love.mouse.getY()) / game.scale
end
-- return the mouse position as game coordinates
function Camera:mouseGamePos()
return self:ptScreenToGame(self:mouseScreenPos())
end

51
code/chunk.lua Normal file
View File

@@ -0,0 +1,51 @@
-- pieces of levels
Chunk = {all = {}}
Chunk.__index = Chunk
-- CLASS METHODS
-- box == nil for global chunks
function Chunk:new(filename, box)
local o = { filename = filename, box = box }
setmetatable(o, self)
self.all[o] = true
end
function Chunk:getExportList()
local r = {}
for chunk in pairs(self.all) do
table.insert(r, {chunk.filename, chunk.box})
end
return r
end
-- INSTANCE METHODS
function Chunk:containsPoint(pt)
return self.box == nil or self.box:containsPoint(pt)
end
function Chunk:load()
if self.loaded then
return
end
logPrint("loading chunk "..self.filename)
self.data = dofile(level_current.."/chunks/"..self.filename)
self.loaded = { rooms = {}, collisions = {} }
LevelTiles = self.data.tiles
indexLevelTiles()
optimizeTileObjects(self.loaded.collisions)
for _, v in ipairs(self.data.rooms or {}) do
local room = Collision:new(v[1],v[2],v[3],v[4])
table.insert(self.data.rooms, room)
table.insert(LoadedObjects.Rooms, room)
end
logPrint("loaded chunk with "..#self.loaded.collisions.." collisions")
end
function Chunk:save(chunkdir)
return love.filesystem.write(chunkdir.."/"..self.filename, "return "..serialize_lua_value(self.data))
end

View File

@@ -88,3 +88,7 @@ function Collision:draw(color)
love.graphics.setColor(0,1,90,0.5) love.graphics.setColor(0,1,90,0.5)
love.graphics.rectangle("line",self.from.x-Camera.pos.x, self.from.y-Camera.pos.y, self.width, self.height) love.graphics.rectangle("line",self.from.x-Camera.pos.x, self.from.y-Camera.pos.y, self.width, self.height)
end end
function Collision:asRect()
return Rect:fromCoords(self.from.x, self.from.y, self.to.x, self.to.y)
end

View File

@@ -1,17 +1,37 @@
assert(editor == nil) assert(editor == nil)
editor = { editor = {
active = false,
room_mode = false, room_mode = false,
--palette_mode = false,
palette = { palette = {
active = false, active = false,
scroll = Point:new(0, 0), scroll = Point:new(0, 0),
}, },
multiselect = {
active = false,
sweeping = false,
box = nil,
},
pan = { fixed = false, speed = 3 }, pan = { fixed = false, speed = 3 },
} }
function stepEditor() function stepEditor()
animateTiles() animateTiles()
local osweep = editor.multiselect.sweeping
editor.multiselect.sweeping = Keybind:checkDown(Keybind.editor.entity_select)
frameDebug("sweeping: "..tostring(editor.multiselect.sweeping))
if editor.multiselect.sweeping and not editor.multiselect.active then
print("multiselect enabled")
editor.multiselect.active = true
end
if not osweep and osweep ~= editor.multiselect.sweeping then
editor.multiselect.box = nil
end
if editor.multiselect.active then
doEditorMultiselect()
end
if Keybind:checkPressed(Keybind.editor.room_mode) then if Keybind:checkPressed(Keybind.editor.room_mode) then
if love.keyboard.isDown("lshift") then if love.keyboard.isDown("lshift") then
editor.room_mode = "delete" editor.room_mode = "delete"
@@ -80,7 +100,7 @@ function stepEditor()
if name_prompt.canceled then return end if name_prompt.canceled then return end
Prompt:new({ Prompt:new({
name = "filename", name = "filename",
input = "level.lua", input = "unnamed_level",
func = function(file_prompt) func = function(file_prompt)
if file_prompt.canceled then return end if file_prompt.canceled then return end
exportLevel(name_prompt.input, file_prompt.input) exportLevel(name_prompt.input, file_prompt.input)
@@ -89,13 +109,6 @@ function stepEditor()
end, end,
}):activate() }):activate()
end end
if Keybind:checkPressed(Keybind.debug.editor) then
editor_mode = not editor_mode
deselectSpawns()
createTileObjects()
restartGame()
end
end end
function scrollEditor(y) function scrollEditor(y)
@@ -128,6 +141,10 @@ function drawEditor()
if editor.palette.active then if editor.palette.active then
doEditorPalette() doEditorPalette()
end end
if editor.multiselect.box ~= nil then
frameDebug("drawing multiselect "..tostring(editor.multiselect.box))
drawEditorMultiselect()
end
end end
function doEditorEdit() function doEditorEdit()
@@ -204,7 +221,9 @@ function doEditorEdit()
else else
if Keybind:checkDown(Keybind.editor.entity_select) then if Keybind:checkDown(Keybind.editor.entity_select) then
deselectSpawns() deselectSpawns()
selectSpawns(mouse_x,mouse_y) if editor.multiselect.box then
selectSpawns(editor.multiselect.box)
end
end end
if Keybind:checkDown(Keybind.editor.entity_move) then if Keybind:checkDown(Keybind.editor.entity_move) then
moveSpawns(mouse_x,mouse_y) moveSpawns(mouse_x,mouse_y)
@@ -353,7 +372,21 @@ end
function drawEditorRooms() function drawEditorRooms()
for _, room in pairs(LoadedObjects.Rooms) do for _, room in pairs(LoadedObjects.Rooms) do
love.graphics.setColor(0,0,100,1) love.graphics.setColor(0,0,1,1)
love.graphics.rectangle("line",room.from.x-Camera.pos.x, room.from.y-Camera.pos.y, room.width, room.height) room:asRect():draw("line")
end
end
function drawEditorMultiselect()
love.graphics.setColor(0,1,1,1)
editor.multiselect.box:draw("line")
end
function doEditorMultiselect()
local mousept = Camera:mouseGamePos()
if editor.multiselect.box == nil then
editor.multiselect.box = Rect:fromPoints(mousept, mousept)
elseif editor.multiselect.sweeping then
editor.multiselect.box.max = mousept
end end
end end

View File

@@ -36,20 +36,30 @@ function Arrow:drawBackground()
end end
function Arrow:doPhysics() function Arrow:doPhysics()
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then -- horizontal collision
self.pos.x = self.pos.x + self.vel.x self:moveX(
else self.vel.x,
self.stuck = true function()
end self.stuck = true
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then end
self.pos.y = self.pos.y + self.vel.y )
else
self.stuck = true if not self.stuck then
-- vertical collision
self:moveY(
self.vel.y,
function()
self.stuck = true
end
)
end end
if self.stuck then if self.stuck then
self.pos.x = self.pos.x + self.vel.x * (2/3) self.pos.x = self.pos.x + self.vel.x * (2/3)
self.pos.y = self.pos.y + self.vel.y * (2/3) self.pos.y = self.pos.y + self.vel.y * (2/3)
self.vel.x = 0 self.vel.x = 0
self.vel.y = 0 self.vel.y = 0
end end
self:adjustLight()
end end

View File

@@ -67,6 +67,13 @@ function CursedBook:doLogic()
elseif self.status == 4 then elseif self.status == 4 then
end end
if self.isFlying then
local random_x = math.random(-4, 4)/100
local random_y = math.random(-4, 4)/100
self.vel.x = self.vel.x + random_x
self.vel.y = self.vel.y + random_y
end
end end
function CursedBook:handleAnimation() function CursedBook:handleAnimation()
@@ -101,15 +108,21 @@ function CursedBook:handleAnimation()
end end
function CursedBook:doPhysics() function CursedBook:doPhysics()
if self.isFlying then -- horizontal collision
local random_x = math.random(-4, 4)/100 self:moveX(
local random_y = math.random(-4, 4)/100 self.vel.x,
self.vel.x = self.vel.x + random_x function()
self.vel.y = self.vel.y + random_y self.vel.x = 0
end end
-- move )
-- vertical collision
self:moveWithCollision() self:moveY(
self.vel.y,
function()
self.vel.y = 0
end
)
-- final position
self:adjustLight() self:adjustLight()
end end

View File

@@ -34,7 +34,6 @@ function Fairy:new(x,y)
end end
function Fairy:doLogic() function Fairy:doLogic()
if self:checkVisionLine(main_player,self.vision_range) then if self:checkVisionLine(main_player,self.vision_range) then
self.target.x = main_player.pos.x + main_player.target_offset.x self.target.x = main_player.pos.x + main_player.target_offset.x
@@ -63,31 +62,19 @@ function Fairy:doLogic()
local distance_x = self.target.x - self.pos.x local distance_x = self.target.x - self.pos.x
local distance_y = self.target.y - self.pos.y local distance_y = self.target.y - self.pos.y
local angle = getAngleFromVector(distance_x,distance_y) local angle = getAngleFromVector(vector(distance_x,distance_y))
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if distance < self.range then if distance < self.range then
self.vel.x = self.vel.x * 0.9 local random_x = math.random(-1, 1)
self.vel.y = self.vel.y * 0.9 local random_y = math.random(-1, 1)
self.vel.x = self.vel.x * 0.9 + random_x/10
self.vel.y = self.vel.y * 0.9 + random_y/10
else else
self.vel.x = math.cos(angle)*self.speed local random_x = math.random(-6, 6)
self.vel.y = math.sin(angle)*self.speed local random_y = math.random(-6, 6)
end self.vel.x = math.cos(angle)*self.speed + random_x/10
self.particle_timer = self.particle_timer + 1 self.vel.y = math.sin(angle)*self.speed + random_y/10
if self.particle_timer >= self.particle_time then
self.particle_timer = 0
local particle_data = {
animation = animation.particle.simple,
animation_speed = 1,
sprite_tint = hex2rgb("#fed100"),
sprite_alpha_fade = true,
direction = angle-math.rad(180+math.random(60)-30),
speed = 0.8*(distance/50),
speed_increase = -0.01,
time = 0.75
}
Particle:new(self.pos.x,self.pos.y,particle_data)
end end
end end
@@ -95,19 +82,42 @@ function Fairy:handleAnimation()
self.body:animate() self.body:animate()
--if self:isCollidingWith(main_player) then self.sprite_tint = {1,0,0} else self.sprite_tint = {1,1,1} end --if self:isCollidingWith(main_player) then self.sprite_tint = {1,0,0} else self.sprite_tint = {1,1,1} end
self:draw(self.body) self:draw(self.body)
self.particle_timer = self.particle_timer + 1
if self.particle_timer >= self.particle_time then
local vector = vector(self.vel.x,self.vel.y)
local angle = getAngleFromVector(vector)
self.particle_timer = 0
local particle_data = {
animation = animation.particle.simple,
animation_speed = 1,
sprite_tint = hex2rgb("#fed100"),
sprite_alpha_fade = true,
direction = angle-math.rad(180+math.random(60)-30),
speed = 1,
speed_increase = -0.01,
time = 0.75
}
Particle:new(self.pos.x,self.pos.y,particle_data)
end
end end
function Fairy:doPhysics() function Fairy:doPhysics()
local random_x = math.random(-4, 4)/10 -- horizontal collision
local random_y = math.random(-4, 4)/10 self:moveX(
self.vel.x,
self.vel.x = self.vel.x + random_x function()
self.vel.y = self.vel.y + random_y self.vel.x = 0
end
self:moveWithCollision() )
self.vel.x = 0 -- vertical collision
self.vel.y = 0 self:moveY(
self.vel.y,
function()
self.vel.y = 0
end
)
-- final position
self:adjustLight() self:adjustLight()
end end

View File

@@ -36,10 +36,6 @@ function HookAnchor:drawBackground()
) )
end end
function HookAnchor:doPhysics()
end
function Fairy:debug() function Fairy:debug()
Entity.debug(self) Entity.debug(self)
end end

View File

@@ -44,8 +44,9 @@ function Kupo:doLogic()
self.target.y = main_player.pos.y - main_player.target_offset.y self.target.y = main_player.pos.y - main_player.target_offset.y
local distance_x = self.target.x - self.pos.x local distance_x = self.target.x - self.pos.x
local distance_y = self.target.y - self.pos.y local distance_y = self.target.y - self.pos.y
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
local angle = getAngleFromVector(distance_x,distance_y) local angle = getAngleFromVector(vector(distance_x,distance_y))
self.draw_bow = false self.draw_bow = false
if distance <= self.range then if distance <= self.range then
if self.hostile == true then if self.hostile == true then
@@ -153,7 +154,3 @@ function Kupo:handleAnimation()
) )
end end
end end
function Kupo:doPhysics()
self:moveWithCollision()
end

View File

@@ -21,8 +21,14 @@ function Particle:new(x,y,particle_data)
o.sprite_flip = particle_data.sprite_flip or o.sprite_flip o.sprite_flip = particle_data.sprite_flip or o.sprite_flip
o.time = particle_data.time or nil o.time = particle_data.time or nil
if o.time ~= nil then o.time = o.time * game.framerate end if o.time ~= nil then
if particle_data.time_unit ~= nil
and particle_data.time_unit == "frames" then
o.time = o.time
else
o.time = o.time * game.framerate
end
end
o.timer = 0 o.timer = 0
o.vel = { o.vel = {
@@ -83,26 +89,32 @@ function Particle:handleAnimation()
end end
end end
function Particle:doPhysics() function Particle:doLogic()
-- adjust speed -- adjust speed
if self.speed_increase ~= 0 then if self.speed_increase ~= 0 then
self.speed = self.speed + self.speed_increase self.speed = self.speed + self.speed_increase
self.vel.x = self.speed * math.cos(self.direction) self.vel.x = self.speed * math.cos(self.direction)
self.vel.y = self.speed * math.sin(self.direction) self.vel.y = self.speed * math.sin(self.direction)
end end
-- move
self:moveWithCollision()
if self.light ~= nil then
self:adjustLight()
self.light.range = self.light_range * self.sprite_alpha/2
end
if self.time ~= nil then if self.time ~= nil then
if self.timer >= self.time then self:kill() end if self.timer >= self.time then self:kill() end
end end
end end
function Particle:doPhysics()
-- horizontal collision
self:moveX(
self.vel.x
)
-- vertical collision
self:moveY(
self.vel.y
)
-- final position
self:adjustLight()
end
function Particle:debug() function Particle:debug()
-- draw center CYAN -- draw center CYAN
love.graphics.setColor(0,1,1) love.graphics.setColor(0,1,1)

View File

@@ -155,7 +155,7 @@ function Player:doLogic()
end end
-- set dash values -- set dash values
self.dashDirection = getAngleFromVector(horizontal, vertical) self.dashDirection = getAngleFromVector(vector(horizontal, vertical))
self.dash_timer = math.floor(self.dash_time * game.framerate) self.dash_timer = math.floor(self.dash_time * game.framerate)
end end
else else
@@ -232,10 +232,10 @@ function Player:doPhysics()
-- hook state -- hook state
if self.is_hooked then if self.is_hooked then
self.move_x = 0 self.move_x = 0
local hook = vector(self.pos.x, self.pos.y, self.hook_anchor.x, self.hook_anchor.y) local hook = vector(self.hook_anchor.x - self.pos.x, self.hook_anchor.y - self.pos.y)
local dist = math.min(getVectorValue(hook), self.hook_distance) local dist = math.min(getVectorValue(hook), self.hook_distance)
local hook_angle = getAngleFromVector(hook[1],hook[2])-math.rad(180) local hook_angle = getAngleFromVector(hook)-math.rad(180)
if Keybind:checkDown(Keybind.move.right) then if Keybind:checkDown(Keybind.move.right) then
hook_angle = hook_angle - self.hook_swing_speed hook_angle = hook_angle - self.hook_swing_speed
@@ -251,7 +251,8 @@ function Player:doPhysics()
animation_speed = 0, animation_speed = 0,
sprite_tint = hex2rgb("#fed100"), sprite_tint = hex2rgb("#fed100"),
sprite_alpha = 0.5, sprite_alpha = 0.5,
time = 0.05, time = 4,
time_unit = "frames",
sprite_flip = { sprite_flip = {
x = self.sprite_flip.x, x = self.sprite_flip.x,
y = self.sprite_flip.y y = self.sprite_flip.y
@@ -263,8 +264,13 @@ function Player:doPhysics()
local pos_y = self.hook_anchor.y + dist * math.sin(hook_angle) local pos_y = self.hook_anchor.y + dist * math.sin(hook_angle)
self.vel.x = self.vel.x + pos_x - self.pos.x self.vel.x = self.vel.x + pos_x - self.pos.x
self.vel.y = self.vel.y + pos_y - self.pos.y self.vel.y = self.vel.y + pos_y - self.pos.y
self.pos.x = pos_x
self.pos.y = pos_y self:moveX(
pos_x - self.pos.x
)
self:moveY(
pos_y - self.pos.y
)
end end
@@ -275,24 +281,26 @@ function Player:doPhysics()
end end
-- horizontal collision -- horizontal collision
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then self.wall_hit = 0
self.pos.x = self.pos.x + self.vel.x self:moveX(
self.wall_hit = 0 self.vel.x,
else function()
self.wall_hit = math.sign(self.vel.x) self.wall_hit = math.sign(self.vel.x)
self.vel.x = 0 self.vel.x = 0
end end
)
-- vertical collision -- vertical collision
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then self:moveY(
self.pos.y = self.pos.y + self.vel.y self.vel.y,
else function()
if self.vel.y > 0 then if self.vel.y > 0 then
self.is_on_ground = true self.is_on_ground = true
self.dash_count = self.dash_amount self.dash_count = self.dash_amount
end
self.vel.y = 0
end end
self.vel.y = 0 )
end
-- if u collision w hazard, respawn -- if u collision w hazard, respawn
if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then
@@ -326,10 +334,10 @@ function Player:handleAnimation()
elseif self.vel.y < 0 then elseif self.vel.y < 0 then
self.body = self.body:change(animation.nancy.jump) self.body = self.body:change(animation.nancy.jump)
self.mask = self.mask:change(self.mask_type.jump) self.mask = self.mask:change(self.mask_type.jump)
elseif self.vel.x + self.move_x ~= 0 then elseif self.vel.x + self.move_x ~= 0 and not self.is_hooked then
self.body = self.body:change(animation.nancy.run) self.body = self.body:change(animation.nancy.run)
self.mask = self.mask:change(self.mask_type.run) self.mask = self.mask:change(self.mask_type.run)
else elseif not self.is_hooked then
self.body = self.body:change(animation.nancy.idle) self.body = self.body:change(animation.nancy.idle)
self.mask = self.mask:change(self.mask_type.idle) self.mask = self.mask:change(self.mask_type.idle)
end end

View File

@@ -5,6 +5,7 @@ function Entity:new(x,y)
local o = {} local o = {}
o.pos = {x = x, y = y} o.pos = {x = x, y = y}
o.move_remainder = {x = 0, y = 0}
o.vel = {x = 0, y = 0} o.vel = {x = 0, y = 0}
o.direction = 0 o.direction = 0
@@ -69,24 +70,53 @@ end
function Entity:doLogic() function Entity:doLogic()
end end
function Entity:move() function Entity:moveX(amount, func)
self.pos.x = self.pos.x + self.vel.x self.move_remainder.x = self.move_remainder.x + amount
self.pos.y = self.pos.y + self.vel.y local move = math.round(self.move_remainder.x)
if move ~= 0 then
self.move_remainder.x = self.move_remainder.x - move
local sign = math.sign(move)
while math.round(move) ~= 0 do
if not self:isCollidingAt(
self.pos.x + sign,
self.pos.y,
LoadedObjects.Collisions
) then
self.pos.x = self.pos.x + sign
move = move - sign
if tostring(move) == "nan" then error() end
else
if func then
func()
end
break
end
end
end
end end
function Entity:moveWithCollision() function Entity:moveY(amount, func)
-- horizontal collision self.move_remainder.y = self.move_remainder.y + amount
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then local move = math.round(self.move_remainder.y)
self.pos.x = self.pos.x + self.vel.x if move ~= 0 then
else self.move_remainder.y = self.move_remainder.y - move
self.vel.x = 0 local sign = math.sign(move)
end while math.round(move) ~= 0 do
if not self:isCollidingAt(
-- vertical collision self.pos.x,
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then self.pos.y + sign,
self.pos.y = self.pos.y + self.vel.y LoadedObjects.Collisions
else ) then
self.vel.y = 0 self.pos.y = self.pos.y + sign
move = move - sign
if tostring(move) == "nan" then error() end
else
if func then
func()
end
break
end
end
end end
end end
@@ -120,8 +150,9 @@ function Entity:checkVisionLine(entity,range)
local distance_x = target_x - self.pos.x local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y local distance_y = target_y - self.pos.y
local distance = vector(distance_x,distance_y)
local angle = getAngleFromVector(distance_x,distance_y) local angle = getAngleFromVector(distance)
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
local is_colliding = true local is_colliding = true
@@ -227,8 +258,9 @@ function Entity:checkVisionLineDebug(entity,range)
local distance_x = target_x - self.pos.x local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y local distance_y = target_y - self.pos.y
local distance = vector(distance_x,distance_y)
local angle = getAngleFromVector(distance_x,distance_y) local angle = getAngleFromVector(distance)
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if distance < range then if distance < range then
@@ -277,6 +309,9 @@ function Entity:debug()
end end
end end
function Entity:doPhysics()
end
function Entity:handleAnimation() function Entity:handleAnimation()
end end

View File

@@ -53,10 +53,6 @@ function stepGame()
initMenu("dialog",dialog_sequence.example) initMenu("dialog",dialog_sequence.example)
end end
if Keybind:checkPressed(Keybind.debug.editor) then
editor_mode = true
end
if Keybind:checkPressed(Keybind.debug.recording) then if Keybind:checkPressed(Keybind.debug.recording) then
if DemoRecording then if DemoRecording then
Demo:endRecord() Demo:endRecord()

View File

@@ -20,7 +20,6 @@ function drawGameworldBackground()
for i = 1, #LevelTiles do for i = 1, #LevelTiles do
for j = 1, #LevelTiles[i] do for j = 1, #LevelTiles[i] do
if LevelTiles[i][j].id ~= 0 then if LevelTiles[i][j].id ~= 0 then
local depth = TileData[LevelTiles[i][j].id].depth local depth = TileData[LevelTiles[i][j].id].depth
drawTile( drawTile(
LevelTiles[i][j], LevelTiles[i][j],

View File

@@ -1,90 +1,51 @@
function exportLevel(levelname, filename) function exportLevel(levelname, dirname)
love.filesystem.createDirectory("export") dirname = "export/"..dirname
filename = filename or "output.lua"
if string.sub(filename, 1, 1) ~= "/" then if love.filesystem.exists(dirname) then
filename = "export/"..filename -- TODO: prompt to overwrite
error("file already exists")
end
local ok = love.filesystem.createDirectory(dirname)
if not ok then
logPrint("error creating directory")
end end
exportFile = io.open(filename, "w+")
if exportFile then
logPrint("Exporting level \"".. levelname .. "\"...")
exportFile:write("return {")
logPrint("- level name") logPrint("Exporting level \"".. levelname .. "\"...")
exportFile:write("\n name = \"" .. levelname .. "\",") local exportTable = {}
exportTable.name = levelname
logPrint("- tileset") exportTable.tileset = "library"
for k, v in pairs(tileset) do exportTable.properties = LevelData.properties
if v == LevelData.tileset then --exportTable.tiles = LevelTiles
exportFile:write("\n tileset = tileset." .. k .. ",") --logPrint("- objects")
end --exportTable.objects = { spawns = {}, rooms = {} }
end --logPrint(" - spawns")
--for i, v in ipairs(LoadedObjects.Spawns) do
logPrint("- properties") --exportTable.objects.spawns = {v.archetype.name,{},v.args}
exportFile:write("\n properties = {") --end
logPrint(" - darkness: ".. tostring(LevelData.properties.darkness))
exportFile:write("\n darkness = " .. tostring(LevelData.properties.darkness)) --logPrint(" - rooms")
exportFile:write("\n },")
--for i, room in ipairs(LoadedObjects.Rooms) do
logPrint("- tiles") --- table.insert(exportTable.objects.rooms,{room:asRect():getCoords()})
exportFile:write("\n tiles = {") --end
local rows = #LevelTiles exportTable.chunks = Chunk:getExportList()
for i = 1, #LevelTiles do logPrint("Writing to file...")
if i > 1 then local ok, err = love.filesystem.write(dirname.."/level.lua", "return "..serialize_lua_value(exportTable))
exportFile:write(", ")
end if ok then
exportFile:write("\n { ") logPrint("Saving chunks...")
for j = 1, #LevelTiles[i] do local chunkdir = dirname.."/chunks"
if j ~= 1 then love.filesystem.createDirectory(chunkdir)
exportFile:write(", ") for chunk in pairs(Chunk.all) do
end local ok, err = chunk:save(chunkdir)
exportFile:write(tostring(LevelTiles[i][j].id)) if not ok then error(err) end
end end
exportFile:write("}") logPrint("Exporting complete.")
logPrint(" - row "..i.."/"..rows.." "..math.floor(100*((i-1)*100/rows))/100 .."%") else
end -- TODO: clean up created files
exportFile:write("\n },") logPrint("Exporting failed: "..err)
logPrint("- objects")
exportFile:write("\n objects = {")
logPrint(" - spawns")
exportFile:write("\n spawns = {")
for i, v in ipairs(LoadedObjects.Spawns) do
if i > 1 then
exportFile:write(",")
end
exportFile:write("\n {")
exportFile:write(v.archetype.type)
exportFile:write(",{")
for i=1, #v.args do
if i > 1 then
exportFile:write(",")
end
exportFile:write(v.args[i])
end
exportFile:write("}}")
end
exportFile:write("\n },")
logPrint(" - rooms")
exportFile:write("\n rooms = {")
for i, room in ipairs(LoadedObjects.Rooms) do
if i > 1 then
exportFile:write(",")
end
exportFile:write("\n {{")
exportFile:write(room.from.x)
exportFile:write(",")
exportFile:write(room.from.y)
exportFile:write("},{")
exportFile:write(room.to.x)
exportFile:write(",")
exportFile:write(room.to.y)
exportFile:write("}}")
end
exportFile:write("\n },")
exportFile:write("\n },")
logPrint("Exporting complete.")
exportFile:write("\n}")
exportFile:close()
end end
end end

View File

@@ -17,6 +17,10 @@ Keybind.debug = {}
Keybind.editor = {} Keybind.editor = {}
Keybind.generic = {} Keybind.generic = {}
function Keybind:isAvailable(action)
return not action.occupied
end
function Keybind:checkDown(action) function Keybind:checkDown(action)
if DemoPlayback then if DemoPlayback then
for _, demo_action in pairs(DemoAction[CurrentDemoFrame]) do for _, demo_action in pairs(DemoAction[CurrentDemoFrame]) do
@@ -37,9 +41,11 @@ function Keybind:checkDown(action)
if action.demo ~= nil then if action.demo ~= nil then
Demo:recordAction(action.demo) Demo:recordAction(action.demo)
end end
action.occupied = true
return true return true
end end
end end
action.occupied = false
return false return false
end end
end end

View File

@@ -1,7 +1,25 @@
function loadLevelTiles() function loadLevelTiles()
math.randomseed(3) math.randomseed(3)
LevelData = dofile("data/levels/"..level_current) level_current = "data/levels/level1"
LevelData = dofile(level_current.."/level.lua")
LoadedObjects.Collisions = {}
LoadedObjects.Platforms = {}
LoadedObjects.Ladders = {}
LoadedObjects.Hazards = {}
if type(LevelData.tileset) == "string" then
LevelData.tileset_name = LevelData.tileset
end
LevelData.tileset = tileset[LevelData.tileset_name]
getLevelTileData()
for _, v in ipairs(LevelData.chunks) do
Chunk:new(v[1], v[2])
end
local global_chunk = next(Chunk.all)
global_chunk:load()
LoadedObjects.Collisions = global_chunk.loaded.collisions
LevelTiles = global_chunk.data.tiles
--[[ --[[
on level format: on level format:
@@ -12,26 +30,26 @@ function loadLevelTiles()
overlay_depth = foreground/background overlay depth overlay_depth = foreground/background overlay depth
type = collision type type = collision type
]] ]]
getLevelTileData()
LevelTiles = LevelData.tiles
updateLevelDimensions() updateLevelDimensions()
indexLevelTiles() --
createTileObjects() --createTileObjects()
createRoomObjects() --createRoomObjects()
getSpawns() --getSpawns()
end end
function createRoomObjects() function createRoomObjects()
LoadedObjects.Rooms = {} LoadedObjects.Rooms = {}
for _, v in pairs(LevelData.objects.rooms) do for _, v in pairs(LevelData.objects.rooms) do
table.insert(LoadedObjects.Rooms, Collision:new(v[1][1],v[1][2],v[2][1],v[2][2])) table.insert(LoadedObjects.Rooms, Collision:new(v[1],v[2],v[3],v[4]))
end end
end end
function getSpawns() function getSpawns()
LoadedObjects.Spawns = {} LoadedObjects.Spawns = {}
for _, v in pairs(LevelData.objects.spawns) do for _, v in pairs(LevelData.objects.spawns) do
addSpawn(v[1],unpack(v[2])) --addSpawn(v[1],unpack(v[2]))
end end
end end
@@ -121,11 +139,8 @@ function reduceLevelCanvas(horizontal,vertical)
end end
function getLevelTileData() function getLevelTileData()
for k, v in pairs(tileset) do TileData = dofile("data/tileset/"..LevelData.tileset_name..".lua")
if v == LevelData.tileset then
TileData = dofile("data/tileset/"..k..".lua")
end
end
end end
function reloadLevelTiles() function reloadLevelTiles()
@@ -159,10 +174,10 @@ end
function indexLevelTiles() function indexLevelTiles()
TileIndex = {} TileIndex = {}
local this_tileset = LevelData.tileset
-- index from tileset -- index from tileset
local width = LevelData.tileset:getPixelWidth()/tile_properties.width local width = this_tileset:getPixelWidth()/tile_properties.width
local height = LevelData.tileset:getPixelHeight()/tile_properties.height local height = this_tileset:getPixelHeight()/tile_properties.height
for i = 0, height do for i = 0, height do
for j = 0, width do for j = 0, width do
TileIndex[i*width+j+1] = love.graphics.newQuad( TileIndex[i*width+j+1] = love.graphics.newQuad(
@@ -170,7 +185,7 @@ function indexLevelTiles()
i*tile_properties.height, i*tile_properties.height,
tile_properties.width, tile_properties.width,
tile_properties.height, tile_properties.height,
LevelData.tileset:getDimensions() this_tileset:getDimensions()
) )
end end
end end
@@ -220,6 +235,9 @@ end
function instanceTile(id) function instanceTile(id)
local tile = {} local tile = {}
if type(id) == "table" then
id = id.id
end
tile.id = id tile.id = id
local Properties = TileData[tile.id] local Properties = TileData[tile.id]
@@ -258,7 +276,7 @@ function drawGridDisplay()
end end
end end
function optimizeTileObjects() function optimizeTileObjects(dest)
logPrint("Optimizing Objects...") logPrint("Optimizing Objects...")
local unoptimized = 0 local unoptimized = 0
local isTileOptimized = {} local isTileOptimized = {}
@@ -270,8 +288,9 @@ function optimizeTileObjects()
end end
for i = 1, #LevelTiles do for i = 1, #LevelTiles do
for j = 1, #LevelTiles[i] do for j = 1, #LevelTiles[i] do
if LevelTiles[i][j].id ~= 0 then if LevelTiles[i][j].id ~= 0 and TileData[LevelTiles[i][j].id] then
local type = TileData[LevelTiles[i][j].id].type local tile_dat = TileData[LevelTiles[i][j].id]
local type = tile_dat.type
if type == "whole" and not isTileOptimized[i][j] then if type == "whole" and not isTileOptimized[i][j] then
isTileOptimized[i][j] = true isTileOptimized[i][j] = true
local n = 1 local n = 1
@@ -337,29 +356,27 @@ function optimizeTileObjects()
base_x + tile_properties.width * tile_properties.scale * n, base_x + tile_properties.width * tile_properties.scale * n,
base_y + tile_properties.height * tile_properties.scale * m base_y + tile_properties.height * tile_properties.scale * m
) )
table.insert(LoadedObjects.Collisions,col) table.insert(dest,col)
end end
end end
end end
end end
logPrint("collisions optimized from " .. unoptimized .. " to " .. #LoadedObjects.Collisions) --logPrint("collisions optimized from " .. unoptimized .. " to " .. #LoadedObjects.Collisions)
end end
function createTileObjects() -- currently broken
LoadedObjects.Collisions = {} function createTileObjects(dest)
LoadedObjects.Platforms = {}
LoadedObjects.Ladders = {}
LoadedObjects.Hazards = {}
optimizeTileObjects()
optimizeTileObjects(dest.collisions)
for i = 1, #LevelTiles do for i = 1, #LevelTiles do
for j = 1, #LevelTiles[i] do for j = 1, #LevelTiles[i] do
if LevelTiles[i][j].id ~= 0 then if LevelTiles[i][j].id ~= 0 then
local tile_dat = TileData[LevelTiles[i][j].id] or {}
local type = TileData[LevelTiles[i][j].id].type local type = tile_dat.type
local light = TileData[LevelTiles[i][j].id].light local light = tile_dat.light
local base_x = tile_properties.scale * j * tile_properties.width + tile_properties.scale * (level_properties.offset.x - tile_properties.height) local base_x = tile_properties.scale * j * tile_properties.width + tile_properties.scale * (level_properties.offset.x - tile_properties.height)
local base_y = tile_properties.scale * i * tile_properties.height + tile_properties.scale * (level_properties.offset.y - tile_properties.height) local base_y = tile_properties.scale * i * tile_properties.height + tile_properties.scale * (level_properties.offset.y - tile_properties.height)
@@ -372,6 +389,9 @@ function createTileObjects()
) )
end end
local col
local list = dest.collisions
-- wholes are handled in optimization now -- wholes are handled in optimization now
--[[if type == "whole" then --[[if type == "whole" then
local col = Collision:new( local col = Collision:new(
@@ -383,33 +403,33 @@ function createTileObjects()
table.insert(LoadedObjects.Collisions,col) table.insert(LoadedObjects.Collisions,col)
else]]if type == "half_bottom" then else]]if type == "half_bottom" then
local col = Collision:new( col = Collision:new(
base_x, base_x,
base_y + tile_properties.height/2 * tile_properties.scale, base_y + tile_properties.height/2 * tile_properties.scale,
base_x + tile_properties.width * tile_properties.scale, base_x + tile_properties.width * tile_properties.scale,
base_y + tile_properties.height * tile_properties.scale base_y + tile_properties.height * tile_properties.scale
) )
table.insert(LoadedObjects.Collisions,col)
elseif type == "half_top" then elseif type == "half_top" then
local col = Collision:new( col = Collision:new(
base_x, base_x,
base_y , base_y ,
base_x + tile_properties.width * tile_properties.scale, base_x + tile_properties.width * tile_properties.scale,
base_y + tile_properties.height/2 * tile_properties.scale base_y + tile_properties.height/2 * tile_properties.scale
) )
table.insert(LoadedObjects.Collisions,col)
elseif type == "half_right" then elseif type == "half_right" then
local col = Collision:new( col = Collision:new(
base_x + tile_properties.height/2 * tile_properties.scale, base_x + tile_properties.height/2 * tile_properties.scale,
base_y, base_y,
base_x + tile_properties.width * tile_properties.scale, base_x + tile_properties.width * tile_properties.scale,
base_y + tile_properties.height * tile_properties.scale base_y + tile_properties.height * tile_properties.scale
) )
table.insert(LoadedObjects.Collisions,col)
elseif type == "half_left" then elseif type == "half_left" then
@@ -580,7 +600,8 @@ function createTileObjects()
end end
elseif type == "ladder_right" then -- TODO: fix ladders
--[[elseif type == "ladder_right" then
local ladder = Collision:new( local ladder = Collision:new(
base_x + (tile_properties.width-4)* tile_properties.scale, base_x + (tile_properties.width-4)* tile_properties.scale,
@@ -638,7 +659,7 @@ function createTileObjects()
) )
table.insert(LoadedObjects.Platforms,plat) table.insert(LoadedObjects.Platforms,plat)
elseif type == "bottom_hazard" then ]]elseif type == "bottom_hazard" then
local hazard = Collision:new( local hazard = Collision:new(
@@ -647,9 +668,10 @@ function createTileObjects()
base_x + tile_properties.width * tile_properties.scale, base_x + tile_properties.width * tile_properties.scale,
base_y + tile_properties.height * tile_properties.scale base_y + tile_properties.height * tile_properties.scale
) )
table.insert(LoadedObjects.Hazards,hazard) list = dest.hazards
end end
table.insert(list, col)
end end
end end
end end

View File

@@ -8,20 +8,22 @@ function math.sign(x)
end end
end end
function vector(init_x, init_y, final_x, final_y) function math.round(x)
local distance_x = final_x - init_x return math.floor(x+0.5)
local distance_y = final_y - init_y end
return {distance_x, distance_y}
function vector(x, y)
return {x = x, y = y}
end end
function getVectorValue(vector) function getVectorValue(vector)
return math.sqrt(vector[1] ^ 2 + vector[2] ^ 2) return math.sqrt(vector.x ^ 2 + vector.y ^ 2)
end end
function getAngleFromVector(x,y) function getAngleFromVector(vector)
local reduce = 0 local reduce = 0
if x < 0 then if vector.x < 0 then
reduce = math.rad(180) reduce = math.rad(180)
end end
return math.atan(y/x) - reduce return math.atan(vector.y/vector.x) - reduce
end end

View File

@@ -25,10 +25,7 @@ function isThereObjectAt(x,y,objectType)
for _, object in pairs(objectType) do for _, object in pairs(objectType) do
if object.is_disabled then if object.is_disabled then
-- Dont calculate if dissabled -- Dont calculate if dissabled
elseif x >= object.from.x elseif object:asRect():containsPoint(Point:new(x, y)) then
and x <= object.to.x
and y >= object.from.y
and y <= object.to.y then
object.is_colliding = true object.is_colliding = true
return true return true
end end
@@ -36,14 +33,6 @@ function isThereObjectAt(x,y,objectType)
return false return false
end end
function isThereCollisionAt(x,y)
if x >= 0 and x < #CollisionTable
and y >= 0 and y < #CollisionTable[0] then
return CollisionTable[math.floor(y)][math.floor(x)]
end
return false
end
-- flags -- flags
function setCollisionFlags() function setCollisionFlags()
local Check = { local Check = {

86
code/rect.lua Normal file
View File

@@ -0,0 +1,86 @@
-- based of of plan9's Rectangle struct
-- rect.max is not counted as "in" the rectangle
Rect = {}
Rect.__index = Rect
function Rect:fromPoints(pt1, pt2)
local o = { min = pt1, max = pt2 }
setmetatable(o, self)
return o
end
function Rect:getPoints()
return self.min, self.max
end
function Rect:fromCoords(x1, y1, x2, y2)
return Rect:fromPoints(Point:new(x1, y1), Point:new(x2, y2))
end
function Rect:getCoords()
return self.min.x, self.min.y, self.max.x, self.max.y
end
-- clone refers to a deep copy
function Rect:clone()
return Rect:fromCoords(self.min.x, self.min.y, self.max.x, self.max.y)
end
-- make sure min and max refer to the correct corners
-- acts in place, returns self
function Rect:fix()
if self.min.x > self.max.x then
self.min.x, self.max.x = self.max.x, self.min.x
end
if self.min.y > self.max.y then
self.min.y, self.max.y = self.max.y, self.min.y
end
end
function Rect:width()
return self.max.x - self.min.x
end
function Rect:height()
return self.max.y - self.min.y
end
function Rect:size()
return Point:new(self:width(), self:height())
end
function Rect:__add(pt)
return Rect:fromPoints(self.min + pt, self.max + pt)
end
function Rect:corners()
return {
self.min:copy(), -- top left
Point:new(self.max.x, self.min.y), -- top right
Point:new(self.min.x, self.max.y), -- bottom left
self.max:copy(), -- bottom right
}
end
function Rect:containsPoint(pt)
return pt.x >= self.min.x
and pt.y >= self.min.y
and pt.x <= self.max.x
and pt.y <= self.max.y
end
function Rect:overlapsRect(other)
return self.min.x < other.max.x
and self.max.x > other.min.x
and self.min.y < other.max.y
and self.max.y > other.min.y
end
function Rect:draw(style)
love.graphics.rectangle(style, self.min.x - Camera.pos.x, self.min.y - Camera.pos.y, self:width(), self:height())
end
function Rect:__tostring()
return "Rect["..tostring(self.min).." "..tostring(self.max).."]"
end

View File

@@ -7,6 +7,7 @@ require "data/sfx"
require "code/locale" require "code/locale"
-- support functions -- support functions
require "code/serialize"
require "code/math" require "code/math"
require "code/draw" require "code/draw"
require "code/hex" require "code/hex"
@@ -14,6 +15,8 @@ require "code/in_out"
-- classes -- classes
require "code/point" require "code/point"
require "code/rect"
require "code/chunk"
require "code/objects" require "code/objects"
require "code/level" require "code/level"
require "code/camera" require "code/camera"

31
code/serialize.lua Normal file
View File

@@ -0,0 +1,31 @@
local function quote(str, lvl)
--lvl = lvl or
local rp = "]"..(lvl or "").."]"
if string.match(str, rp) then
return quote(str, (lvl or "") .. "=")
end
return "["..(lvl or "").."["..str..rp
end
function serialize_lua_value(val)
if type(val) == "number" then
return tostring(val)
elseif type(val) == "string" then
-- TODO: use different quotes if ']]' appears in the value
return quote(val)
elseif type(val) == "table" then
local r = "{"
for k, v in pairs(val) do
r = r .. "[ "..serialize_lua_value(k).." ]="..serialize_lua_value(v)..","
end
return r .. "}"
elseif val == nil then
return "nil"
elseif val == false then
return "false"
elseif val == true then
return "true"
end
error("serialization failed")
end

View File

@@ -20,7 +20,11 @@ function deselectSpawns()
end end
end end
function selectSpawns(x,y) function selectSpawns(rect)
local x, y = rect:getPoints()
local select_rect = Rect:fromPoints(x-{x=Camera.pos.x,y=Camera.pos.y},y-{x=Camera.pos.x,y=Camera.pos.y})
select_rect:fix()
for _, spawn in pairs(LoadedObjects.Spawns) do for _, spawn in pairs(LoadedObjects.Spawns) do
local offset_x, offset_y = spawn.archetype.display:getCenteredOffset() local offset_x, offset_y = spawn.archetype.display:getCenteredOffset()
@@ -28,9 +32,9 @@ function selectSpawns(x,y)
local top = spawn.args[2] - Camera.pos.y - offset_y local top = spawn.args[2] - Camera.pos.y - offset_y
local right = spawn.args[1] - Camera.pos.x + offset_x local right = spawn.args[1] - Camera.pos.x + offset_x
local bottom = spawn.args[2] - Camera.pos.y + offset_y local bottom = spawn.args[2] - Camera.pos.y + offset_y
local x = (x / game.scale)
local y = (y / game.scale) local spawn_rect = Rect:fromCoords(left, top, right, bottom)
if x >= left and y >= top and x <= right and y <= bottom then if spawn_rect:overlapsRect(select_rect) then
spawn.selected = true spawn.selected = true
end end
@@ -47,10 +51,22 @@ function selectSpawns(x,y)
end end
function moveSpawns(x,y) function moveSpawns(x,y)
local move_x = nil
local move_y = nil
for _, spawn in pairs(LoadedObjects.Spawns) do for _, spawn in pairs(LoadedObjects.Spawns) do
if spawn.selected then if spawn.selected then
spawn.args[1] = math.floor(x/game.scale)+Camera.pos.x local difference_x = math.floor((x/game.scale)+Camera.pos.x) - spawn.args[1]
spawn.args[2] = math.floor(y/game.scale)+Camera.pos.y local difference_y = math.floor((y/game.scale)+Camera.pos.y) - spawn.args[2]
if move_x == nil or Point.abs({x=difference_x,y=difference_y}) < Point.abs({x=move_x,y=move_y}) then
move_x = difference_x
move_y = difference_y
end
end
end
for _, spawn in pairs(LoadedObjects.Spawns) do
if spawn.selected then
spawn.args[1] = spawn.args[1] + move_x
spawn.args[2] = spawn.args[2] + move_y
end end
end end
end end
@@ -72,6 +88,9 @@ function promptSpawnNew()
for i=2, #result+1 do for i=2, #result+1 do
print("arg #"..i-1) print("arg #"..i-1)
args[i-1] = result[i] args[i-1] = result[i]
if i < 4 then
args[i-1] = math.floor(args[i-1])
end
end end
else else
args = {0,0} args = {0,0}

View File

@@ -5,16 +5,19 @@ function addElement(self)
self.id = #UIElement self.id = #UIElement
end end
function drawTextBox(text,x,y,color,background_color) function drawTextBox(text,x,y,style)
local color = color or {1,1,1,1} local style = style or {}
local background_color = background_color or {0,0,0,1}
local c1, c2, c3, a = love.graphics.getColor() local c1, c2, c3, a = love.graphics.getColor()
local width = locale_font:getWidth(text) local width = locale_font:getWidth(text)
local height = locale_font:getHeight(text) local height = locale_font:getHeight(text)
local margin = 5
local color = style.color or {1,1,1,1}
local background_color = style.background_color or {0,0,0,1}
local margin = style.margin or 5
local lines = 1 local lines = 1
for i in text:gmatch("\n") do for i in text:gmatch("\n") do
lines = lines + 1 lines = lines + 1
end end
love.graphics.setColor(unpack(color)) love.graphics.setColor(unpack(color))

View File

@@ -62,8 +62,10 @@ function Prompt:draw()
self.name .. ": " .. self.input, self.name .. ": " .. self.input,
self.pos.x, self.pos.x,
self.pos.y, self.pos.y,
self.color, {
self.background_color color = self.color,
background_color = self.background_color
}
) )
end end

View File

@@ -1,42 +0,0 @@
return {
name = "Dev Level",
tileset = tileset.library,
properties = {
darkness = false
},
tiles = {
{ 1, 4, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 4, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 4, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 4, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 4, 0, 0, 0, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14},
{ 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 13, 13, 13, 13, 13, 13, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
},
objects = {
spawns = {
{Fairy,{100,88}},
{HookAnchor,{200,89,100}},
{HookAnchor,{400,89,120}}
},
rooms = {
{{96,64},{544,320}},
{{0,0},{112,176}}
},
},
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
return {[ [[tileset]] ]=[[library]],[ [[chunks]] ]={[ 1 ]={[ 1 ]=[[global.lua]],},},[ [[name]] ]=[[unnamed]],[ [[properties]] ]={[ [[darkness]] ]=false,},}

View File

@@ -6,9 +6,10 @@ function love.load()
secs = 0 secs = 0
menu_type = "no" menu_type = "no"
-- FIXME: this overrides a standard library!
debug = false debug = false
debug_collision = false debug_collision = false
editor_mode = false --editor_mode = false
text_size = 1 text_size = 1
@@ -103,6 +104,15 @@ function love.update(dt)
return return
end end
if Keybind:checkPressed(Keybind.debug.editor) then
if editor.active then
deselectSpawns()
createTileObjects()
restartGame()
end
editor.active = not editor.active
end
if love.keyboard.isDown("f7") then if love.keyboard.isDown("f7") then
local test_prompt = Prompt:new({ local test_prompt = Prompt:new({
name = "test prompt", name = "test prompt",
@@ -127,7 +137,7 @@ function love.update(dt)
if menu_type ~= nil then stepMenu(menu_type) end if menu_type ~= nil then stepMenu(menu_type) end
--editor --editor
if editor_mode then if editor.active then
stepEditor() stepEditor()
else else
stepGame() stepGame()
@@ -136,7 +146,7 @@ end
function love.wheelmoved(_, y) function love.wheelmoved(_, y)
if editor_mode then if editor.active then
scrollEditor(y) scrollEditor(y)
end end
end end
@@ -150,7 +160,7 @@ function love.draw()
game_resize = false game_resize = false
end end
if editor_mode then if editor.active then
drawEditor() drawEditor()
else else
drawGame() drawGame()