Compare commits
80 Commits
2b9f605a0a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a20b172af | ||
|
|
a01599c001 | ||
|
|
410c00dcd4 | ||
|
|
8edcbe2d9b | ||
|
|
fa62e1428b | ||
|
|
9be52e2b5f | ||
|
|
a3074acb3c | ||
|
|
59726dc2b7 | ||
|
|
f0a9c1acf9 | ||
|
|
1549976382 | ||
|
|
d20e5392f8 | ||
|
|
d359afaf97 | ||
|
|
11a46e6227 | ||
|
|
f670f6bc87 | ||
|
|
0486787b98 | ||
|
|
6ba4f4d1c9 | ||
|
|
918c63c535 | ||
|
|
6fa7dcbeef | ||
|
|
236e23177d | ||
|
|
4d94cc805d | ||
|
|
9c4b5431ee | ||
|
|
ba1c0f0c89 | ||
|
|
ef632d50ee | ||
|
|
5bcf25a461 | ||
|
|
1039479c47 | ||
|
|
62555b4526 | ||
|
|
a4af57ca6c | ||
|
|
5189bef537 | ||
|
|
eab4cbbcdc | ||
|
|
829963e080 | ||
|
|
82246dc0c6 | ||
|
|
3a5e0b395b | ||
|
|
feed65cf6d | ||
|
|
1883bcd78b | ||
|
|
3c1746d914 | ||
|
|
f091fba9f7 | ||
|
|
27f1dc71c0 | ||
|
|
97de68e34b | ||
|
|
719c6cc5af | ||
|
|
5f48756e2e | ||
|
|
9c070e161f | ||
|
|
4ae674f0a7 | ||
|
|
362c7ea52d | ||
|
|
644b1a4828 | ||
|
|
c0af34fd76 | ||
|
|
e648705e5b | ||
|
|
61b8aa883b | ||
|
|
3d41699d8f | ||
|
|
f7947af505 | ||
|
|
222f4478ca | ||
|
|
f62ec3ea32 | ||
|
|
266bf10d13 | ||
|
|
96b1e750e4 | ||
|
|
8c8e4808ad | ||
|
|
cb6623f29a | ||
|
|
68fb258d26 | ||
|
|
ce66ab73d3 | ||
|
|
e575cb5725 | ||
|
|
6dd970c1d4 | ||
|
|
dbfae2f74e | ||
|
|
93bfe0bda4 | ||
|
|
39b65571a0 | ||
|
|
6e76607030 | ||
|
|
9ada88f4f5 | ||
|
|
a230d3ed06 | ||
|
|
d3796a0204 | ||
|
|
e8242f6564 | ||
|
|
0acbfd5e9d | ||
|
|
a8ffae726f | ||
|
|
59a21aa655 | ||
|
|
081fd99d04 | ||
|
|
5c9fc39fad | ||
|
|
05bf757ea5 | ||
|
|
edd064c2fd | ||
|
|
8cfc6a9d18 | ||
|
|
70958c5762 | ||
|
|
3c4f763ae7 | ||
|
|
cef2096577 | ||
|
|
c978855711 | ||
|
|
5643fc0140 |
BIN
assets/entities/nancy/moth_mask/slide1.png
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
assets/entities/nancy/moth_mask/slide2.png
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
assets/entities/nancy/moth_mask/slide3.png
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
assets/entities/nancy/slide1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/entities/nancy/slide2.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/entities/nancy/slide3.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 92 B After Width: | Height: | Size: 92 B |
|
Before Width: | Height: | Size: 89 B After Width: | Height: | Size: 90 B |
|
Before Width: | Height: | Size: 88 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
@@ -1,6 +1,6 @@
|
||||
Animation = {}
|
||||
|
||||
function Animation:New(anim_data)
|
||||
function Animation:new(anim_data,speed)
|
||||
local o = {}
|
||||
|
||||
o.path = anim_data.path
|
||||
@@ -8,23 +8,30 @@ function Animation:New(anim_data)
|
||||
o.imgs = anim_data.imgs
|
||||
o.subframe = 0
|
||||
o.frame = 1
|
||||
o.speed = speed or 1
|
||||
|
||||
o.was_updated = false
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Animation:ChangeTo(anim_data)
|
||||
function Animation:getCenteredOffset()
|
||||
return self.imgs[1]:getWidth()/2, self.imgs[1]:getHeight()/2
|
||||
end
|
||||
|
||||
function Animation:change(anim_data)
|
||||
if anim_data.path == self.path
|
||||
then
|
||||
return self
|
||||
else
|
||||
return Animation:New(anim_data)
|
||||
return Animation:new(anim_data)
|
||||
end
|
||||
end
|
||||
|
||||
-- to manually handle what frame
|
||||
function Animation:DrawFrame(frame, x, y, rotate, sx, sy)
|
||||
function Animation:drawFrame(frame, x, y, rotate, sx, sy)
|
||||
if frame > #self.frames then
|
||||
frame = #self.frames
|
||||
end
|
||||
@@ -43,14 +50,18 @@ function Animation:DrawFrame(frame, x, y, rotate, sx, sy)
|
||||
end
|
||||
|
||||
-- to linearly animate
|
||||
function Animation:Animate()
|
||||
function Animation:animate()
|
||||
if self.was_updated then
|
||||
self.was_updated = false
|
||||
end
|
||||
if self.frames[self.frame] ~= 0 then
|
||||
-- try to animate
|
||||
self.subframe = self.subframe + current_dt
|
||||
self.subframe = self.subframe + self.speed
|
||||
|
||||
if self.subframe > self.frames[self.frame] then
|
||||
self.subframe = self.subframe - self.frames[self.frame]
|
||||
if self.subframe > self.frames[self.frame]*game.framerate then
|
||||
self.subframe = self.subframe - self.frames[self.frame]*game.framerate
|
||||
self.frame = self.frame + 1
|
||||
self.was_updated = true
|
||||
end
|
||||
|
||||
-- cycle
|
||||
@@ -61,7 +72,7 @@ function Animation:Animate()
|
||||
end
|
||||
|
||||
-- to draw the current frame
|
||||
function Animation:Draw(x, y, rotate, sx, sy)
|
||||
function Animation:draw(x, y, rotate, sx, sy)
|
||||
local x = x or 0
|
||||
local y = y or 0
|
||||
local sx = sx or 1
|
||||
|
||||
@@ -1,21 +1,92 @@
|
||||
Camera = {
|
||||
pos = {x = 0, y = 0},
|
||||
width = 0,
|
||||
height = 0
|
||||
pos = Point:new(0, 0),
|
||||
width = 0,
|
||||
height = 0,
|
||||
speed = 4,
|
||||
}
|
||||
|
||||
function Camera:ConfineToLevel()
|
||||
function Camera:followPlayer(player)
|
||||
-- make sure we have the Point metatable self:moveTowards(pos)
|
||||
local pos = Point.copy(player.pos)
|
||||
local room = player:getCollidingAt(pos.x,pos.y,LoadedObjects.Rooms)
|
||||
|
||||
self:moveTowards(self:confineTo(room, pos))
|
||||
end
|
||||
|
||||
function Camera:confineTo(box, pos)
|
||||
if box == nil then
|
||||
--frameDebug("not in a room")
|
||||
return pos
|
||||
end
|
||||
--frameDebug("in a room")
|
||||
|
||||
local w = self.width/game.scale
|
||||
local h = self.height/game.scale
|
||||
local npos = pos - self:centerOffset()
|
||||
|
||||
-- bottom edge
|
||||
npos.y = math.min(npos.y+h, box.to.y)-h
|
||||
-- right edge
|
||||
npos.x = math.min(npos.x+w, box.to.x)-w
|
||||
-- top edge
|
||||
npos.y = math.max(npos.y, box.from.y)
|
||||
-- left edge
|
||||
npos.x = math.max(npos.x, box.from.x)
|
||||
return npos + self:centerOffset()
|
||||
end
|
||||
|
||||
function Camera:confineToLevel()
|
||||
self.pos.x = math.max(0,math.min(self.pos.x,LevelData.Width-self.width/game.scale))
|
||||
self.pos.y = math.max(0,math.min(self.pos.y,LevelData.Height-self.height/game.scale))
|
||||
end
|
||||
|
||||
function Camera:moveTowards(pt)
|
||||
--local pt = Point:new(x,y)
|
||||
local diff = pt - self:center()
|
||||
local dist = diff:abs()
|
||||
local npos
|
||||
if dist < self.speed then
|
||||
npos = pt
|
||||
else
|
||||
frameDebug("camera at speed limit")
|
||||
npos = self:center() + diff * (self.speed/dist)
|
||||
frameDebug("dist = "..dist..", npos = "..tostring(npos))
|
||||
end
|
||||
self:positionCenterAt(npos.x, npos.y)
|
||||
end
|
||||
|
||||
function Camera:size()
|
||||
return Point:new(self.width, self.height)
|
||||
end
|
||||
|
||||
function Camera:centerOffset()
|
||||
return self:size()/game.scale/2
|
||||
end
|
||||
|
||||
function Camera:center()
|
||||
return self.pos + self:centerOffset()
|
||||
end
|
||||
function Camera:positionCenterAt(x,y)
|
||||
self.pos.x = x-self.width/game.scale/2
|
||||
self.pos.y = y-self.height/game.scale/2
|
||||
self:ConfineToLevel()
|
||||
--self:ConfineToLevel()
|
||||
end
|
||||
|
||||
function Camera:positionAt(x,y)
|
||||
self.pos.x = math.floor((x/self.width)*self.width)
|
||||
self.pos.y = math.floor((y/self.height)*self.height)
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Canvas = {class = "Canvas"}
|
||||
|
||||
function Canvas:New(name)
|
||||
function Canvas:new(name)
|
||||
local o = {}
|
||||
o.name = name
|
||||
o.width = game.width/game.scale
|
||||
@@ -12,12 +12,12 @@ function Canvas:New(name)
|
||||
return o
|
||||
end
|
||||
|
||||
function Canvas:Recreate()
|
||||
function Canvas:recreate()
|
||||
self.canvas:release()
|
||||
self.canvas = love.graphics.newCanvas(self.width,self.height)
|
||||
end
|
||||
|
||||
function Canvas:Reset()
|
||||
function Canvas:reset()
|
||||
love.graphics.setCanvas(self.canvas)
|
||||
love.graphics.setBlendMode("replace")
|
||||
love.graphics.setColor(0,0,0,0)
|
||||
@@ -31,18 +31,18 @@ function Canvas:Reset()
|
||||
love.graphics.setCanvas()
|
||||
end
|
||||
|
||||
function Canvas:DrawingStart()
|
||||
self:Reset()
|
||||
function Canvas:startDrawing()
|
||||
self:reset()
|
||||
love.graphics.setCanvas(self.canvas)
|
||||
end
|
||||
|
||||
function Canvas:DrawingEnd()
|
||||
function Canvas:endDrawing()
|
||||
love.graphics.setCanvas()
|
||||
love.graphics.setBlendMode("alpha")
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
end
|
||||
|
||||
function Canvas:Draw()
|
||||
function Canvas:draw()
|
||||
love.graphics.draw(self.canvas)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Canvas.Darkness = Canvas:New("Darkness")
|
||||
Canvas.Darkness = Canvas:new("Darkness")
|
||||
|
||||
function Canvas.Darkness:Reset()
|
||||
function Canvas.Darkness:reset()
|
||||
love.graphics.setCanvas(Canvas.Darkness.canvas)
|
||||
love.graphics.setBlendMode("replace")
|
||||
love.graphics.setColor(0,0,0,0.95)
|
||||
|
||||
17
code/class.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
function class(super, self)
|
||||
assert(super == nil or super.__index == super)
|
||||
self = self or {}
|
||||
self.__index = self
|
||||
setmetatable(self, super)
|
||||
return self
|
||||
end
|
||||
|
||||
function getAncestors(self)
|
||||
local family = self
|
||||
local list = {}
|
||||
while family ~= nil do
|
||||
family = getmetatable(family)
|
||||
table.insert(list,family)
|
||||
end
|
||||
return list
|
||||
end
|
||||
@@ -1,17 +1,19 @@
|
||||
Collision = {}
|
||||
Collision = class()
|
||||
|
||||
LoadedObjects.Collisions = {}
|
||||
LoadedObjects.Platforms = {}
|
||||
LoadedObjects.Ladders = {}
|
||||
LoadedObjects.Hazards = {}
|
||||
LoadedObjects.Rooms = {}
|
||||
|
||||
|
||||
--[[
|
||||
Collision
|
||||
|
||||
[bool flag] isDisabled
|
||||
[bool flag] is_disabled
|
||||
> if true used for collision
|
||||
|
||||
[bool flag] isColliding
|
||||
[bool flag] is_colliding
|
||||
> if true, this collision is colliding
|
||||
|
||||
[vec2 position] from - x, y
|
||||
@@ -28,8 +30,8 @@ LoadedObjects.Hazards = {}
|
||||
--]]
|
||||
|
||||
-- can also be called with only ox and oy, where they become the width and height instead
|
||||
function Collision:New(ox,oy,tx,ty)
|
||||
local o = {isColliding = false, isDisabled = false}
|
||||
function Collision:new(ox,oy,tx,ty)
|
||||
local o = {is_colliding = false, is_disabled = false}
|
||||
|
||||
if tx ~= nil and ty ~= nil then
|
||||
o.from = {x = ox, y = oy}
|
||||
@@ -46,27 +48,35 @@ function Collision:New(ox,oy,tx,ty)
|
||||
end
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function Collision:CenterAt(x, y)
|
||||
|
||||
|
||||
function Collision:centerAt(x, y)
|
||||
self.from.x = x-self.width/2
|
||||
self.from.y = y-self.height/2
|
||||
self.to.x = x+self.width/2
|
||||
self.to.y = y+self.height/2
|
||||
end
|
||||
|
||||
function Collision:PlaceAt(x, y)
|
||||
function Collision:placeAt(x, y)
|
||||
self.from.x = x or self.from.x
|
||||
self.from.y = y or self.from.y
|
||||
self.to.x = self.from.x + self.width
|
||||
self.to.y = self.from.x + self.height
|
||||
end
|
||||
|
||||
function Collision:Draw(color)
|
||||
if self.isColliding == true then
|
||||
function Collision:containsPoint(x, y)
|
||||
return x >= self.from.x and
|
||||
y >= self.from.y and
|
||||
x <= self.to.x and
|
||||
y <= self.to.y
|
||||
end
|
||||
|
||||
function Collision:draw(color)
|
||||
if self.is_colliding == true then
|
||||
love.graphics.setColor(0,1,0,0.5)
|
||||
elseif color == 1 then
|
||||
love.graphics.setColor(1,0,0,0.5)
|
||||
@@ -77,3 +87,7 @@ function Collision:Draw(color)
|
||||
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)
|
||||
end
|
||||
|
||||
function Collision:asRect()
|
||||
return Rect:fromCoords(self.from.x, self.from.y, self.to.x, self.to.y)
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
function DebugUI()
|
||||
function debugUI()
|
||||
love.graphics.setScale()
|
||||
|
||||
local mouse_x, mouse_y = love.mouse.getPosition()
|
||||
@@ -8,37 +8,35 @@ function DebugUI()
|
||||
love.graphics.print(light.pos.x,light.pos.x,light.pos.y+40)
|
||||
end
|
||||
|
||||
love.graphics.print("time: ".. tostring(math.floor(100*game.secondsSinceStart)/100) .." fps: "..fps_current, 10*textScale, 0*textScale, 0, textScale)
|
||||
love.graphics.print(--[["CPUtime: "..checkCPUTime("total")..", CPU: "..(math.floor(checkCPUTime("get")*10000)/100).."%,]] "memoryUsage: "..memoryUsage.."kB", 10*textScale, 20*textScale, 0, textScale)
|
||||
love.graphics.print("time: ".. tostring(math.floor(100*game.seconds_since_start)/100) .." fps: "..fps_current, 10*text_size, 0*text_size, 0, text_size)
|
||||
love.graphics.print(--[["CPUtime: "..checkCPUTime("total")..", CPU: "..(math.floor(checkCPUTime("get")*10000)/100).."%,]] "memory_usage: "..memory_usage.."kB", 10*text_size, 20*text_size, 0, text_size)
|
||||
|
||||
love.graphics.setColor(1,1,1)
|
||||
-- lots of variables
|
||||
love.graphics.print("LoadedObjects",10*textScale,40*textScale, 0, textScale)
|
||||
love.graphics.print("LoadedObjects",10*text_size,40*text_size, 0, text_size)
|
||||
local i = 1
|
||||
for k, v in pairs(LoadedObjects) do
|
||||
if type(v) == "table" then
|
||||
love.graphics.print("<"..k.."> ".. #v,10*textScale,(40+(10*i))*textScale, 0, textScale)
|
||||
love.graphics.print("<"..k.."> ".. #v,10*text_size,(40+(10*i))*text_size, 0, text_size)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
-- player isOnGroundCheck
|
||||
--love.graphics.main_Player
|
||||
love.graphics.setColor(1,0,0)
|
||||
end
|
||||
|
||||
function DebugColisions()
|
||||
function debugColisions()
|
||||
love.graphics.setScale(game.scale)
|
||||
-- DrawColisionTable()
|
||||
LoadedObjects.DrawCollisions()
|
||||
LoadedObjects.drawCollisions()
|
||||
end
|
||||
|
||||
function DebugEntities()
|
||||
function debugEntities()
|
||||
love.graphics.setScale(game.scale)
|
||||
for _, particle in pairs(LoadedParticles) do
|
||||
particle:Debug()
|
||||
for _, particle in pairs(LoadedObjects.Particles) do
|
||||
particle:debug()
|
||||
end
|
||||
for _, enty in pairs(LoadedObjects.Entities) do
|
||||
enty:Debug()
|
||||
enty:debug()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -93,3 +91,21 @@ end
|
||||
function logWrite(string)
|
||||
if logging then logFile:write(string.."\n") end
|
||||
end
|
||||
|
||||
local frameDebug_lines = {}
|
||||
|
||||
-- used for debug output that will be printed every frame
|
||||
function frameDebug(str)
|
||||
table.insert(frameDebug_lines, str)
|
||||
end
|
||||
|
||||
-- called at the end of each frame, draw everything passed to frameDebug this frame
|
||||
function frameDebugFlush()
|
||||
local y = 0
|
||||
love.graphics.setColor(100, 100, 100, 0.8)
|
||||
for _, str in ipairs(frameDebug_lines) do
|
||||
love.graphics.print(str, 2, y)
|
||||
y = y + 10
|
||||
end
|
||||
frameDebug_lines = {}
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ DemoRecording = false
|
||||
DemoAction = nil -- Table of actions
|
||||
CurrentDemoFrame = nil
|
||||
|
||||
function Demo:Draw()
|
||||
function Demo:draw()
|
||||
if DemoRecording then
|
||||
love.graphics.setColor(1,0,0,1)
|
||||
elseif DemoPlayback then
|
||||
@@ -13,18 +13,18 @@ function Demo:Draw()
|
||||
love.graphics.rectangle("line",0,0,game.width ,game.height)
|
||||
end
|
||||
|
||||
function Demo:PlaybackStart()
|
||||
function Demo:startPlayback()
|
||||
DemoPlayback = true
|
||||
CurrentDemoFrame = 0
|
||||
dofile("demos/play_demo.lua")
|
||||
end
|
||||
|
||||
function Demo:PlaybackEnd()
|
||||
function Demo:endPlayback()
|
||||
DemoPlayback = false
|
||||
DemoAction = nil
|
||||
end
|
||||
|
||||
function Demo:RecordAction(action)
|
||||
function Demo:recordAction(action)
|
||||
if DemoRecording
|
||||
and action ~= nil
|
||||
then
|
||||
@@ -32,26 +32,26 @@ function Demo:RecordAction(action)
|
||||
end
|
||||
end
|
||||
|
||||
function Demo:RecordStart()
|
||||
function Demo:startRecord()
|
||||
-- Make demo stuff
|
||||
os.execute( "mkdir \"./demos\"" )
|
||||
DemoFile = io.open("demos/play_demo.lua", "w+")
|
||||
--DemoFile = io.open("demo/mothbackDemo_"..os.date("%Y-%m-%d_%H-%M-%S")..".lua", "w+")
|
||||
DemoFile:write("main_Player.pos.x = "..main_Player.pos.x.."\n")
|
||||
DemoFile:write("main_Player.pos.y = "..main_Player.pos.y.."\n")
|
||||
DemoFile:write("main_player.pos.x = "..main_player.pos.x.."\n")
|
||||
DemoFile:write("main_player.pos.y = "..main_player.pos.y.."\n")
|
||||
DemoFile:write("DemoAction = {\n")
|
||||
DemoRecording = true
|
||||
CurrentDemoFrame = 1
|
||||
end
|
||||
|
||||
function Demo:RecordEnd()
|
||||
function Demo:endRecord()
|
||||
DemoFile:write("}\n}")
|
||||
DemoFile:close()
|
||||
DemoFile = nil
|
||||
DemoRecording = false
|
||||
end
|
||||
|
||||
function Demo:Step()
|
||||
function Demo:step()
|
||||
if DemoRecording then
|
||||
if CurrentDemoFrame == 1 then
|
||||
DemoFile:write("\t{")
|
||||
@@ -59,7 +59,7 @@ function Demo:Step()
|
||||
DemoFile:write("},\n\t{")
|
||||
end
|
||||
elseif DemoPlayback then
|
||||
if DemoAction[CurrentDemoFrame + 1] == nil then Demo:PlaybackEnd() end
|
||||
if DemoAction[CurrentDemoFrame + 1] == nil then Demo:endPlayback() end
|
||||
end
|
||||
CurrentDemoFrame = CurrentDemoFrame + 1
|
||||
end
|
||||
|
||||
372
code/editor.lua
@@ -1,33 +1,73 @@
|
||||
function EditorStep()
|
||||
palette = palette or false
|
||||
AnimateTiles()
|
||||
assert(editor == nil)
|
||||
editor = {
|
||||
active = false,
|
||||
room_mode = false,
|
||||
palette = {
|
||||
active = false,
|
||||
scroll = Point:new(0, 0),
|
||||
},
|
||||
multiselect = {
|
||||
active = false,
|
||||
sweeping = false,
|
||||
box = nil,
|
||||
},
|
||||
pan = { fixed = false, speed = 3 },
|
||||
}
|
||||
|
||||
if Keybind:CheckPressed(Keybind.editor.palette) then
|
||||
if palette then
|
||||
palette = false
|
||||
palette_scroll_x = nil
|
||||
palette_scroll_y = nil
|
||||
function stepEditor()
|
||||
|
||||
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 love.keyboard.isDown("lshift") then
|
||||
editor.room_mode = "delete"
|
||||
else
|
||||
palette = true
|
||||
palette_scroll_x = 0
|
||||
palette_scroll_y = 0
|
||||
editor.room_mode = not editor.room_mode
|
||||
end
|
||||
editor.room_points = {}
|
||||
end
|
||||
if love.keyboard.isDown('a',"left") then
|
||||
Camera.pos.x = Camera.pos.x - 3*game.scale
|
||||
end
|
||||
if love.keyboard.isDown('d',"right") then
|
||||
Camera.pos.x = Camera.pos.x + 3*game.scale
|
||||
end
|
||||
if love.keyboard.isDown("up", "w") then
|
||||
Camera.pos.y = Camera.pos.y - 3*game.scale
|
||||
end
|
||||
if love.keyboard.isDown("down", "s") then
|
||||
Camera.pos.y = Camera.pos.y + 3*game.scale
|
||||
if Keybind:checkPressed(Keybind.editor.palette_mode) then
|
||||
editor.palette.active = not editor.palette.active
|
||||
end
|
||||
|
||||
if palette then
|
||||
if Keybind:CheckPressed(Keybind.debug.debug) then
|
||||
|
||||
local cvel = Point:new(0, 0)
|
||||
if Keybind:checkDown(Keybind.editor.left) then
|
||||
cvel.x = -1
|
||||
end
|
||||
if Keybind:checkDown(Keybind.editor.right) then
|
||||
cvel.x = 1
|
||||
end
|
||||
if Keybind:checkDown(Keybind.editor.up) then
|
||||
cvel.y = -1
|
||||
end
|
||||
if Keybind:checkDown(Keybind.editor.down) then
|
||||
cvel.y = 1
|
||||
end
|
||||
|
||||
cvel = cvel * editor.pan.speed
|
||||
if not editor.pan.fixed then
|
||||
cvel = cvel / game.scale
|
||||
end
|
||||
|
||||
Camera.pos = Camera.pos + cvel
|
||||
|
||||
if editor.palette.active then
|
||||
if Keybind:checkPressed(Keybind.editor.palette_change) then
|
||||
local next = false
|
||||
local export = nil
|
||||
for k, v in pairs(tileset) do
|
||||
@@ -47,105 +87,178 @@ function EditorStep()
|
||||
if next then
|
||||
LevelData.tileset = export
|
||||
end
|
||||
LevelGetTileData()
|
||||
LevelIndexTiles()
|
||||
getLevelTileData()
|
||||
indexLevelTiles()
|
||||
end
|
||||
end
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.reload) then
|
||||
ExportLevel("test")
|
||||
end
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.editor) then
|
||||
editor_mode = false
|
||||
TileCreateObjects()
|
||||
if Keybind:checkPressed(Keybind.editor.save) then
|
||||
Prompt:new({
|
||||
name = "level name",
|
||||
input = "unnamed",
|
||||
func = function(name_prompt)
|
||||
if name_prompt.canceled then return end
|
||||
Prompt:new({
|
||||
name = "filename",
|
||||
input = "level.lua",
|
||||
func = function(file_prompt)
|
||||
if file_prompt.canceled then return end
|
||||
exportLevel(name_prompt.input, file_prompt.input)
|
||||
end,
|
||||
}):activate()
|
||||
end,
|
||||
}):activate()
|
||||
end
|
||||
end
|
||||
|
||||
function EditorScroll(y)
|
||||
if palette then
|
||||
function scrollEditor(y)
|
||||
if editor.palette.active then
|
||||
local scr = editor.palette.scroll
|
||||
if love.keyboard.isDown("lshift") then
|
||||
palette_scroll_y = palette_scroll_y + y
|
||||
scr.y = scr.y + y
|
||||
else
|
||||
palette_scroll_x = palette_scroll_x + y
|
||||
scr.x = scr.x + y
|
||||
end
|
||||
else
|
||||
local oscale = game.scale
|
||||
game.scale = math.max(0.1,game.scale + y/16)
|
||||
end
|
||||
end
|
||||
|
||||
function EditorDraw()
|
||||
GameworldDrawPrepare()
|
||||
GameworldDrawBackground()
|
||||
GridDisplay()
|
||||
GameworldDrawForeground()
|
||||
GameworldDrawEnd()
|
||||
EditorDoEdit()
|
||||
function drawEditor()
|
||||
startGameworldDraw()
|
||||
drawGameworldBackground()
|
||||
drawGridDisplay()
|
||||
drawGameworldForeground()
|
||||
endGameworldDraw()
|
||||
|
||||
DrawSelectingPaletteTile()
|
||||
if palette then
|
||||
EditorDoPalette()
|
||||
drawEditorRooms()
|
||||
drawSpawns()
|
||||
|
||||
doEditorEdit()
|
||||
|
||||
drawSelectingPaletteTile()
|
||||
|
||||
if editor.palette.active then
|
||||
doEditorPalette()
|
||||
end
|
||||
if editor.multiselect.box ~= nil then
|
||||
frameDebug("drawing multiselect "..tostring(editor.multiselect.box))
|
||||
drawEditorMultiselect()
|
||||
end
|
||||
end
|
||||
|
||||
function EditorDoEdit()
|
||||
function doEditorEdit()
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
local horizontal = 1+math.floor(((mouse_x/game.scale) / tileProperties.width) + (Camera.pos.x / tileProperties.width))
|
||||
local vertical = 1+math.floor(((mouse_y/game.scale) / tileProperties.height) + (Camera.pos.y / tileProperties.height))
|
||||
local horizontal = 1+math.floor(((mouse_x/game.scale) / tile_properties.width) + (Camera.pos.x / tile_properties.width))
|
||||
local vertical = 1+math.floor(((mouse_y/game.scale) / tile_properties.height) + (Camera.pos.y / tile_properties.height))
|
||||
local expand_h = 0
|
||||
local expand_v = 0
|
||||
local LevelWidth = LevelGetTileWidth()
|
||||
local LevelHeight = LevelGetTileHeight()
|
||||
local level_width = getLevelTileWidth()
|
||||
local level_height = getLevelTileHeight()
|
||||
|
||||
if horizontal > LevelWidth then
|
||||
expand_h = horizontal-LevelWidth
|
||||
if horizontal > level_width then
|
||||
expand_h = horizontal-level_width
|
||||
elseif horizontal < 0 then
|
||||
expand_h = horizontal
|
||||
end
|
||||
if vertical > LevelHeight then
|
||||
expand_v = vertical-LevelHeight
|
||||
if vertical > level_height then
|
||||
expand_v = vertical-level_height
|
||||
elseif vertical < 0 then
|
||||
expand_v = vertical
|
||||
end
|
||||
love.graphics.print("> " .. horizontal .. ", " .. vertical .. "; " .. math.floor(mouse_x / game.scale + Camera.pos.x) .. ", " .. math.floor(mouse_y / game.scale + Camera.pos.y))
|
||||
love.graphics.print("> " .. LevelWidth .. "(" .. expand_h .. "), " .. LevelHeight .. "(".. expand_v .. ")", 0, 10)
|
||||
love.graphics.setColor(100, 100, 100, 0.8)
|
||||
drawTextBox(
|
||||
"Coords: [" ..
|
||||
horizontal .. "," .. vertical .. "] (tile)\t[" ..
|
||||
math.floor(mouse_x / game.scale + Camera.pos.x) .. "," .. math.floor(mouse_y / game.scale + Camera.pos.y).."] (pixel)\n" ..
|
||||
"Level size: [" .. level_width .. ", " .. level_height .. "] +(" .. expand_h .. "," .. expand_v .. ")",
|
||||
0,
|
||||
0
|
||||
)
|
||||
|
||||
if not palette then
|
||||
if editor.room_mode then
|
||||
local rx = horizontal * tile_properties.width
|
||||
local ry = vertical * tile_properties.height
|
||||
local r = editor.room_points
|
||||
if Keybind:checkPressed(Keybind.generic.rclick) then
|
||||
editor.room_points = {}
|
||||
elseif Keybind:checkPressed(Keybind.generic.lclick) then
|
||||
if editor.room_mode == "delete" then
|
||||
for i, room in ipairs(LoadedObjects.Rooms) do
|
||||
if room:containsPoint(rx, ry) then
|
||||
table.remove(LoadedObjects.Rooms, i)
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(r, { x = rx, y = ry })
|
||||
end
|
||||
end
|
||||
if #editor.room_points == 2 then
|
||||
table.insert(LoadedObjects.Rooms, Collision:new(r[1].x-tile_properties.width,r[1].y-tile_properties.height,r[2].x,r[2].y))
|
||||
editor.room_points = {}
|
||||
end
|
||||
if editor.room_mode == "delete" then
|
||||
drawTextBox("Select room to delete", 0, 20)
|
||||
elseif #editor.room_points == 0 then
|
||||
drawTextBox("Select top left of new room", 0, 20)
|
||||
else
|
||||
drawTextBox("Select bottom right of new room", 0, 20)
|
||||
end
|
||||
elseif not editor.palette.active then
|
||||
if LevelTiles[vertical] ~= nil
|
||||
and LevelTiles[vertical][horizontal] ~= nil
|
||||
and love.keyboard.isDown("lshift") ~= true
|
||||
and love.keyboard.isDown("lctrl") ~= true
|
||||
then
|
||||
if Keybind:CheckDown(Keybind.generic.lclick)
|
||||
and selecting_tile ~= nil
|
||||
then
|
||||
SetTile(vertical,horizontal,selecting_tile)
|
||||
elseif Keybind:CheckDown(Keybind.generic.rclick) then
|
||||
SetTile(vertical,horizontal,0)
|
||||
if selecting_tile ~= nil then
|
||||
if Keybind:checkDown(Keybind.editor.tile_set) then
|
||||
setTile(vertical,horizontal,selecting_tile)
|
||||
elseif Keybind:checkDown(Keybind.editor.tile_remove) then
|
||||
setTile(vertical,horizontal,0)
|
||||
end
|
||||
reloadLevelTiles()
|
||||
else
|
||||
if Keybind:checkDown(Keybind.editor.entity_select) then
|
||||
deselectSpawns()
|
||||
if editor.multiselect.box then
|
||||
selectSpawns(editor.multiselect.box)
|
||||
end
|
||||
end
|
||||
if Keybind:checkDown(Keybind.editor.entity_move) then
|
||||
moveSpawns(mouse_x,mouse_y)
|
||||
end
|
||||
if Prompt.active_prompt == nil then
|
||||
if Keybind:checkDown(Keybind.editor.entity_modify_archetype) then
|
||||
promptSpawnArchetype()
|
||||
elseif Keybind:checkDown(Keybind.editor.entity_modify_data) then
|
||||
promptSpawnArgs()
|
||||
elseif Keybind:checkDown(Keybind.editor.entity_remove) then
|
||||
deleteSpawn()
|
||||
elseif Keybind:checkDown(Keybind.editor.entity_new) then
|
||||
promptSpawnNew()
|
||||
end
|
||||
end
|
||||
end
|
||||
LevelReloadTiles()
|
||||
|
||||
elseif Keybind:CheckPressed(Keybind.generic.lshift) then
|
||||
LevelExpandCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
LevelReloadTiles()
|
||||
elseif Keybind:CheckPressed(Keybind.generic.lctrl) then
|
||||
LevelReduceCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
LevelReloadTiles()
|
||||
elseif Keybind:checkPressed(Keybind.generic.lshift) then
|
||||
expandLevelCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
reloadLevelTiles()
|
||||
elseif Keybind:checkPressed(Keybind.generic.lctrl) then
|
||||
reduceLevelCanvas(math.sign(expand_h),math.sign(expand_v))
|
||||
reloadLevelTiles()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DrawSelectingPaletteTile()
|
||||
function drawSelectingPaletteTile()
|
||||
if selecting_tile ~= nil and selecting_tile ~= 0 then
|
||||
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
local horizontal = math.floor(((mouse_x/game.scale) / tileProperties.width) + (Camera.pos.x / tileProperties.width))
|
||||
local vertical = math.floor(((mouse_y/game.scale) / tileProperties.height) + (Camera.pos.y / tileProperties.height))
|
||||
local draw_x = tileProperties.width * horizontal - Camera.pos.x
|
||||
local draw_y = tileProperties.height * vertical - Camera.pos.y
|
||||
local horizontal = math.floor(((mouse_x/game.scale) / tile_properties.width) + (Camera.pos.x / tile_properties.width))
|
||||
local vertical = math.floor(((mouse_y/game.scale) / tile_properties.height) + (Camera.pos.y / tile_properties.height))
|
||||
local draw_x = tile_properties.width * horizontal - Camera.pos.x
|
||||
local draw_y = tile_properties.height * vertical - Camera.pos.y
|
||||
|
||||
love.graphics.draw(
|
||||
LevelData.tileset,
|
||||
@@ -156,28 +269,32 @@ function DrawSelectingPaletteTile()
|
||||
end
|
||||
end
|
||||
|
||||
function EditorDoPalette()
|
||||
|
||||
local width = LevelData.tileset:getPixelWidth()/tileProperties.width
|
||||
local height = LevelData.tileset:getPixelHeight()/tileProperties.height
|
||||
function doEditorPalette()
|
||||
local width = LevelData.tileset:getPixelWidth()/tile_properties.width
|
||||
local height = LevelData.tileset:getPixelHeight()/tile_properties.height
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
local hovering = nil
|
||||
local hov_x = nil
|
||||
local hov_y = nil
|
||||
local output = ""
|
||||
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.rectangle(
|
||||
"fill",
|
||||
(palette_scroll_x + 1) * (tileProperties.width+1),
|
||||
(palette_scroll_y + 1) * (tileProperties.height+1),
|
||||
1 + LevelData.tileset:getPixelWidth() * ((tileProperties.width+1) / tileProperties.width),
|
||||
1 + LevelData.tileset:getPixelHeight()* ((tileProperties.height+1) / tileProperties.height)
|
||||
(editor.palette.scroll.x + 1) * (tile_properties.width+1),
|
||||
(editor.palette.scroll.y + 1) * (tile_properties.height+1),
|
||||
1 + LevelData.tileset:getPixelWidth() * ((tile_properties.width+1) / tile_properties.width),
|
||||
1 + LevelData.tileset:getPixelHeight()* ((tile_properties.height+1) / tile_properties.height)
|
||||
)
|
||||
|
||||
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
|
||||
local position_x = 1
|
||||
local position_y = 1
|
||||
for i = 1, #TileIndex-width-1 do
|
||||
|
||||
local tile_x = (palette_scroll_x + position_x) * (tileProperties.width+1)
|
||||
local tile_y = (palette_scroll_y + position_y) * (tileProperties.height+1)
|
||||
local tile_x = (editor.palette.scroll.x + position_x) * (tile_properties.width+1)
|
||||
local tile_y = (editor.palette.scroll.y + position_y) * (tile_properties.height+1)
|
||||
|
||||
love.graphics.draw(
|
||||
LevelData.tileset,
|
||||
@@ -188,22 +305,21 @@ function EditorDoPalette()
|
||||
1,
|
||||
1
|
||||
)
|
||||
if Keybind:CheckDown(Keybind.generic.lclick) then
|
||||
local mouse_x = love.mouse.getX()
|
||||
local mouse_y = love.mouse.getY()
|
||||
|
||||
if mouse_x > (tile_x) * game.scale
|
||||
and mouse_x < (tile_x + tileProperties.width) * game.scale
|
||||
and mouse_y > (tile_y) * game.scale
|
||||
and mouse_y < (tile_y + tileProperties.height) * game.scale
|
||||
then
|
||||
selecting_tile = position_x + ((position_y-1) * width)
|
||||
|
||||
love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y, 0, 20)
|
||||
if mouse_x > (tile_x) * game.scale
|
||||
and mouse_x < (tile_x + tile_properties.width) * game.scale
|
||||
and mouse_y > (tile_y) * game.scale
|
||||
and mouse_y < (tile_y + tile_properties.height) * game.scale
|
||||
then
|
||||
hovering = position_x + ((position_y-1) * width)
|
||||
hov_x = tile_x
|
||||
hov_y = tile_y
|
||||
if Keybind:checkDown(Keybind.generic.lclick) then
|
||||
selecting_tile = hovering
|
||||
end
|
||||
end
|
||||
|
||||
if Keybind:CheckDown(Keybind.generic.rclick) then
|
||||
if Keybind:checkDown(Keybind.generic.rclick) then
|
||||
selecting_tile = nil
|
||||
end
|
||||
|
||||
@@ -213,8 +329,8 @@ function EditorDoPalette()
|
||||
"line",
|
||||
tile_x,
|
||||
tile_y,
|
||||
tileProperties.width,
|
||||
tileProperties.height
|
||||
tile_properties.width,
|
||||
tile_properties.height
|
||||
)
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
end
|
||||
@@ -230,9 +346,47 @@ function EditorDoPalette()
|
||||
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
(palette_scroll_x + 1) * (tileProperties.width+1),
|
||||
(palette_scroll_y + 1) * (tileProperties.height+1),
|
||||
1 + LevelData.tileset:getPixelWidth() * ((tileProperties.width+1) / tileProperties.width),
|
||||
1 + LevelData.tileset:getPixelHeight()* ((tileProperties.height+1) / tileProperties.height)
|
||||
(editor.palette.scroll.x + 1) * (tile_properties.width+1),
|
||||
(editor.palette.scroll.y + 1) * (tile_properties.height+1),
|
||||
1 + LevelData.tileset:getPixelWidth() * ((tile_properties.width+1) / tile_properties.width),
|
||||
1 + LevelData.tileset:getPixelHeight()* ((tile_properties.height+1) / tile_properties.height)
|
||||
)
|
||||
|
||||
local tile = "none"
|
||||
if selecting_tile ~= nil then
|
||||
tile = "#"..selecting_tile
|
||||
end
|
||||
output = output .. "Selected: " .. tile
|
||||
|
||||
if hovering ~= nil then
|
||||
output = output .. " \nHovering: #".. hovering .. "\nImage coords: " .. hov_x .. ", " .. hov_y
|
||||
end
|
||||
|
||||
drawTextBox(
|
||||
output,
|
||||
(editor.palette.scroll.x + 1+width) * (tile_properties.width+1),
|
||||
(editor.palette.scroll.y + 1) * (tile_properties.height+1)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
function drawEditorRooms()
|
||||
for _, room in pairs(LoadedObjects.Rooms) do
|
||||
love.graphics.setColor(0,0,1,1)
|
||||
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
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
Arrow = Entity:New()
|
||||
Arrow = class(Entity, {
|
||||
type = "Arrow",
|
||||
display = Animation:new(animation.kupo.arrow),
|
||||
})
|
||||
|
||||
function Arrow:New(x,y,rotation,speed)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
o.type = "arrow"
|
||||
function Arrow:new(x,y,rotation,speed)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
o.speed = speed or 10
|
||||
@@ -17,40 +19,49 @@ function Arrow:New(x,y,rotation,speed)
|
||||
o.illuminated = true
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation.kupo.arrow)
|
||||
o.body = Animation:new(animation.kupo.arrow)
|
||||
|
||||
o.boxCollision = {
|
||||
o.box = {
|
||||
from = {x = -0.5, y = -0.5}, --gameworld pixels
|
||||
to = {x = 0.5, y = 0.5} -- gameworld pixels
|
||||
}
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
o:id()
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Arrow:DrawBackground()
|
||||
self:Draw(self.body)
|
||||
function Arrow:drawBackground()
|
||||
self:draw(self.body)
|
||||
end
|
||||
|
||||
function Arrow:DoPhysics()
|
||||
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
else
|
||||
self.stuck = true
|
||||
end
|
||||
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
else
|
||||
self.stuck = true
|
||||
function Arrow:doPhysics()
|
||||
-- horizontal collision
|
||||
self:moveX(
|
||||
self.vel.x,
|
||||
function()
|
||||
self.stuck = true
|
||||
end
|
||||
)
|
||||
|
||||
if not self.stuck then
|
||||
-- vertical collision
|
||||
self:moveY(
|
||||
self.vel.y,
|
||||
function()
|
||||
self.stuck = true
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
if self.stuck then
|
||||
self.pos.x = self.pos.x + self.vel.x * (2/3)
|
||||
self.pos.y = self.pos.y + self.vel.y * (2/3)
|
||||
self.vel.x = 0
|
||||
self.vel.y = 0
|
||||
end
|
||||
|
||||
self:adjustLight()
|
||||
end
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
CursedBook = Entity:New()
|
||||
CursedBook = class(Entity, {
|
||||
type = "CursedBook",
|
||||
display = Animation:new(animation.cursed_book.flying),
|
||||
})
|
||||
|
||||
function CursedBook:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
function CursedBook:new(x,y)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.type = "cursed_book"
|
||||
-- behaviour
|
||||
o.pos = {x = x, y = y}
|
||||
o.speed = 0.01
|
||||
@@ -20,36 +22,40 @@ function CursedBook:New(x,y)
|
||||
o.attack_range = 50
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation.cursed_book.spawn)
|
||||
o.body = Animation:new(animation.cursed_book.spawn)
|
||||
o.body.speed = 0
|
||||
o.sprite_tint = {0.7,0.7,0.7}
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
o:createBox(o.body)
|
||||
|
||||
-- light
|
||||
o.light_range = 500
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.light_range,2,HEX2RGB("#fe00d1"))
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
local light_data = {}
|
||||
light_data.radius = 500
|
||||
light_data.shine_radius = 0
|
||||
light_data.flicker = nil
|
||||
light_data.color = nil
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function CursedBook:Smart()
|
||||
self.target.x = main_Player.pos.x - main_Player.target_offset.x
|
||||
self.target.y = main_Player.pos.y - main_Player.target_offset.y
|
||||
function CursedBook:doLogic()
|
||||
print(self.status)
|
||||
self.target.x = main_player.pos.x - main_player.target_offset.x
|
||||
self.target.y = main_player.pos.y - main_player.target_offset.y
|
||||
|
||||
local distance_x = self.target.x - self.pos.x
|
||||
local distance_y = self.target.y - self.pos.y
|
||||
local angle = GetAngleFromVector(distance_x,distance_y)
|
||||
local angle = getAngleFromVector(distance_x,distance_y)
|
||||
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
|
||||
|
||||
if self.status == 0 then
|
||||
if distance < self.spawn_range then
|
||||
self.status = 1
|
||||
end
|
||||
elseif self.status == -1 then
|
||||
elseif self.status == 2 then
|
||||
if distance < self.range then
|
||||
self.vel.x = 0
|
||||
self.vel.y = 0
|
||||
@@ -59,22 +65,30 @@ function CursedBook:Smart()
|
||||
end
|
||||
elseif self.status == 2 then
|
||||
if distance < self.attack_range then
|
||||
self.status = 3
|
||||
--self.status = 3
|
||||
end
|
||||
elseif self.status == 4 then
|
||||
|
||||
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
|
||||
|
||||
function CursedBook:HandleAnimation()
|
||||
function CursedBook:handleAnimation()
|
||||
if self.status == 1 then
|
||||
if self.body.path == "assets/entities/cursed_book/spawn" then
|
||||
self.body.speed = 1/3
|
||||
local tint = 0.7 + 0.3 * (self.body.frame-1)/self.body.frames
|
||||
self.body.speed = 1
|
||||
local tint = 0.7 + 0.3 * (self.body.frame-1)/#self.body.frames
|
||||
self.sprite_tint = {tint,tint,tint}
|
||||
if self.body.frame == self.body.frames then
|
||||
if self.body.frame == #self.body.frames then
|
||||
self.status = 2
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.flying)
|
||||
self.isFlying = true
|
||||
self.body = self.body:change(animation.cursed_book.flying)
|
||||
self.sprite_tint = {1,1,1}
|
||||
--self:getBoundingBox(self.body,2,2,-2,-2)
|
||||
self:centerOffset(self.body)
|
||||
@@ -82,38 +96,44 @@ function CursedBook:HandleAnimation()
|
||||
end
|
||||
elseif self.status == 3 then
|
||||
if self.body.path == "assets/entities/cursed_book/flying" then
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.attack_transition)
|
||||
self.body.speed = 1/3
|
||||
self:centerOffset(self.body)
|
||||
if self.body.frame == self.body.frames then
|
||||
self.body = self.body:change(animation.cursed_book.attack_transition)
|
||||
self.body.speed = 1
|
||||
--self:centerOffset(self.body)
|
||||
if self.body.frame == #self.body.frames then
|
||||
self.status = 4
|
||||
self.body = self.body:ChangeTo(animation.cursed_book.attack_loop)
|
||||
self.body = self.body:change(animation.cursed_book.attack_loop)
|
||||
self:centerOffset(self.body)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
end
|
||||
|
||||
function CursedBook:DoPhysics()
|
||||
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
|
||||
-- move
|
||||
|
||||
self:CollisionMove()
|
||||
self:LightAdjust()
|
||||
function CursedBook:doPhysics()
|
||||
-- horizontal collision
|
||||
self:moveX(
|
||||
self.vel.x,
|
||||
function()
|
||||
self.vel.x = 0
|
||||
end
|
||||
)
|
||||
-- vertical collision
|
||||
self:moveY(
|
||||
self.vel.y,
|
||||
function()
|
||||
self.vel.y = 0
|
||||
end
|
||||
)
|
||||
-- final position
|
||||
self:adjustLight()
|
||||
end
|
||||
|
||||
function CursedBook:Debug()
|
||||
function CursedBook:debug()
|
||||
-- draw center GREEN
|
||||
love.graphics.setColor(0,1,0)
|
||||
love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.spawn_range)
|
||||
love.graphics.setColor(1,0,0)
|
||||
love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.attack_range)
|
||||
Entity.Debug(self)
|
||||
Entity.debug(self)
|
||||
end
|
||||
|
||||
@@ -1,34 +1,32 @@
|
||||
Decoration = Entity:New()
|
||||
Decoration = class(Entity, {
|
||||
type = "Decoration",
|
||||
supertype = Entity.type,
|
||||
display = Animation:new(animation.particle.simple),
|
||||
})
|
||||
|
||||
function Decoration:New(x,y,animation,lightRange)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
o.type = "decoration"
|
||||
function Decoration:new(x,y,animation,light_data)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
|
||||
if lightRange ~= nil then
|
||||
o.lightRange = lightRange
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.lightRange)
|
||||
if animation then
|
||||
o.body = Animation:new(animation)
|
||||
o:centerOffset(o.body)
|
||||
o:createBox(o.body)
|
||||
end
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
if light_data then
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
end
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Decoration:HandleAnimation()
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
function Decoration:handleAnimation()
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
end
|
||||
|
||||
function Decoration:DoPhysics()
|
||||
end
|
||||
require "code/entities/decorations/candelabra"
|
||||
|
||||
54
code/entities/decorations/candelabra.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
Candelabra = class(Decoration, {
|
||||
type = "Candelabra",
|
||||
display = Animation:new(animation.decoration.candelabra),
|
||||
})
|
||||
|
||||
function Candelabra:new(x,y)
|
||||
local light_data = {}
|
||||
light_data.radius = 100
|
||||
light_data.color = hex2rgb("#fed100")
|
||||
|
||||
local o = Decoration:new(x,y,animation.decoration.candelabra,light_data)
|
||||
|
||||
o.particle_rate = 5
|
||||
o.particle_count = 0
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Candelabra:handleAnimation()
|
||||
if self.body.was_updated then
|
||||
self.particle_count = self.particle_count + 1
|
||||
while self.particle_count >= self.particle_rate do
|
||||
local pos = math.floor(math.random(1,3))-2
|
||||
|
||||
local particle_data = {}
|
||||
particle_data.animation = animation.particle.simple
|
||||
particle_data.sprite_tint = hex2rgb("#ffffff")
|
||||
particle_data.sprite_alpha_fade = true
|
||||
particle_data.direction = -math.rad(90)
|
||||
particle_data.speed = 0.5 + math.random(2)*0.005
|
||||
particle_data.time = 0.5+math.random(0.5)
|
||||
particle_data.animation_speed = 1/particle_data.time
|
||||
|
||||
particle_data.func = function(self)
|
||||
--COSINE WAVE FUNCTION
|
||||
--init variables and constants
|
||||
self.t = self.t or 0
|
||||
self.phase = self.phase or math.random(2*math.pi)
|
||||
local dt = 0.5
|
||||
local amplitude = 0.5
|
||||
local frequency = 0.5/game.framerate
|
||||
--calc
|
||||
self.t = self.t + dt
|
||||
self:moveX(amplitude*math.cos(2*math.pi*frequency*self.t+self.phase))
|
||||
end
|
||||
|
||||
Particle:new(self.pos.x+pos*5,self.pos.y-3,particle_data)
|
||||
self.particle_count = self.particle_count - self.particle_rate
|
||||
end
|
||||
end
|
||||
Decoration.handleAnimation(self)
|
||||
end
|
||||
@@ -1,9 +1,10 @@
|
||||
Fairy = Entity:New()
|
||||
Fairy = class(Entity, {
|
||||
type = "Fairy",
|
||||
display = Animation:new(animation.fairy.flying),
|
||||
})
|
||||
|
||||
function Fairy:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
o.type = "fairy"
|
||||
function Fairy:new(x,y)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
-- behaviour
|
||||
o.pos = {x = x, y = y}
|
||||
@@ -11,40 +12,40 @@ function Fairy:New(x,y)
|
||||
o.range = 20
|
||||
o.vision_range = 120
|
||||
o.target = {x = x, y = y}
|
||||
o.hover_distance = 60
|
||||
o.hover_distance = 40
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation.fairy.flying)
|
||||
o.body = Animation:new(animation.fairy.flying)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
o:createBox(o.body)
|
||||
|
||||
-- light
|
||||
o.light_range = 80
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.light_range,nil,HEX2RGB("#fed100"))
|
||||
local light_data = {}
|
||||
light_data.radius = 80
|
||||
light_data.shine_radius = 80
|
||||
light_data.flicker = nil
|
||||
light_data.color = hex2rgb("#fed100")
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
|
||||
-- timer
|
||||
o.particle_timer = 0
|
||||
o.particle_time = 5
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Fairy:Smart()
|
||||
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.y = main_Player.pos.y + main_Player.target_offset.y
|
||||
self.target.x = main_player.pos.x + main_player.target_offset.x
|
||||
self.target.y = main_player.pos.y + main_player.target_offset.y
|
||||
|
||||
local below = 1
|
||||
while not isThereObjectAt(
|
||||
self.target.x,
|
||||
self.target.y + below * game.scale,
|
||||
self.pos.x,
|
||||
self.pos.y + below * game.scale,
|
||||
LoadedObjects.Collisions
|
||||
) do
|
||||
below = below + 1
|
||||
@@ -52,8 +53,8 @@ function Fairy:Smart()
|
||||
end
|
||||
local top = 1
|
||||
while not isThereObjectAt(
|
||||
self.target.x,
|
||||
self.target.y - top * game.scale,
|
||||
self.pos.x,
|
||||
self.pos.y - top * game.scale,
|
||||
LoadedObjects.Collisions
|
||||
) do
|
||||
top = top + 1
|
||||
@@ -64,52 +65,69 @@ function Fairy:Smart()
|
||||
|
||||
local distance_x = self.target.x - self.pos.x
|
||||
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)
|
||||
|
||||
if distance < self.range then
|
||||
self.vel.x = self.vel.x * 0.9
|
||||
self.vel.y = self.vel.y * 0.9
|
||||
local random_x = math.random(-1, 1)
|
||||
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
|
||||
self.vel.x = math.cos(angle)*self.speed
|
||||
self.vel.y = math.sin(angle)*self.speed
|
||||
local random_x = math.random(-6, 6)
|
||||
local random_y = math.random(-6, 6)
|
||||
self.vel.x = math.cos(angle)*self.speed + random_x/10
|
||||
self.vel.y = math.sin(angle)*self.speed + random_y/10
|
||||
end
|
||||
end
|
||||
|
||||
function Fairy:handleAnimation()
|
||||
self.body:animate()
|
||||
--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.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,
|
||||
sprite_tint = HEX2RGB("#fed100"),
|
||||
direction = angle-math.rad(180+math.random(60)-30),
|
||||
speed = 0.8*(distance/50),
|
||||
speed_increase = -0.01,
|
||||
}
|
||||
Particle:New(self.pos.x,self.pos.y,particle_data)
|
||||
local particle_data = {}
|
||||
particle_data.animation = animation.particle.simple
|
||||
particle_data.animation_speed = 1
|
||||
particle_data.sprite_tint = hex2rgb("#fed100")
|
||||
particle_data.sprite_alpha_fade = true
|
||||
particle_data.direction = angle-math.rad(180+math.random(60)-30)
|
||||
particle_data.speed = 1
|
||||
particle_data.time = 0.75
|
||||
particle_data.func = function(self)
|
||||
self.speed = self.speed - 0.01
|
||||
self.vel.x = self.speed * math.cos(self.direction)
|
||||
self.vel.y = self.speed * math.sin(self.direction)
|
||||
end
|
||||
Particle:new(self.pos.x,self.pos.y,particle_data)
|
||||
end
|
||||
end
|
||||
|
||||
function Fairy:HandleAnimation()
|
||||
self.body:Animate()
|
||||
--if self:isCollidingWith(main_Player) then self.sprite_tint = {1,0,0} else self.sprite_tint = {1,1,1} end
|
||||
self:Draw(self.body)
|
||||
function Fairy:doPhysics()
|
||||
-- horizontal collision
|
||||
self:moveX(
|
||||
self.vel.x,
|
||||
function()
|
||||
self.vel.x = 0
|
||||
end
|
||||
)
|
||||
-- vertical collision
|
||||
self:moveY(
|
||||
self.vel.y,
|
||||
function()
|
||||
self.vel.y = 0
|
||||
end
|
||||
)
|
||||
-- final position
|
||||
self:adjustLight()
|
||||
end
|
||||
|
||||
function Fairy:DoPhysics()
|
||||
local random_x = math.random(-4, 4)/10
|
||||
local random_y = math.random(-4, 4)/10
|
||||
|
||||
self.vel.x = self.vel.x + random_x
|
||||
self.vel.y = self.vel.y + random_y
|
||||
|
||||
self:CollisionMove()
|
||||
self.vel.x = 0
|
||||
self.vel.y = 0
|
||||
|
||||
self:LightAdjust()
|
||||
end
|
||||
|
||||
function Fairy:Debug()
|
||||
Entity.Debug(self)
|
||||
self:CheckVisionLineDebug(main_Player,self.vision_range)
|
||||
function Fairy:debug()
|
||||
Entity.debug(self)
|
||||
self:checkVisionLineDebug(main_player,self.vision_range)
|
||||
end
|
||||
|
||||
@@ -1,46 +1,40 @@
|
||||
HookAnchor = Entity:New()
|
||||
HookAnchor = class(Entity, {
|
||||
type = "HookAnchor",
|
||||
display = Animation:new(animation.fairy.flying),
|
||||
})
|
||||
|
||||
function HookAnchor:New(x,y,hookDistance)
|
||||
local o = Entity:New(x,y)
|
||||
function HookAnchor:new(x,y,hook_distance)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.type = "hook_anchor"
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
o.hookDistance = hookDistance or 100
|
||||
o.hook_distance = hook_distance or 100
|
||||
-- animations
|
||||
o.body = Animation:New(animation.fairy.flying)
|
||||
o.body = Animation:new(animation.fairy.flying)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
o:createBox(o.body)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function HookAnchor:HandleAnimation()
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
function HookAnchor:handleAnimation()
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
end
|
||||
|
||||
function HookAnchor:DrawBackground()
|
||||
Entity.DrawBackground(self)
|
||||
function HookAnchor:drawBackground()
|
||||
Entity.drawBackground(self)
|
||||
love.graphics.setColor(1,1,1,0)
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
-Camera.pos.x + self.pos.x,
|
||||
-Camera.pos.y + self.pos.y,
|
||||
self.hookDistance
|
||||
self.hook_distance
|
||||
)
|
||||
end
|
||||
|
||||
function HookAnchor:DoPhysics()
|
||||
end
|
||||
|
||||
|
||||
function Fairy:Debug()
|
||||
Entity.Debug(self)
|
||||
function Fairy:debug()
|
||||
Entity.debug(self)
|
||||
end
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
Kupo = Entity:New()
|
||||
Kupo = class(Entity, {
|
||||
type = "Kupo",
|
||||
display = Animation:new(animation.kupo.body),
|
||||
})
|
||||
|
||||
function Kupo:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
o.type = "kupo"
|
||||
function Kupo:new(x,y)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
o.speed = 20
|
||||
@@ -12,8 +13,8 @@ function Kupo:New(x,y)
|
||||
o.sprite_offset = {x = 8, y = 5}
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(animation.kupo.body)
|
||||
o.bow = Animation:New(animation.kupo.bow)
|
||||
o.body = Animation:new(animation.kupo.body)
|
||||
o.bow = Animation:new(animation.kupo.bow)
|
||||
|
||||
-- bow
|
||||
o.bow_flip = 1
|
||||
@@ -27,27 +28,29 @@ function Kupo:New(x,y)
|
||||
o.bow_aim_frames = 8
|
||||
o.hostile = true
|
||||
|
||||
o.lightRange = o.range/2
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.lightRange)
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
-- light values
|
||||
local light_data = {}
|
||||
light_data.radius = 100
|
||||
light_data.shine_radius = 20
|
||||
light_data.flicker = nil
|
||||
light_data.color = nil
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Kupo:Smart()
|
||||
self.light.pos.x = self.pos.x-self.target_offset.x
|
||||
self.light.pos.y = self.pos.y-self.target_offset.y
|
||||
function Kupo:doLogic()
|
||||
self:adjustLight(self.target_offset.x,self.target_offset.y)
|
||||
|
||||
self.target.x = main_Player.pos.x - main_Player.target_offset.x
|
||||
self.target.y = main_Player.pos.y - main_Player.target_offset.y
|
||||
self.target.x = main_player.pos.x - main_player.target_offset.x
|
||||
self.target.y = main_player.pos.y - main_player.target_offset.y
|
||||
local distance_x = self.target.x - self.pos.x
|
||||
local distance_y = self.target.y - self.pos.y
|
||||
|
||||
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
|
||||
if distance <= self.range then
|
||||
if self.hostile == true then
|
||||
@@ -89,7 +92,7 @@ function Kupo:Smart()
|
||||
if self.bow_aim_frame > self.bow_aim_frames then
|
||||
self.bow_aim_frame = self.bow_aim_frame - self.bow_aim_frames
|
||||
self.bow_frame = self.bow_frame + 1
|
||||
Arrow:New(self.pos.x,self.pos.y,self.bow_rotation,10)
|
||||
Arrow:new(self.pos.x,self.pos.y,self.bow_rotation,10)
|
||||
end
|
||||
else
|
||||
self.bow_frame = self.bow_frame + 1
|
||||
@@ -130,7 +133,7 @@ function Kupo:Smart()
|
||||
self.angle = angle
|
||||
end
|
||||
|
||||
function Kupo:HandleAnimation()
|
||||
function Kupo:handleAnimation()
|
||||
local distance_x = self.target.x - self.pos.x
|
||||
local distance_y = self.target.y - self.pos.y
|
||||
|
||||
@@ -143,11 +146,11 @@ function Kupo:HandleAnimation()
|
||||
-- flip sprite to look in the direction is moving
|
||||
if self.vel.x ~= 0 then self.sprite_flip.x = math.sign(self.vel.x) end
|
||||
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
|
||||
if self.draw_bow == true then
|
||||
self.bow:DrawFrame(
|
||||
self.bow:drawFrame(
|
||||
math.min(self.bow_frame,self.bow_frames),
|
||||
self.pos.x + ( 8 * math.sin(self.bow_rotation)),
|
||||
self.pos.y + (2 - 6 * math.cos(self.bow_rotation)),
|
||||
@@ -155,7 +158,3 @@ function Kupo:HandleAnimation()
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function Kupo:DoPhysics()
|
||||
self:CollisionMove()
|
||||
end
|
||||
|
||||
@@ -1,24 +1,35 @@
|
||||
Particle = Entity:New()
|
||||
LoadedObjects.Particles = {}
|
||||
Particle = class(Entity, {
|
||||
type = "Particle",
|
||||
display = Animation:new(animation.particle.simple),
|
||||
})
|
||||
|
||||
function Particle:New(x,y,particle_data)
|
||||
local o = Entity:New(x,y)
|
||||
function Particle:new(x,y,particle_data)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
|
||||
o.speed = particle_data.speed or 0
|
||||
o.direction = particle_data.direction or o.direction
|
||||
o.sprite_rotation = particle_data.sprite_rotation or o.sprite_rotation
|
||||
o.sprite_offset = particle_data.sprite_offset or o.sprite_offset
|
||||
o.sprite_scale = particle_data.sprite_scale or o.sprite_scale
|
||||
o.sprite_tint = particle_data.sprite_tint or o.sprite_tint
|
||||
o.sprite_alpha = particle_data.sprite_alpha or o.sprite_alpha
|
||||
o.direction = particle_data.direction or 0
|
||||
o.sprite_rotation = particle_data.sprite_rotation or 0
|
||||
o.sprite_offset = particle_data.sprite_offset or vector(0,0)
|
||||
o.sprite_scale = particle_data.sprite_scale or vector(1,1)
|
||||
o.sprite_tint = particle_data.sprite_tint or {1,1,1}
|
||||
o.sprite_alpha = particle_data.sprite_alpha or 1
|
||||
o.sprite_alpha_fade = particle_data.sprite_alpha_fade or false
|
||||
o.sprite_alpha_base = o.sprite_alpha
|
||||
o.sprite_flip = particle_data.sprite_flip or vector(1,1)
|
||||
o.func = particle_data.func or nil
|
||||
o.time = particle_data.time or nil
|
||||
|
||||
o.sprite_flip = particle_data.sprite_flip or o.sprite_flip
|
||||
o.animation_active = particle_data.animation_active or false
|
||||
|
||||
o.time = 0.5
|
||||
if o.time 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.vel = {
|
||||
@@ -26,75 +37,96 @@ function Particle:New(x,y,particle_data)
|
||||
y = o.speed * math.sin(o.direction)
|
||||
}
|
||||
|
||||
o.speed_increase = particle_data.speed_increase or 0
|
||||
|
||||
if particle_data.light ~= nil then
|
||||
o.lightRange = particle_data.light
|
||||
local flicker = particle_data.light_flicker or nil
|
||||
local color = particle_data.light_color or nil
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.lightRange,flicker,color)
|
||||
if particle_data.light then
|
||||
local light_data = {}
|
||||
light_data.radius = particle_data.light
|
||||
light_data.shine_radius = particle_data.light_shine or nil
|
||||
light_data.flicker = particle_data.light_flicer or nil
|
||||
light_data.color = particle_data.light_color or nil
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
end
|
||||
|
||||
-- animations
|
||||
if particle_data.animation ~= nil then
|
||||
o.body = Animation:New(particle_data.animation)
|
||||
if particle_data.animation then
|
||||
o.body = Animation:new(particle_data.animation,particle_data.animation_speed)
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body)
|
||||
if not o.animation_active then
|
||||
o.body.speed = 0
|
||||
end
|
||||
o:createBox(o.body)
|
||||
end
|
||||
|
||||
table.remove(LoadedObjects.Entities,#LoadedObjects.Entities)
|
||||
table.insert(LoadedObjects.Particles,o)
|
||||
o.id = #LoadedObjects.Particles
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Particle:Kill()
|
||||
if self.light ~= nil then
|
||||
self.light:Kill()
|
||||
function Particle:kill()
|
||||
if self.light then
|
||||
self.light:kill()
|
||||
end
|
||||
if self.id ~= nil then
|
||||
for _, e in pairs(LoadedObjects.Particles) do
|
||||
if e.id > self.id then
|
||||
e.id = e.id - 1
|
||||
end
|
||||
self.dead = true
|
||||
end
|
||||
|
||||
function Particle:handleAnimation()
|
||||
self.timer = self.timer + 1
|
||||
|
||||
if self.sprite_alpha_fade ~= false then
|
||||
self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time
|
||||
end
|
||||
|
||||
if self.body then
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
end
|
||||
end
|
||||
|
||||
function Particle:doLogic()
|
||||
if self.func then
|
||||
self:func()
|
||||
end
|
||||
|
||||
if self.time then
|
||||
if self.timer >= self.time then self:kill() end
|
||||
end
|
||||
end
|
||||
|
||||
function cleanDeadParticles()
|
||||
for i=1, #LoadedObjects.Particles do
|
||||
part = LoadedObjects.Particles[i]
|
||||
if part.kill then
|
||||
table.remove(LoadedObjects.Particles,i)
|
||||
end
|
||||
table.remove(LoadedObjects.Particles,self.id)
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
function Particle:HandleAnimation()
|
||||
self.timer = self.timer + current_dt
|
||||
self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time
|
||||
if self.light ~= nil then
|
||||
self:LightAdjust()
|
||||
self.light.range = self.lightRange * self.sprite_alpha/2
|
||||
end
|
||||
if self.sprite_alpha < 0 then self:Kill() end
|
||||
if self.body ~= nil then
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
end
|
||||
end
|
||||
|
||||
function Particle:DoPhysics()
|
||||
-- adjust speed
|
||||
if self.speed_increase ~= 0 then
|
||||
self.speed = self.speed + self.speed_increase
|
||||
self.vel.x = self.speed * math.cos(self.direction)
|
||||
self.vel.y = self.speed * math.sin(self.direction)
|
||||
end
|
||||
-- move
|
||||
self:CollisionMove()
|
||||
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
|
||||
love.graphics.setColor(0,1,1)
|
||||
love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1)
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
function cleanDeadParticles()
|
||||
for i=1, #LoadedObjects.Particles do
|
||||
part = LoadedObjects.Particles[i]
|
||||
if part and part.dead then
|
||||
table.remove(LoadedObjects.Particles,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
@@ -1,152 +1,154 @@
|
||||
Player = Entity:New()
|
||||
Player = class(Entity, {
|
||||
type = "Player",
|
||||
display = Animation:new(animation.nancy.idle),
|
||||
})
|
||||
|
||||
function Player:New(x,y)
|
||||
local o = Entity:New(x,y)
|
||||
function Player:new(x,y)
|
||||
local o = Entity:new(x,y)
|
||||
|
||||
o.type = "player"
|
||||
-- physics
|
||||
o.moveSpeed = 1.3 -- gameworld pixels
|
||||
o.zeroSpeed = 0.01 -- gameworld pixels
|
||||
o.zero_speed = 0.01 -- gameworld pixels
|
||||
|
||||
o.move_x = 0 -- gameworld pixels
|
||||
o.noDriftFrames = 0 -- frames
|
||||
o.move_speed = 1.3 -- gameworld pixels
|
||||
|
||||
o.airFriction = 0.01 -- gameworld pixels
|
||||
o.groundFriction = 0.3 -- gameworld pixels
|
||||
o.nodrift_frames = 0 -- frames
|
||||
|
||||
o.jumpImpulse = 3.5 -- gameworld pixels
|
||||
o.air_friction = 0.01 -- gameworld pixels
|
||||
o.ground_friction = 0.3 -- gameworld pixels
|
||||
o.wall_friction = 0.3 -- gameworld pixels
|
||||
|
||||
o.coyoteValue = 5 -- frames
|
||||
o.coyoteAmount = 5 -- int
|
||||
o.jump_impulse = 3.5 -- gameworld pixels
|
||||
|
||||
o.coyote_value = 5 -- frames
|
||||
o.coyote_amount = 5 -- int
|
||||
|
||||
o.dashCooldownTime = 0.1 -- seconds
|
||||
o.dashCooldownTimer = 0 -- seconds
|
||||
|
||||
-- dash values
|
||||
o.dashTimer = 0 -- seconds
|
||||
o.dashTime = 0.15 -- seconds
|
||||
o.dashDistance = 40 -- gameworld pixels
|
||||
o.dashSpeed = o.dashDistance / (o.dashTime*60) -- pixels
|
||||
o.dashCount = 1 -- int
|
||||
o.dashAmount = 10 -- int
|
||||
o.dash_timer = 0 -- seconds
|
||||
o.dash_time = 0.15 -- seconds
|
||||
o.dash_distance = 40 -- gameworld pixels
|
||||
o.dash_speed = o.dash_distance / (o.dash_time*60) -- pixels
|
||||
o.dash_count = 1 -- int
|
||||
o.dash_amount = 10 -- int
|
||||
o.dash_cooldown_time = 0.1 -- seconds
|
||||
o.dash_cooldown_timer = 0 -- seconds
|
||||
|
||||
-- hook values
|
||||
o.hookSwingSpeed = math.rad(0.05)
|
||||
o.hookAnchor = {
|
||||
x = nil,
|
||||
y = nil
|
||||
}
|
||||
o.hook_swing_speed = math.rad(0.05)
|
||||
o.hook_anchor = nil
|
||||
|
||||
-- walljump values
|
||||
o.walljumpNoDriftAmount = 12
|
||||
o.walljumpImpulse = { x = 2.5, y = 3.5 }
|
||||
o.walljumpFriction = 0.3 -- gameworld pixels
|
||||
|
||||
-- light values
|
||||
o.lightRange = 40 -- screen pixels
|
||||
o.walljump_nodrift_amount = 12
|
||||
o.walljump_impulse = { x = 2.5, y = 3.5 }
|
||||
|
||||
-- status
|
||||
o.canJump = true
|
||||
o.canFall = true
|
||||
o.canFriction = true
|
||||
o.canHook = true
|
||||
o.canWalljump = true
|
||||
o.can_jump = true
|
||||
o.can_fall = true
|
||||
o.can_friction = true
|
||||
o.can_hook = true
|
||||
o.can_walljump = true
|
||||
|
||||
o.isDashing = false
|
||||
o.isHooked = false
|
||||
o.isSliding = false
|
||||
o.isJumping = false
|
||||
o.isOnGround = false
|
||||
o.isOnLadder = false
|
||||
o.is_dashing = false
|
||||
o.is_hooked = false
|
||||
o.is_sliding = false
|
||||
o.is_jumping = false
|
||||
o.is_on_ground = false
|
||||
o.is_on_ladder = false
|
||||
|
||||
o.maskType = animation.moth_mask
|
||||
o.wallHit = 0
|
||||
o.mask_type = animation.moth_mask
|
||||
o.wall_hit = 0
|
||||
|
||||
o.anchorRespawn = {
|
||||
o.respawn_anchor = {
|
||||
x = o.pos.x,
|
||||
y = o.pos.y
|
||||
}
|
||||
|
||||
-- sprite
|
||||
o.target_offset = {x = 0, y = 0}
|
||||
o.body = Animation:New(animation.nancy.idle)
|
||||
o.mask = Animation:New(animation.moth_mask.idle)
|
||||
o.body = Animation:new(animation.nancy.idle)
|
||||
o.mask = Animation:new(animation.moth_mask.idle)
|
||||
|
||||
o:centerOffset(o.body)
|
||||
o:getBoundingBox(o.body,0,3,-1,-3)
|
||||
o:createBox(o.body,0,4,-1,-5)
|
||||
|
||||
-- lights
|
||||
o.light = Light:New(o.pos.x,o.pos.y,o.lightRange)
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
o.id = #LoadedObjects.Entities
|
||||
local light_data = {}
|
||||
light_data.radius = 40
|
||||
light_data.shine_radius = 20
|
||||
light_data.flicker = nil
|
||||
light_data.color = nil
|
||||
o.light = Light:new(o.pos.x,o.pos.y,light_data)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Player:Smart()
|
||||
self:LightAdjust(self.target_offset.x,self.target_offset.y)
|
||||
function Player:doLogic()
|
||||
|
||||
-- reset coyoteValue
|
||||
if self.isOnGround then
|
||||
self.coyoteValue = self.coyoteAmount
|
||||
elseif self.coyoteValue > 0 then
|
||||
self.coyoteValue = self.coyoteValue - 1
|
||||
-- reset coyote_value
|
||||
if self.is_on_ground then
|
||||
self.coyote_value = self.coyote_amount
|
||||
elseif self.coyote_value > 0 then
|
||||
self.coyote_value = self.coyote_value - 1
|
||||
end
|
||||
|
||||
-- not dashing, normal movment
|
||||
if self.dashTimer <= 0 then
|
||||
if self.dash_timer <= 0 then
|
||||
-- horizontal movement
|
||||
if not self.isHooked then
|
||||
if self.noDriftFrames > 0 then
|
||||
if not self.is_hooked then
|
||||
if self.nodrift_frames > 0 then
|
||||
self.move_x = 0
|
||||
elseif Keybind:CheckDown(Keybind.move.left) then
|
||||
elseif Keybind:checkDown(Keybind.move.left) then
|
||||
self.move_x = -1
|
||||
self.vel.x = math.min(self.vel.x, -self.moveSpeed)
|
||||
elseif Keybind:CheckDown(Keybind.move.right) then
|
||||
self.vel.x = math.min(self.vel.x, -self.move_speed)
|
||||
elseif Keybind:checkDown(Keybind.move.right) then
|
||||
self.move_x = 1
|
||||
self.vel.x = math.max(self.vel.x, self.moveSpeed)
|
||||
self.vel.x = math.max(self.vel.x, self.move_speed)
|
||||
end
|
||||
end
|
||||
|
||||
-- jump if on ground (coyotevalue) or if 0
|
||||
if self.canJump and Keybind:CheckPressed(Keybind.move.jump) then
|
||||
if self.canWalljump and self.wallHit ~= 0 then
|
||||
self.isSliding = false
|
||||
self.vel.y = -self.walljumpImpulse.y
|
||||
self.vel.x = -self.walljumpImpulse.x * self.wallHit
|
||||
if self.can_jump and Keybind:checkPressed(Keybind.move.jump) then
|
||||
if self.can_walljump and self.wall_hit ~= 0 then
|
||||
self.is_sliding = false
|
||||
self.vel.y = -self.walljump_impulse.y
|
||||
self.vel.x = -self.walljump_impulse.x * self.wall_hit
|
||||
self.move_x = 0
|
||||
self.sprite_flip.x = -self.sprite_flip.x
|
||||
self.noDriftFrames = self.walljumpNoDriftAmount
|
||||
elseif self.coyoteValue > 0 then
|
||||
self.vel.y = -self.jumpImpulse
|
||||
self.coyoteValue = 0
|
||||
self.nodrift_frames = self.walljump_nodrift_amount
|
||||
elseif self.coyote_value > 0 then
|
||||
self.vel.y = -self.jump_impulse
|
||||
self.coyote_value = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- dash timer
|
||||
self.dashCooldownTimer = math.max(0,self.dashCooldownTimer - current_dt)
|
||||
self.dash_cooldown_timer = math.max(0,self.dash_cooldown_timer - current_dt)
|
||||
|
||||
-- try to dash
|
||||
if Keybind:CheckDown(Keybind.move.dash) then
|
||||
if self.dashCooldownTimer == 0
|
||||
and not self.isDashing
|
||||
and self.dashCount > 0 then
|
||||
self:Unhook()
|
||||
if Keybind:checkDown(Keybind.move.dash) then
|
||||
if self.dash_cooldown_timer == 0
|
||||
and not self.is_dashing
|
||||
and self.dash_count > 0 then
|
||||
|
||||
self:unhook()
|
||||
self.nodrift_frames = 0
|
||||
|
||||
-- state player
|
||||
self.isDashing = true
|
||||
self.dashCount = self.dashCount - 1
|
||||
self.is_dashing = true
|
||||
self.is_sliding = false
|
||||
self.dash_count = self.dash_count - 1
|
||||
|
||||
-- get dash direction
|
||||
local vertical = 0
|
||||
if Keybind:CheckDown(Keybind.move.down) then vertical = vertical + 1 end
|
||||
if Keybind:CheckDown(Keybind.move.up) then vertical = vertical - 1 end
|
||||
if Keybind:checkDown(Keybind.move.down) then vertical = vertical + 1 end
|
||||
if Keybind:checkDown(Keybind.move.up) then vertical = vertical - 1 end
|
||||
local horizontal = 0
|
||||
if Keybind:CheckDown(Keybind.move.right) then horizontal = horizontal + 1 end
|
||||
if Keybind:CheckDown(Keybind.move.left) then horizontal = horizontal - 1 end
|
||||
if Keybind:checkDown(Keybind.move.right) then horizontal = horizontal + 1 end
|
||||
if Keybind:checkDown(Keybind.move.left) then horizontal = horizontal - 1 end
|
||||
|
||||
-- if no direction, then dash forward
|
||||
if horizontal == 0 and vertical == 0 then
|
||||
@@ -154,23 +156,23 @@ function Player:Smart()
|
||||
end
|
||||
|
||||
-- set dash values
|
||||
self.dashDirection = GetAngleFromVector(horizontal, vertical)
|
||||
self.dashTimer = math.floor(self.dashTime * game.framerate)
|
||||
self.dashDirection = getAngleFromVector(vector(horizontal, vertical))
|
||||
self.dash_timer = math.floor(self.dash_time * game.framerate)
|
||||
end
|
||||
else
|
||||
-- not dashing!
|
||||
self.isDashing = false
|
||||
self.is_dashing = false
|
||||
end
|
||||
|
||||
if self.canHook and Keybind:CheckPressed(Keybind.move.hook) then
|
||||
if self.isHooked then
|
||||
self:Unhook()
|
||||
if self.can_hook and Keybind:checkPressed(Keybind.move.hook) then
|
||||
if self.is_hooked then
|
||||
self:unhook()
|
||||
else
|
||||
local anchor = self:CheckNearest("hook_anchor",self.hookDistance)
|
||||
local anchor = self:checkNearest("HookAnchor","hook_specific")
|
||||
if anchor then
|
||||
self.isHooked = true
|
||||
self.hookDistance = anchor.hookDistance
|
||||
self.hookAnchor = {
|
||||
self.is_hooked = true
|
||||
self.hook_distance = anchor.hook_distance
|
||||
self.hook_anchor = {
|
||||
x = anchor.pos.x,
|
||||
y = anchor.pos.y
|
||||
}
|
||||
@@ -179,150 +181,166 @@ function Player:Smart()
|
||||
end
|
||||
end
|
||||
|
||||
function Player:DoPhysics()
|
||||
if self.dashTimer <= 0 then
|
||||
if self.isOnGround then
|
||||
self.vel.x = self.vel.x * (1-self.groundFriction)
|
||||
function Player:doPhysics()
|
||||
if self.dash_timer <= 0 then
|
||||
if self.is_on_ground then
|
||||
self.vel.x = self.vel.x * (1-self.ground_friction)
|
||||
else
|
||||
self.vel.x = self.vel.x * (1-self.airFriction)
|
||||
self.vel.x = self.vel.x * (1-self.air_friction)
|
||||
end
|
||||
|
||||
self.isSliding = false
|
||||
if self.wallHit == 0 then
|
||||
self.vel.y = self.vel.y * (1-self.airFriction)
|
||||
elseif self.noDriftFrames ~= self.walljumpNoDriftAmount then
|
||||
self.isSliding = true
|
||||
self.vel.y = self.vel.y * (1-self.walljumpFriction)
|
||||
self.is_sliding = false
|
||||
if self.wall_hit == 0 then
|
||||
self.vel.y = self.vel.y * (1-self.air_friction)
|
||||
elseif self.nodrift_frames ~= self.walljump_nodrift_amount then
|
||||
self.is_sliding = true
|
||||
self.vel.y = self.vel.y * (1-self.wall_friction)
|
||||
end
|
||||
|
||||
if math.abs(self.vel.x) < self.zeroSpeed then self.vel.x = 0 end
|
||||
if math.abs(self.vel.x) < self.zero_speed then self.vel.x = 0 end
|
||||
end
|
||||
|
||||
-- reset state
|
||||
self.canFall = true
|
||||
self.isOnGround = false
|
||||
self.can_fall = true
|
||||
self.is_on_ground = false
|
||||
|
||||
-- adjust timers
|
||||
self.dashTimer = self.dashTimer - 1
|
||||
self.noDriftFrames = self.noDriftFrames - 1
|
||||
self.dash_timer = self.dash_timer - 1
|
||||
self.nodrift_frames = self.nodrift_frames - 1
|
||||
|
||||
-- DASH STATE
|
||||
if self.dashTimer > 0 then
|
||||
self.canFall = false
|
||||
if self.dash_timer > 0 then
|
||||
self.can_fall = false
|
||||
-- dash particle
|
||||
local particle_data = {
|
||||
animation = self.body,
|
||||
sprite_tint = HEX2RGB("#fed100"),
|
||||
animation_speed = 0,
|
||||
sprite_tint = hex2rgb("#fed100"),
|
||||
sprite_alpha = 0.5,
|
||||
time = 0.2,
|
||||
sprite_flip = {
|
||||
x = self.sprite_flip.x,
|
||||
y = self.sprite_flip.y
|
||||
}
|
||||
}
|
||||
Particle:New(self.pos.x,self.pos.y,particle_data)
|
||||
self.dashCooldownTimer = self.dashCooldownTime
|
||||
Particle:new(self.pos.x,self.pos.y,particle_data)
|
||||
self.dash_cooldown_timer = self.dash_cooldown_time
|
||||
-- dash movement
|
||||
self.vel.x = self.dashSpeed * math.cos(self.dashDirection)
|
||||
self.vel.y = self.dashSpeed * math.sin(self.dashDirection)
|
||||
self.vel.x = self.dash_speed * math.cos(self.dashDirection)
|
||||
self.vel.y = self.dash_speed * math.sin(self.dashDirection)
|
||||
end
|
||||
|
||||
-- hook state
|
||||
if self.isHooked then
|
||||
if self.is_hooked then
|
||||
self.move_x = 0
|
||||
local hook = Vector(self.pos.x, self.pos.y, self.hookAnchor.x, self.hookAnchor.y)
|
||||
local dist = math.min(GetVectorValue(hook), self.hookDistance)
|
||||
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 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
|
||||
hook_angle = hook_angle - self.hookSwingSpeed
|
||||
if Keybind:checkDown(Keybind.move.right) then
|
||||
hook_angle = hook_angle - self.hook_swing_speed
|
||||
end
|
||||
|
||||
if Keybind:CheckDown(Keybind.move.left) then
|
||||
hook_angle = hook_angle + self.hookSwingSpeed
|
||||
if Keybind:checkDown(Keybind.move.left) then
|
||||
hook_angle = hook_angle + self.hook_swing_speed
|
||||
|
||||
end
|
||||
|
||||
local particle_data = {
|
||||
animation = self.body,
|
||||
sprite_tint = HEX2RGB("#fed100"),
|
||||
animation_speed = 0,
|
||||
sprite_tint = hex2rgb("#fed100"),
|
||||
sprite_alpha = 0.5,
|
||||
time = 4,
|
||||
time_unit = "frames",
|
||||
sprite_flip = {
|
||||
x = self.sprite_flip.x,
|
||||
y = self.sprite_flip.y
|
||||
}
|
||||
}
|
||||
Particle:New(self.pos.x,self.pos.y,particle_data)
|
||||
Particle:new(self.pos.x,self.pos.y,particle_data)
|
||||
|
||||
local pos_x = self.hookAnchor.x + dist * math.cos(hook_angle)
|
||||
local pos_y = self.hookAnchor.y + dist * math.sin(hook_angle)
|
||||
local pos_x = self.hook_anchor.x + dist * math.cos(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.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
|
||||
|
||||
|
||||
if self.canFall then
|
||||
if self.can_fall then
|
||||
-- not in dash
|
||||
self.dashTimer = 0
|
||||
self.dash_timer = 0
|
||||
self.vel.y = self.vel.y + gravity
|
||||
end
|
||||
|
||||
-- horizontal collision
|
||||
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
self.wallHit = 0
|
||||
else
|
||||
self.wallHit = math.sign(self.vel.x)
|
||||
self.vel.x = 0
|
||||
end
|
||||
self.wall_hit = 0
|
||||
self:moveX(
|
||||
self.vel.x,
|
||||
function()
|
||||
self.wall_hit = math.sign(self.vel.x)
|
||||
self.vel.x = 0
|
||||
end
|
||||
)
|
||||
|
||||
-- vertical collision
|
||||
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
else
|
||||
if self.vel.y > 0 then
|
||||
self.isOnGround = true
|
||||
self.dashCount = self.dashAmount
|
||||
self:moveY(
|
||||
self.vel.y,
|
||||
function()
|
||||
if self.vel.y > 0 then
|
||||
self.is_on_ground = true
|
||||
self.dash_count = self.dash_amount
|
||||
end
|
||||
self.vel.y = 0
|
||||
end
|
||||
self.vel.y = 0
|
||||
end
|
||||
)
|
||||
|
||||
-- if u collision w hazard, respawn
|
||||
if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then
|
||||
self:Respawn()
|
||||
self:respawn()
|
||||
end
|
||||
|
||||
self:adjustLight(self.target_offset.x,self.target_offset.y)
|
||||
end
|
||||
|
||||
function Player:Respawn()
|
||||
self.pos.x = self.anchorRespawn.x
|
||||
self.pos.y = self.anchorRespawn.y
|
||||
function Player:respawn()
|
||||
self.pos.x = self.respawn_anchor.x
|
||||
self.pos.y = self.respawn_anchor.y
|
||||
end
|
||||
|
||||
function Player:HandleAnimation()
|
||||
function Player:handleAnimation()
|
||||
-- flip sprite to look in the direction is moving
|
||||
if self.isHooked then
|
||||
if self.is_hooked then
|
||||
if self.vel.x ~= 0 then
|
||||
self.sprite_flip.x = math.sign(self.vel.x)
|
||||
end
|
||||
elseif self.move_x ~= 0 then
|
||||
self.sprite_flip.x = math.sign(self.move_x)
|
||||
end
|
||||
|
||||
-- animation priority
|
||||
if self.vel.y > 1.25 or self.isSliding then
|
||||
self.body = self.body:ChangeTo(animation.nancy.fall)
|
||||
self.mask = self.mask:ChangeTo(self.maskType.fall)
|
||||
if self.is_sliding then
|
||||
self.body = self.body:change(animation.nancy.slide)
|
||||
self.mask = self.mask:change(self.mask_type.slide)
|
||||
elseif self.vel.y > 1.25 then
|
||||
self.body = self.body:change(animation.nancy.fall)
|
||||
self.mask = self.mask:change(self.mask_type.fall)
|
||||
elseif self.vel.y < 0 then
|
||||
self.body = self.body:ChangeTo(animation.nancy.jump)
|
||||
self.mask = self.mask:ChangeTo(self.maskType.jump)
|
||||
elseif self.vel.x + self.move_x ~= 0 then
|
||||
self.body = self.body:ChangeTo(animation.nancy.run)
|
||||
self.mask = self.mask:ChangeTo(self.maskType.run)
|
||||
else
|
||||
self.body = self.body:ChangeTo(animation.nancy.idle)
|
||||
self.mask = self.mask:ChangeTo(self.maskType.idle)
|
||||
self.body = self.body:change(animation.nancy.jump)
|
||||
self.mask = self.mask:change(self.mask_type.jump)
|
||||
elseif self.vel.x + self.move_x ~= 0 and not self.is_hooked then
|
||||
self.body = self.body:change(animation.nancy.run)
|
||||
self.mask = self.mask:change(self.mask_type.run)
|
||||
elseif not self.is_hooked then
|
||||
self.body = self.body:change(animation.nancy.idle)
|
||||
self.mask = self.mask:change(self.mask_type.idle)
|
||||
end
|
||||
|
||||
-- special case: idle animation gets slower by time
|
||||
@@ -332,30 +350,31 @@ function Player:HandleAnimation()
|
||||
end
|
||||
end
|
||||
|
||||
if self.isHooked then
|
||||
if self.is_hooked then
|
||||
love.graphics.line(
|
||||
-Camera.pos.x + self.pos.x,
|
||||
-Camera.pos.y + self.pos.y,
|
||||
-Camera.pos.x + self.hookAnchor.x,
|
||||
-Camera.pos.y + self.hookAnchor.y
|
||||
-Camera.pos.x + self.hook_anchor.x,
|
||||
-Camera.pos.y + self.hook_anchor.y
|
||||
)
|
||||
end
|
||||
|
||||
self.body:Animate()
|
||||
self:Draw(self.body)
|
||||
self.body:animate()
|
||||
self:draw(self.body)
|
||||
|
||||
if self.dashCount > 0 then
|
||||
self:Draw(self.mask)
|
||||
if self.dash_count > 0 then
|
||||
self:draw(self.mask)
|
||||
end
|
||||
self.move_x = 0
|
||||
end
|
||||
|
||||
function Player:Unhook()
|
||||
self.isHooked = false
|
||||
self.hookAnchor = nil
|
||||
function Player:unhook()
|
||||
self.is_hooked = false
|
||||
self.hook_anchor = nil
|
||||
self.hook_distance = nil
|
||||
end
|
||||
|
||||
function Player:Debug()
|
||||
Entity.Debug(self)
|
||||
love.graphics.print("wallHit: "..self.wallHit)
|
||||
function Player:debug()
|
||||
Entity.debug(self)
|
||||
love.graphics.print("wall_hit: "..self.wall_hit)
|
||||
end
|
||||
|
||||
195
code/entity.lua
@@ -1,15 +1,16 @@
|
||||
Entity = {class = "Entity"}
|
||||
LoadedObjects.Entities = {}
|
||||
Entity = class(nil, {type = "Entity"})
|
||||
|
||||
function Entity:New(x,y)
|
||||
function Entity:new(x,y)
|
||||
local o = {}
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
o.move_remainder = {x = 0, y = 0}
|
||||
o.vel = {x = 0, y = 0}
|
||||
|
||||
o.direction = 0
|
||||
|
||||
o.boxCollision = {
|
||||
o.box = {
|
||||
from = {x = x, y = y},
|
||||
to = {x = x, y = y},
|
||||
}
|
||||
@@ -22,61 +23,95 @@ function Entity:New(x,y)
|
||||
o.sprite_tint = {1,1,1}
|
||||
o.sprite_alpha = 1
|
||||
o.sprite_flip = { x = 1, y = 1}
|
||||
o.illuminated = false
|
||||
|
||||
table.insert(LoadedObjects.Entities,o)
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
function Entity:CheckNearest(type,maxdistance)
|
||||
function Entity:checkNearest(type,maxdistance)
|
||||
local return_entity = nil
|
||||
local shortest = -1
|
||||
local flag_variable_distance = false
|
||||
|
||||
if maxdistance == "hook_specific" then
|
||||
flag_variable_distance = true
|
||||
end
|
||||
|
||||
for _, entity in pairs(LoadedObjects.Entities) do
|
||||
if not type or entity.type == type then
|
||||
local distance_x = entity.pos.x - self.pos.x
|
||||
local distance_y = entity.pos.y - self.pos.y
|
||||
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
|
||||
|
||||
if flag_variable_distance then
|
||||
maxdistance = entity.hook_distance
|
||||
end
|
||||
|
||||
if not maxdistance or distance < maxdistance then
|
||||
if shortest == -1 or distance < shortest then
|
||||
shortest = distance
|
||||
return_entity = entity
|
||||
end
|
||||
print(shortest,maxdistance,distance)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
return return_entity
|
||||
end
|
||||
|
||||
function Entity:Smart()
|
||||
end
|
||||
|
||||
function Entity:Move()
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
end
|
||||
|
||||
function Entity:CollisionMove()
|
||||
local r = false
|
||||
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
else
|
||||
self.vel.x = 0
|
||||
r = true
|
||||
function Entity:moveX(amount, func)
|
||||
self.move_remainder.x = self.move_remainder.x + amount
|
||||
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
|
||||
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
else
|
||||
self.vel.y = 0
|
||||
r = true
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
function Entity:LightAdjust(x,y)
|
||||
function Entity:moveY(amount, func)
|
||||
self.move_remainder.y = self.move_remainder.y + amount
|
||||
local move = math.round(self.move_remainder.y)
|
||||
if move ~= 0 then
|
||||
self.move_remainder.y = self.move_remainder.y - move
|
||||
local sign = math.sign(move)
|
||||
while math.round(move) ~= 0 do
|
||||
if not self:isCollidingAt(
|
||||
self.pos.x,
|
||||
self.pos.y + sign,
|
||||
LoadedObjects.Collisions
|
||||
) then
|
||||
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
|
||||
|
||||
function Entity:adjustLight(x,y)
|
||||
if self.light ~= nil then
|
||||
local x = x or 0
|
||||
local y = y or 0
|
||||
@@ -85,29 +120,22 @@ function Entity:LightAdjust(x,y)
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:Kill()
|
||||
function Entity:kill()
|
||||
if self.light ~= nil then
|
||||
self.light:Kill()
|
||||
self.light:kill()
|
||||
end
|
||||
if self.id ~= nil then
|
||||
for _, e in pairs(LoadedObjects.Entities) do
|
||||
if e.id > self.id then
|
||||
e.id = e.id - 1
|
||||
end
|
||||
end
|
||||
table.remove(LoadedObjects.Entities,self.id)
|
||||
end
|
||||
self = nil
|
||||
self.dead = true
|
||||
end
|
||||
|
||||
function Entity:CheckVisionLine(entity,range)
|
||||
function Entity:checkVisionLine(entity,range)
|
||||
local target_x = entity.pos.x + entity.target_offset.x
|
||||
local target_y = entity.pos.y + entity.target_offset.y
|
||||
|
||||
local distance_x = target_x - self.pos.x
|
||||
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 is_colliding = true
|
||||
@@ -128,10 +156,11 @@ function Entity:CheckVisionLine(entity,range)
|
||||
return not is_colliding
|
||||
end
|
||||
|
||||
function Entity:Draw(animation)
|
||||
function Entity:draw(animation)
|
||||
if animation == nil then return end
|
||||
local c1, c2, c3, a = love.graphics.getColor()
|
||||
love.graphics.setColor(self.sprite_tint[1],self.sprite_tint[2],self.sprite_tint[3],self.sprite_alpha)
|
||||
animation:Draw(
|
||||
animation:draw(
|
||||
self.pos.x - Camera.pos.x - ( (self.sprite_offset.x) * math.cos(self.sprite_rotation) - (self.sprite_offset.y) * math.sin(self.sprite_rotation)) * self.sprite_scale.x * self.sprite_flip.x,
|
||||
self.pos.y - Camera.pos.y - ( (self.sprite_offset.x) * math.sin(self.sprite_rotation) + (self.sprite_offset.y) * math.cos(self.sprite_rotation)) * self.sprite_scale.y * self.sprite_flip.y,
|
||||
self.sprite_rotation,
|
||||
@@ -142,46 +171,52 @@ function Entity:Draw(animation)
|
||||
end
|
||||
|
||||
function Entity:centerOffset(animation,x,y)
|
||||
if animation == nil then return end
|
||||
local x = x or 0
|
||||
local y = y or 0
|
||||
self.sprite_offset.x = animation.imgs[1]:getWidth()/2 + x
|
||||
self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y
|
||||
end
|
||||
|
||||
function Entity:getBoundingBox(animation,top,left,bottom,right)
|
||||
function Entity:createBox(animation,top,left,bottom,right)
|
||||
if animation == nil then return end
|
||||
local left = left or 0
|
||||
local right = right or 0
|
||||
local top = top or 0
|
||||
local bottom = bottom or 0
|
||||
self.boxCollision.from.x = -animation.imgs[1]:getWidth()/2 + left
|
||||
self.boxCollision.to.x = animation.imgs[1]:getWidth()/2 + right
|
||||
self.boxCollision.from.y = -animation.imgs[1]:getHeight()/2 + top
|
||||
self.boxCollision.to.y = animation.imgs[1]:getHeight()/2 + bottom
|
||||
self.box.from.x = -animation.imgs[1]:getWidth()/2 + left
|
||||
self.box.to.x = animation.imgs[1]:getWidth()/2 + right
|
||||
self.box.from.y = -animation.imgs[1]:getHeight()/2 + top
|
||||
self.box.to.y = animation.imgs[1]:getHeight()/2 + bottom
|
||||
end
|
||||
|
||||
-- checks if the the reciever would collide with an object if it was positioned at the given point.
|
||||
-- also marks collisioned tile as collision true
|
||||
function Entity:isCollidingAt(x,y,object)
|
||||
return self:getCollidingAt(x,y,object) ~= nil
|
||||
end
|
||||
|
||||
function Entity:getCollidingAt(x,y,object)
|
||||
for _, collision in pairs(object) do
|
||||
if collision.disable then
|
||||
-- Dont calculate if disabled
|
||||
elseif x + self.boxCollision.from.x < collision.to.x
|
||||
and x + self.boxCollision.to.x > collision.from.x
|
||||
and y + self.boxCollision.from.y < collision.to.y
|
||||
and y + self.boxCollision.to.y > collision.from.y
|
||||
elseif x + self.box.from.x < collision.to.x
|
||||
and x + self.box.to.x > collision.from.x
|
||||
and y + self.box.from.y < collision.to.y
|
||||
and y + self.box.to.y > collision.from.y
|
||||
then
|
||||
collision.isColliding = true
|
||||
return true
|
||||
collision.is_colliding = true
|
||||
return collision
|
||||
end
|
||||
end
|
||||
return false
|
||||
return nil
|
||||
end
|
||||
|
||||
function Entity:isCollidingWith(entity)
|
||||
return self.pos.x + self.boxCollision.from.x < entity.pos.x + entity.boxCollision.to.x
|
||||
and entity.pos.x + entity.boxCollision.from.x < self.pos.x + self.boxCollision.to.x
|
||||
and self.pos.y + self.boxCollision.from.y < entity.pos.y + entity.boxCollision.to.y
|
||||
and entity.pos.y + entity.boxCollision.from.y < self.pos.y + self.boxCollision.to.y
|
||||
return self.pos.x + self.box.from.x < entity.pos.x + entity.box.to.x
|
||||
and entity.pos.x + entity.box.from.x < self.pos.x + self.box.to.x
|
||||
and self.pos.y + self.box.from.y < entity.pos.y + entity.box.to.y
|
||||
and entity.pos.y + entity.box.from.y < self.pos.y + self.box.to.y
|
||||
end
|
||||
|
||||
function Entity:isCollidingAtAll(x,y)
|
||||
@@ -198,7 +233,7 @@ function Entity:isCollidingAtAll(x,y)
|
||||
return result
|
||||
end
|
||||
|
||||
function Entity:CheckVisionLineDebug(entity,range)
|
||||
function Entity:checkVisionLineDebug(entity,range)
|
||||
local c1, c2, c3, a = love.graphics.getColor()
|
||||
|
||||
local target_x = entity.pos.x + entity.target_offset.x
|
||||
@@ -206,8 +241,9 @@ function Entity:CheckVisionLineDebug(entity,range)
|
||||
|
||||
local distance_x = target_x - self.pos.x
|
||||
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)
|
||||
|
||||
if distance < range then
|
||||
@@ -233,7 +269,7 @@ function Entity:CheckVisionLineDebug(entity,range)
|
||||
love.graphics.setColor(c1,c2,c3,a)
|
||||
end
|
||||
|
||||
function Entity:Debug()
|
||||
function Entity:debug()
|
||||
-- draw center GREEN
|
||||
love.graphics.setColor(0,1,0)
|
||||
love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1)
|
||||
@@ -241,10 +277,10 @@ function Entity:Debug()
|
||||
love.graphics.setColor(1,0,1)
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
-Camera.pos.x + self.pos.x + self.boxCollision.from.x,
|
||||
-Camera.pos.y + self.pos.y + self.boxCollision.from.y,
|
||||
-Camera.pos.x + self.pos.x + self.boxCollision.to.x -(-Camera.pos.x + self.pos.x + self.boxCollision.from.x),
|
||||
-Camera.pos.y + self.pos.y + self.boxCollision.to.y -(-Camera.pos.y + self.pos.y + self.boxCollision.from.y)
|
||||
-Camera.pos.x + self.pos.x + self.box.from.x,
|
||||
-Camera.pos.y + self.pos.y + self.box.from.y,
|
||||
-Camera.pos.x + self.pos.x + self.box.to.x -(-Camera.pos.x + self.pos.x + self.box.from.x),
|
||||
-Camera.pos.y + self.pos.y + self.box.to.y -(-Camera.pos.y + self.pos.y + self.box.from.y)
|
||||
)
|
||||
if self.target ~= nil then
|
||||
love.graphics.line(
|
||||
@@ -256,12 +292,31 @@ function Entity:Debug()
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:HandleAnimation()
|
||||
function Entity:doLogic()
|
||||
end
|
||||
|
||||
function Entity:DrawBackground()
|
||||
function Entity:doPhysics()
|
||||
end
|
||||
|
||||
function Entity:handleAnimation()
|
||||
end
|
||||
|
||||
function Entity:drawBackground()
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
function cleanDeadEntities()
|
||||
for i=1, #LoadedObjects.Entities do
|
||||
enty = LoadedObjects.Entities[i]
|
||||
if enty and enty.dead then
|
||||
table.remove(LoadedObjects.Entities,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
require "code/entities/kupo"
|
||||
require "code/entities/arrow"
|
||||
require "code/entities/decoration"
|
||||
|
||||
@@ -1,26 +1,38 @@
|
||||
function GameStep()
|
||||
SetCollisionFlags()
|
||||
function restartGame()
|
||||
for _, entity in ipairs(LoadedObjects.Entities) do
|
||||
if entity.light ~= nil then entity.light:kill() end
|
||||
entity = nil
|
||||
end
|
||||
LoadedObjects.Entities = {}
|
||||
LoadedObjects.Particles = {}
|
||||
main_player = Player:new(75,50)
|
||||
activateSpawns()
|
||||
end
|
||||
|
||||
function stepGame()
|
||||
setCollisionFlags()
|
||||
if menu_type == "no" then
|
||||
for _, particle in pairs(LoadedParticles) do
|
||||
particle:Smart()
|
||||
for _, particle in pairs(LoadedObjects.Particles) do
|
||||
particle:doLogic()
|
||||
end
|
||||
for _, enty in pairs(LoadedObjects.Entities) do
|
||||
enty:Smart()
|
||||
enty:doLogic()
|
||||
end
|
||||
end
|
||||
|
||||
for _, particle in pairs(LoadedObjects.Particles) do
|
||||
particle:DoPhysics()
|
||||
particle:doPhysics()
|
||||
end
|
||||
for _, enty in pairs(LoadedObjects.Entities) do
|
||||
enty:DoPhysics()
|
||||
enty:doPhysics()
|
||||
end
|
||||
|
||||
AnimateTiles()
|
||||
Camera:positionCenterAt(main_Player.pos.x, main_Player.pos.y)
|
||||
--camera:positionAt(main_Player.pos.x, main_Player.pos.y,game.width,game.height)
|
||||
animateTiles()
|
||||
Camera:followPlayer(main_player)
|
||||
--Camera:positionCenterAt(main_player.pos.x, main_player.pos.y)
|
||||
--camera:positionAt(main_player.pos.x, main_player.pos.y,game.width,game.height)
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.debug) then
|
||||
if Keybind:checkPressed(Keybind.debug.debug) then
|
||||
if debug then
|
||||
debug = false
|
||||
debug_collision = true
|
||||
@@ -31,68 +43,66 @@ function GameStep()
|
||||
end
|
||||
end
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.reposition) then
|
||||
if not editor_mode then
|
||||
main_Player.pos.x, main_Player.pos.y = 16,-10
|
||||
end
|
||||
if Keybind:checkPressed(Keybind.debug.reposition) then
|
||||
restartGame()
|
||||
end
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.reload) then
|
||||
MenuClear()
|
||||
if Keybind:checkPressed(Keybind.debug.reload) then
|
||||
clearMenu()
|
||||
menu_type = "dialog"
|
||||
MenuInit("dialog",DialogSequence.Example)
|
||||
initMenu("dialog",dialog_sequence.example)
|
||||
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
|
||||
Demo:RecordEnd()
|
||||
Demo:endRecord()
|
||||
else
|
||||
Demo:RecordStart()
|
||||
Demo:startRecord()
|
||||
end
|
||||
end
|
||||
|
||||
if Keybind:CheckPressed(Keybind.debug.playback) then
|
||||
if Keybind:checkPressed(Keybind.debug.playback) then
|
||||
if DemoPlayback then
|
||||
Demo:PlaybackEnd()
|
||||
Demo:endPlayback()
|
||||
else
|
||||
Demo:PlaybackStart()
|
||||
Demo:startPlayback()
|
||||
end
|
||||
end
|
||||
|
||||
cleanDeadParticles()
|
||||
cleanDeadEntities()
|
||||
cleanDeadLights()
|
||||
end
|
||||
|
||||
function GameDraw()
|
||||
function drawGame()
|
||||
|
||||
-- prepare
|
||||
GameworldDrawPrepare()
|
||||
GameWorldUpdateLights()
|
||||
startGameworldDraw()
|
||||
updateGameWorldLights()
|
||||
|
||||
-- background
|
||||
GameworldDrawBackground()
|
||||
GameworldDrawLights()
|
||||
GameworldDrawEntitiesBackground()
|
||||
drawGameworldBackground()
|
||||
drawGameworldLights()
|
||||
drawGameworldEntitiesBackground()
|
||||
|
||||
-- foreground
|
||||
GameworldDrawForeground()
|
||||
GameworldDrawParticles()
|
||||
GameworldDrawEntities()
|
||||
drawGameworldForeground()
|
||||
drawGameworldParticles()
|
||||
drawGameworldEntities()
|
||||
|
||||
if LevelData.properties.darkness then
|
||||
GameworldDrawDarkness()
|
||||
drawGameworldDarkness()
|
||||
end
|
||||
-- end
|
||||
GameworldDrawEnd()
|
||||
endGameworldDraw()
|
||||
|
||||
-- hud
|
||||
textScale = 1
|
||||
text_size = 1
|
||||
|
||||
-- debug
|
||||
if debug then DebugUI() end
|
||||
if debug then debugUI() end
|
||||
if debug_collision then
|
||||
DebugColisions()
|
||||
DebugEntities()
|
||||
debugColisions()
|
||||
debugEntities()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
function GameworldDrawPrepare()
|
||||
function startGameworldDraw()
|
||||
if game_resize then
|
||||
Camera.height = game.height
|
||||
Camera.width = game.width
|
||||
Canvas.Darkness:Recreate()
|
||||
Canvas.Darkness:recreate()
|
||||
end
|
||||
pcr, pcg, pcb, pca = love.graphics.getColor()
|
||||
love.graphics.setScale(game.scale,game.scale)
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
end
|
||||
|
||||
function GameworldDrawEnd()
|
||||
function endGameworldDraw()
|
||||
love.graphics.setColor(pcr, pcg, pcb, pca)
|
||||
pcr, pcg, pcb, pca = nil, nil, nil, nil
|
||||
end
|
||||
|
||||
function GameworldDrawBackground()
|
||||
function drawGameworldBackground()
|
||||
-- obscure a bit
|
||||
love.graphics.setColor(0.7,0.7,0.7)
|
||||
for i = 1, #LevelTiles do
|
||||
@@ -22,10 +22,10 @@ function GameworldDrawBackground()
|
||||
if LevelTiles[i][j].id ~= 0 then
|
||||
|
||||
local depth = TileData[LevelTiles[i][j].id].depth
|
||||
DrawTile(
|
||||
drawTile(
|
||||
LevelTiles[i][j],
|
||||
tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x,
|
||||
tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y,
|
||||
tile_properties.scale * j * tile_properties.width + tile_properties.scale * (level_properties.offset.x - tile_properties.width) - Camera.pos.x,
|
||||
tile_properties.scale * i * tile_properties.height + tile_properties.scale * (level_properties.offset.y - tile_properties.height) - Camera.pos.y,
|
||||
"background"
|
||||
)
|
||||
|
||||
@@ -34,37 +34,37 @@ function GameworldDrawBackground()
|
||||
end
|
||||
end
|
||||
|
||||
function GameworldDrawParticles()
|
||||
function drawGameworldParticles()
|
||||
love.graphics.setColor(0.7,0.7,0.7)
|
||||
for _, particle in pairs(LoadedObjects.Particles) do
|
||||
particle:HandleAnimation()
|
||||
particle:handleAnimation()
|
||||
end
|
||||
end
|
||||
|
||||
function GameworldDrawEntitiesBackground()
|
||||
function drawGameworldEntitiesBackground()
|
||||
for _, enty in pairs(LoadedObjects.Entities) do
|
||||
enty:DrawBackground()
|
||||
enty:drawBackground()
|
||||
end
|
||||
end
|
||||
|
||||
function GameworldDrawEntities()
|
||||
function drawGameworldEntities()
|
||||
love.graphics.setColor(0.7,0.7,0.7)
|
||||
for _, enty in pairs(LoadedObjects.Entities) do
|
||||
enty:HandleAnimation()
|
||||
enty:handleAnimation()
|
||||
end
|
||||
end
|
||||
|
||||
function GameworldDrawForeground()
|
||||
function drawGameworldForeground()
|
||||
love.graphics.setColor(1,1,1)
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if LevelTiles[i][j].id ~= 0 then
|
||||
|
||||
local depth = TileData[LevelTiles[i][j].id].depth
|
||||
DrawTile(
|
||||
drawTile(
|
||||
LevelTiles[i][j],
|
||||
tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x,
|
||||
tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y,
|
||||
tile_properties.scale * j * tile_properties.width + tile_properties.scale * (level_properties.offset.x - tile_properties.width) - Camera.pos.x,
|
||||
tile_properties.scale * i * tile_properties.height + tile_properties.scale * (level_properties.offset.y - tile_properties.height) - Camera.pos.y,
|
||||
"foreground"
|
||||
)
|
||||
|
||||
@@ -73,54 +73,26 @@ function GameworldDrawForeground()
|
||||
end
|
||||
end
|
||||
|
||||
function GameworldDrawDarkness()
|
||||
Canvas.Darkness:Reset()
|
||||
Canvas.Darkness:DrawingStart()
|
||||
function drawGameworldDarkness()
|
||||
Canvas.Darkness:reset()
|
||||
Canvas.Darkness:startDrawing()
|
||||
love.graphics.setBlendMode("replace")
|
||||
love.graphics.setColor(0,0,0,0)
|
||||
for _, light in pairs(LoadedObjects.Lights) do
|
||||
if light.range ~= 0 then
|
||||
local position = {
|
||||
x = (light.pos.x - Camera.pos.x) / game.scale,
|
||||
y = (light.pos.y - Camera.pos.y) / game.scale
|
||||
}
|
||||
local range = (light.range + light.flicker) / game.scale
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
position.x,
|
||||
position.y,
|
||||
range
|
||||
)
|
||||
end
|
||||
light:drawClear()
|
||||
end
|
||||
Canvas.Darkness:DrawingEnd()
|
||||
Canvas.Darkness:Draw()
|
||||
Canvas.Darkness:endDrawing()
|
||||
Canvas.Darkness:draw()
|
||||
end
|
||||
|
||||
function GameworldDrawLights()
|
||||
function drawGameworldLights()
|
||||
for _, light in pairs(LoadedObjects.Lights) do
|
||||
if light.range ~= 0 then
|
||||
love.graphics.setColor(light.color[1],light.color[2],light.color[3],1)
|
||||
|
||||
Shader.RadiusGradient:send("pos_x",- Camera.pos.x + light.pos.x)
|
||||
Shader.RadiusGradient:send("pos_y",- Camera.pos.y + light.pos.y)
|
||||
Shader.RadiusGradient:send("range",light.range)
|
||||
Shader.RadiusGradient:send("scale",game.scale)
|
||||
|
||||
love.graphics.setShader(Shader.RadiusGradient)
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
- Camera.pos.x + light.pos.x,
|
||||
- Camera.pos.y + light.pos.y,
|
||||
light.range
|
||||
)
|
||||
love.graphics.setShader()
|
||||
end
|
||||
light:drawShine()
|
||||
end
|
||||
end
|
||||
|
||||
function GameWorldUpdateLights()
|
||||
function updateGameWorldLights()
|
||||
for _, light in pairs(LoadedObjects.Lights) do
|
||||
light:Flicker()
|
||||
light:flicker()
|
||||
end
|
||||
end
|
||||
|
||||
16
code/hex.lua
@@ -1,15 +1,15 @@
|
||||
function HEX2RGB(color)
|
||||
local r1 = HEX2DEX(color:sub(2,2))
|
||||
local r2 = HEX2DEX(color:sub(3,3))
|
||||
local g1 = HEX2DEX(color:sub(4,4))
|
||||
local g2 = HEX2DEX(color:sub(5,5))
|
||||
local b1 = HEX2DEX(color:sub(6,6))
|
||||
local b2 = HEX2DEX(color:sub(7,7))
|
||||
function hex2rgb(color)
|
||||
local r1 = hex2dec(color:sub(2,2))
|
||||
local r2 = hex2dec(color:sub(3,3))
|
||||
local g1 = hex2dec(color:sub(4,4))
|
||||
local g2 = hex2dec(color:sub(5,5))
|
||||
local b1 = hex2dec(color:sub(6,6))
|
||||
local b2 = hex2dec(color:sub(7,7))
|
||||
|
||||
return {(r1*16 + r2)/255, (g1*16 + g2)/255, (b1*16 + b2)/255}
|
||||
end
|
||||
|
||||
function HEX2DEX(hex)
|
||||
function hex2dec(hex)
|
||||
if hex == "0" then return 0
|
||||
elseif hex == "1" then return 1
|
||||
elseif hex == "2" then return 2
|
||||
|
||||
127
code/in_out.lua
@@ -1,51 +1,88 @@
|
||||
function ExportLevel(levelname, filename)
|
||||
os.execute( "mkdir \"./export\"" )
|
||||
function exportLevel(levelname, filename)
|
||||
love.filesystem.createDirectory("export")
|
||||
filename = filename or "output.lua"
|
||||
filename = "export/"..filename
|
||||
if string.sub(filename, 1, 1) ~= "/" then
|
||||
filename = "export/"..filename
|
||||
end
|
||||
exportFile = io.open(filename, "w+")
|
||||
|
||||
if exportFile then
|
||||
logPrint("Exporting level \"".. levelname .. "\"...")
|
||||
exportFile:write("return {")
|
||||
|
||||
logPrint("- level name")
|
||||
exportFile:write("\n name = \"" .. levelname .. "\",")
|
||||
logPrint("- level name")
|
||||
exportFile:write("\n name = \"" .. levelname .. "\",")
|
||||
|
||||
logPrint("- tileset")
|
||||
for k, v in pairs(tileset) do
|
||||
if v == LevelData.tileset then
|
||||
exportFile:write("\n tileset = tileset." .. k .. ",")
|
||||
end
|
||||
end
|
||||
|
||||
logPrint("- properties")
|
||||
exportFile:write("\n properties = {")
|
||||
exportFile:write("\n darkness = true")
|
||||
exportFile:write("\n },")
|
||||
|
||||
logPrint("- tiles")
|
||||
exportFile:write("\n tiles = {")
|
||||
local rows = #LevelTiles
|
||||
for i = 1, #LevelTiles do
|
||||
exportFile:write("\n { ")
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if j ~= 1 then
|
||||
exportFile:write(", ")
|
||||
logPrint("- tileset")
|
||||
for k, v in pairs(tileset) do
|
||||
if v == LevelData.tileset then
|
||||
exportFile:write("\n tileset = tileset." .. k .. ",")
|
||||
end
|
||||
exportFile:write(tostring(LevelTiles[i][j].id))
|
||||
end
|
||||
exportFile:write("}")
|
||||
if i ~= #LevelTiles then
|
||||
exportFile:write(", ")
|
||||
|
||||
logPrint("- properties")
|
||||
exportFile:write("\n properties = {")
|
||||
logPrint(" - darkness: ".. tostring(LevelData.properties.darkness))
|
||||
exportFile:write("\n darkness = " .. tostring(LevelData.properties.darkness))
|
||||
exportFile:write("\n },")
|
||||
|
||||
logPrint("- tiles")
|
||||
exportFile:write("\n tiles = {")
|
||||
local rows = #LevelTiles
|
||||
for i = 1, #LevelTiles do
|
||||
if i > 1 then
|
||||
exportFile:write(", ")
|
||||
end
|
||||
exportFile:write("\n { ")
|
||||
for j = 1, #LevelTiles[i] do
|
||||
if j ~= 1 then
|
||||
exportFile:write(", ")
|
||||
end
|
||||
exportFile:write(tostring(LevelTiles[i][j].id))
|
||||
end
|
||||
exportFile:write("}")
|
||||
logPrint(" - row "..i.."/"..rows.." "..math.floor(100*((i-1)*100/rows))/100 .."%")
|
||||
end
|
||||
logPrint(" - Row "..i.."/"..rows.." "..math.floor(100*((i-1)*100/rows))/100 .."%")
|
||||
end
|
||||
exportFile:write("\n },")
|
||||
|
||||
logPrint("- objects")
|
||||
exportFile:write("\n objects = {}")
|
||||
|
||||
logPrint("Exporting complete.")
|
||||
exportFile:write("\n },")
|
||||
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
|
||||
@@ -63,22 +100,6 @@ function scandir(directory)
|
||||
return t
|
||||
end
|
||||
|
||||
--[[
|
||||
return {
|
||||
name = "level1",
|
||||
tileset = tileset.library,
|
||||
tiles = {
|
||||
{13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13},
|
||||
{ 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, 5,25,26, 6,25,26, 7, 0, 5,25,26, 7, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 5,37,38, 6,37,38, 7, 0, 5,37,38, 7, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 5,37,38, 6,37,38, 7, 0, 5,37,38, 7, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 5,49,50, 6,49,50, 7, 0, 5,49,50, 7, 0, 0, 0, 0, 0, 0},
|
||||
{ 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 = {}
|
||||
}
|
||||
]]
|
||||
if logging then
|
||||
-- Make log stuff
|
||||
os.execute( "mkdir \"./logs\"" )
|
||||
|
||||
@@ -17,7 +17,11 @@ Keybind.debug = {}
|
||||
Keybind.editor = {}
|
||||
Keybind.generic = {}
|
||||
|
||||
function Keybind:CheckDown(action)
|
||||
function Keybind:isAvailable(action)
|
||||
return not action.occupied
|
||||
end
|
||||
|
||||
function Keybind:checkDown(action)
|
||||
if DemoPlayback then
|
||||
for _, demo_action in pairs(DemoAction[CurrentDemoFrame]) do
|
||||
if demo_action == action.demo then
|
||||
@@ -35,17 +39,20 @@ function Keybind:CheckDown(action)
|
||||
end
|
||||
if check then
|
||||
if action.demo ~= nil then
|
||||
Demo:RecordAction(action.demo)
|
||||
Demo:recordAction(action.demo)
|
||||
end
|
||||
action.occupied = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
action.occupied = false
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function Keybind:CheckPressed(action)
|
||||
if Keybind:CheckDown(action) then
|
||||
-- relies on being called exactly once per frame to be accurate.
|
||||
function Keybind:checkPressed(action)
|
||||
if Keybind:checkDown(action) then
|
||||
if not action.pressed then
|
||||
action.pressed = true
|
||||
return true
|
||||
@@ -56,7 +63,7 @@ function Keybind:CheckPressed(action)
|
||||
return false
|
||||
end
|
||||
|
||||
function Keybind:CheckCollision(cat, key)
|
||||
function Keybind:checkCollision(cat, key)
|
||||
for _, action in pairs(cat) do
|
||||
for _, keyname in pairs(action.keys) do
|
||||
if key == keyname then return true end
|
||||
@@ -65,19 +72,30 @@ function Keybind:CheckCollision(cat, key)
|
||||
return false
|
||||
end
|
||||
|
||||
function Keybind:AddKey(action, key)
|
||||
function Keybind:addKey(action, key)
|
||||
table.insert(action.keys, key)
|
||||
end
|
||||
|
||||
function Keybind:ChangeKey(action, position, key)
|
||||
function Keybind:changeKey(action, position, key)
|
||||
action.keys[position] = key
|
||||
end
|
||||
|
||||
function Keybind:RemoveKeys(action)
|
||||
function Keybind:removeKeys(action)
|
||||
action.keys = {}
|
||||
end
|
||||
|
||||
function Keybind:Default()
|
||||
-- this prolly should be used by Prompt:keypressed()
|
||||
function Keybind:hasKey(action, key)
|
||||
for _, v in pairs(action.keys) do
|
||||
if v == key then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Keybind:default()
|
||||
--Menu
|
||||
Keybind.menu.pause.keys = {"escape"}
|
||||
Keybind.menu.confirm.keys = {"z", "space", 1}
|
||||
@@ -98,16 +116,34 @@ function Keybind:Default()
|
||||
Keybind.debug.editor = { keys = {"f4"}}
|
||||
Keybind.debug.recording = { keys = {"f5"}}
|
||||
Keybind.debug.playback = { keys = {"f6"}}
|
||||
Keybind.debug.respawn = { keys = {"f8"}}
|
||||
|
||||
-- Editor
|
||||
Keybind.editor.palette = { keys = {"tab"}}
|
||||
|
||||
Keybind.editor.palette_mode = { keys = {"tab"}}
|
||||
Keybind.editor.room_mode = { keys = {"r"}}
|
||||
Keybind.editor.entity_mode = { keys = {"e"}}
|
||||
Keybind.editor.properties_mode = { keys = {"p"}}
|
||||
Keybind.editor.left = { keys = {"left", "a"}}
|
||||
Keybind.editor.right = { keys = {"right", "d"}}
|
||||
Keybind.editor.up = { keys = {"up", "w"}}
|
||||
Keybind.editor.down = { keys = {"down", "s"}}
|
||||
Keybind.editor.palette_change = { keys = {"f1"}}
|
||||
Keybind.editor.save = { keys = {"f3"}}
|
||||
Keybind.editor.tile_set = { keys = {1}}
|
||||
Keybind.editor.tile_remove = { keys = {2}}
|
||||
Keybind.editor.entity_select = { keys = {1}}
|
||||
Keybind.editor.entity_move = { keys = {2}}
|
||||
Keybind.editor.entity_modify_archetype = { keys = {"t"}}
|
||||
Keybind.editor.entity_modify_data = { keys = {"g"}}
|
||||
Keybind.editor.entity_remove = { keys = {"delete"}}
|
||||
Keybind.editor.entity_new = { keys = {"n"}}
|
||||
-- Generic
|
||||
Keybind.generic.lclick = { keys = {1}}
|
||||
Keybind.generic.rclick = { keys = {2}}
|
||||
Keybind.generic.lshift = { keys = {"lshift"}}
|
||||
Keybind.generic.alt = { keys = {"alt"}}
|
||||
Keybind.generic.lctrl = { keys = {"lctrl"}}
|
||||
end
|
||||
|
||||
-- Set default values at start
|
||||
Keybind:Default()
|
||||
Keybind:default()
|
||||
|
||||
408
code/level.lua
@@ -1,6 +1,6 @@
|
||||
function LevelLoadTiles()
|
||||
function loadLevelTiles()
|
||||
math.randomseed(3)
|
||||
LevelData = dofile("data/levels/"..currLevel)
|
||||
LevelData = dofile("data/levels/"..level_current)
|
||||
|
||||
--[[
|
||||
on level format:
|
||||
@@ -12,19 +12,34 @@ function LevelLoadTiles()
|
||||
overlay_depth = foreground/background overlay depth
|
||||
type = collision type
|
||||
]]
|
||||
LevelGetTileData()
|
||||
getLevelTileData()
|
||||
LevelTiles = LevelData.tiles
|
||||
LevelUpdateDimensions()
|
||||
LevelIndexTiles()
|
||||
TileCreateObjects()
|
||||
updateLevelDimensions()
|
||||
indexLevelTiles()
|
||||
createTileObjects()
|
||||
createRoomObjects()
|
||||
getSpawns()
|
||||
end
|
||||
|
||||
function createRoomObjects()
|
||||
LoadedObjects.Rooms = {}
|
||||
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]))
|
||||
end
|
||||
end
|
||||
|
||||
function LevelExpandCanvas(horizontal,vertical)
|
||||
function getSpawns()
|
||||
LoadedObjects.Spawns = {}
|
||||
for _, v in pairs(LevelData.objects.spawns) do
|
||||
addSpawn(v[1],unpack(v[2]))
|
||||
end
|
||||
end
|
||||
|
||||
function expandLevelCanvas(horizontal,vertical)
|
||||
local horizontal = horizontal or 0
|
||||
local vertical = vertical or 0
|
||||
local h = LevelGetTileWidth()
|
||||
local v = LevelGetTileHeight()
|
||||
local h = getLevelTileWidth()
|
||||
local v = getLevelTileHeight()
|
||||
|
||||
-- get new canvas size
|
||||
local newCanvasH = h + math.abs(horizontal)
|
||||
@@ -35,7 +50,7 @@ function LevelExpandCanvas(horizontal,vertical)
|
||||
for i = 1, newCanvasV do
|
||||
ExpandedLevel[i] = {}
|
||||
for j = 1, newCanvasH do
|
||||
ExpandedLevel[i][j] = InstanceTile(0)
|
||||
ExpandedLevel[i][j] = instanceTile(0)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,7 +68,7 @@ function LevelExpandCanvas(horizontal,vertical)
|
||||
-- get data from old canvas to new canvas
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
ExpandedLevel[i+expand_v][j+expand_h] = InstanceTile(LevelTiles[i][j].id)
|
||||
ExpandedLevel[i+expand_v][j+expand_h] = instanceTile(LevelTiles[i][j].id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -62,11 +77,11 @@ function LevelExpandCanvas(horizontal,vertical)
|
||||
end
|
||||
|
||||
|
||||
function LevelReduceCanvas(horizontal,vertical)
|
||||
function reduceLevelCanvas(horizontal,vertical)
|
||||
local horizontal = horizontal or 0
|
||||
local vertical = vertical or 0
|
||||
local h = LevelGetTileWidth()
|
||||
local v = LevelGetTileHeight()
|
||||
local h = getLevelTileWidth()
|
||||
local v = getLevelTileHeight()
|
||||
|
||||
-- get new canvas size
|
||||
local newCanvasH = h - math.abs(horizontal)
|
||||
@@ -77,7 +92,7 @@ function LevelReduceCanvas(horizontal,vertical)
|
||||
for i = 1, newCanvasV do
|
||||
ExpandedLevel[i] = {}
|
||||
for j = 1, newCanvasH do
|
||||
ExpandedLevel[i][j] = InstanceTile(0)
|
||||
ExpandedLevel[i][j] = instanceTile(0)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -95,17 +110,17 @@ function LevelReduceCanvas(horizontal,vertical)
|
||||
-- get data from old canvas to new canvas
|
||||
for i = 1, #ExpandedLevel do
|
||||
for j = 1, #ExpandedLevel[i] do
|
||||
ExpandedLevel[i][j] = InstanceTile(LevelTiles[i+expand_v][j+expand_h].id)
|
||||
ExpandedLevel[i][j] = instanceTile(LevelTiles[i+expand_v][j+expand_h].id)
|
||||
end
|
||||
end
|
||||
|
||||
-- use new canvas
|
||||
LevelTiles = ExpandedLevel
|
||||
|
||||
LevelExpandCanvas()
|
||||
expandLevelCanvas()
|
||||
end
|
||||
|
||||
function LevelGetTileData()
|
||||
function getLevelTileData()
|
||||
for k, v in pairs(tileset) do
|
||||
if v == LevelData.tileset then
|
||||
TileData = dofile("data/tileset/"..k..".lua")
|
||||
@@ -113,20 +128,20 @@ function LevelGetTileData()
|
||||
end
|
||||
end
|
||||
|
||||
function LevelReloadTiles()
|
||||
LevelUpdateDimensions()
|
||||
function reloadLevelTiles()
|
||||
updateLevelDimensions()
|
||||
end
|
||||
|
||||
function LevelUpdateDimensions()
|
||||
LevelData.Width = LevelGetWidth()
|
||||
LevelData.Height = LevelGetHeight()
|
||||
function updateLevelDimensions()
|
||||
LevelData.Width = getLevelWidth()
|
||||
LevelData.Height = getLevelHeight()
|
||||
end
|
||||
|
||||
function LevelGetTileHeight()
|
||||
function getLevelTileHeight()
|
||||
return #LevelTiles
|
||||
end
|
||||
|
||||
function LevelGetTileWidth()
|
||||
function getLevelTileWidth()
|
||||
local width = 0
|
||||
for i = 1, #LevelTiles do
|
||||
if width < #LevelTiles[i] then width = #LevelTiles[i] end
|
||||
@@ -134,42 +149,42 @@ function LevelGetTileWidth()
|
||||
return width
|
||||
end
|
||||
|
||||
function LevelGetHeight()
|
||||
return LevelGetTileHeight() * tileProperties.height
|
||||
function getLevelHeight()
|
||||
return getLevelTileHeight() * tile_properties.height
|
||||
end
|
||||
|
||||
function LevelGetWidth()
|
||||
return LevelGetTileWidth() * tileProperties.width
|
||||
function getLevelWidth()
|
||||
return getLevelTileWidth() * tile_properties.width
|
||||
end
|
||||
|
||||
function LevelIndexTiles()
|
||||
function indexLevelTiles()
|
||||
TileIndex = {}
|
||||
|
||||
-- index from tileset
|
||||
local width = LevelData.tileset:getPixelWidth()/tileProperties.width
|
||||
local height = LevelData.tileset:getPixelHeight()/tileProperties.height
|
||||
local width = LevelData.tileset:getPixelWidth()/tile_properties.width
|
||||
local height = LevelData.tileset:getPixelHeight()/tile_properties.height
|
||||
for i = 0, height do
|
||||
for j = 0, width do
|
||||
TileIndex[i*width+j+1] = love.graphics.newQuad(
|
||||
j*tileProperties.width,
|
||||
i*tileProperties.height,
|
||||
tileProperties.width,
|
||||
tileProperties.height,
|
||||
j*tile_properties.width,
|
||||
i*tile_properties.height,
|
||||
tile_properties.width,
|
||||
tile_properties.height,
|
||||
LevelData.tileset:getDimensions()
|
||||
)
|
||||
end
|
||||
end
|
||||
TileDataInitialize()
|
||||
initTileData()
|
||||
|
||||
-- instance level tiles according to the Properties
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
SetTile(i,j,LevelTiles[i][j])
|
||||
setTile(i,j,LevelTiles[i][j])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TileDataInitialize()
|
||||
function initTileData()
|
||||
for _, Properties in pairs(TileData) do
|
||||
if Properties.animation ~= nil then
|
||||
Properties.tileset = love.graphics.newImage("assets/terrain/"..Properties.animation..".png")
|
||||
@@ -178,18 +193,18 @@ function TileDataInitialize()
|
||||
Properties.current_subimage = 1
|
||||
|
||||
local tileset = Properties.tileset
|
||||
local width = tileset:getPixelWidth()/tileProperties.width
|
||||
local height = tileset:getPixelHeight()/tileProperties.height
|
||||
local width = tileset:getPixelWidth()/tile_properties.width
|
||||
local height = tileset:getPixelHeight()/tile_properties.height
|
||||
local image_count = 0
|
||||
|
||||
for i = 0, height-1 do
|
||||
for j = 0, width-1 do
|
||||
local quad =
|
||||
love.graphics.newQuad(
|
||||
j*tileProperties.width,
|
||||
i*tileProperties.height,
|
||||
tileProperties.width,
|
||||
tileProperties.height,
|
||||
j*tile_properties.width,
|
||||
i*tile_properties.height,
|
||||
tile_properties.width,
|
||||
tile_properties.height,
|
||||
tileset:getDimensions()
|
||||
)
|
||||
image_count = image_count + 1
|
||||
@@ -202,7 +217,7 @@ function TileDataInitialize()
|
||||
end
|
||||
end
|
||||
|
||||
function InstanceTile(id)
|
||||
function instanceTile(id)
|
||||
local tile = {}
|
||||
|
||||
tile.id = id
|
||||
@@ -225,25 +240,25 @@ function InstanceTile(id)
|
||||
return tile
|
||||
end
|
||||
|
||||
function SetTile(i,j,id)
|
||||
LevelTiles[i][j] = InstanceTile(id)
|
||||
function setTile(i,j,id)
|
||||
LevelTiles[i][j] = instanceTile(id)
|
||||
end
|
||||
|
||||
function GridDisplay()
|
||||
function drawGridDisplay()
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
tileProperties.scale * (j * tileProperties.width + (levelProperties.offset.x - tileProperties.width)) - Camera.pos.x,
|
||||
tileProperties.scale * (i * tileProperties.height + (levelProperties.offset.y - tileProperties.height)) - Camera.pos.y,
|
||||
tileProperties.scale * tileProperties.width,
|
||||
tileProperties.scale * tileProperties.height
|
||||
tile_properties.scale * (j * tile_properties.width + (level_properties.offset.x - tile_properties.width)) - Camera.pos.x,
|
||||
tile_properties.scale * (i * tile_properties.height + (level_properties.offset.y - tile_properties.height)) - Camera.pos.y,
|
||||
tile_properties.scale * tile_properties.width,
|
||||
tile_properties.scale * tile_properties.height
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function TileOptimizeObjects()
|
||||
function optimizeTileObjects()
|
||||
logPrint("Optimizing Objects...")
|
||||
local unoptimized = 0
|
||||
local isTileOptimized = {}
|
||||
@@ -313,14 +328,14 @@ function TileOptimizeObjects()
|
||||
|
||||
logPrint("- Group size: "..m.."x"..n)
|
||||
unoptimized = unoptimized + m * n
|
||||
local base_x = tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.height)
|
||||
local base_y = tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.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 col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale * n,
|
||||
base_y + tileProperties.height * tileProperties.scale * m
|
||||
base_x + tile_properties.width * tile_properties.scale * n,
|
||||
base_y + tile_properties.height * tile_properties.scale * m
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
end
|
||||
@@ -331,13 +346,13 @@ function TileOptimizeObjects()
|
||||
logPrint("collisions optimized from " .. unoptimized .. " to " .. #LoadedObjects.Collisions)
|
||||
end
|
||||
|
||||
function TileCreateObjects()
|
||||
function createTileObjects()
|
||||
LoadedObjects.Collisions = {}
|
||||
LoadedObjects.Platforms = {}
|
||||
LoadedObjects.Ladders = {}
|
||||
LoadedObjects.Hazards = {}
|
||||
|
||||
TileOptimizeObjects()
|
||||
optimizeTileObjects()
|
||||
|
||||
for i = 1, #LevelTiles do
|
||||
for j = 1, #LevelTiles[i] do
|
||||
@@ -345,105 +360,105 @@ function TileCreateObjects()
|
||||
|
||||
local type = TileData[LevelTiles[i][j].id].type
|
||||
local light = TileData[LevelTiles[i][j].id].light
|
||||
local base_x = tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.height)
|
||||
local base_y = tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.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)
|
||||
|
||||
|
||||
if light ~= 0 and light ~= nil then
|
||||
CreateLight(
|
||||
base_x + tileProperties.width/2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tile_properties.width/2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale,
|
||||
light
|
||||
)
|
||||
end
|
||||
|
||||
-- wholes are handled in optimization now
|
||||
--[[if type == "whole" then
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
else]]if type == "half_bottom" then
|
||||
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_y + tile_properties.height/2 * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "half_top" then
|
||||
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y ,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "half_right" then
|
||||
|
||||
local col = Collision:New(
|
||||
base_x + tileProperties.height/2 * tileProperties.scale,
|
||||
local col = Collision:new(
|
||||
base_x + tile_properties.height/2 * tile_properties.scale,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "half_left" then
|
||||
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.height/2 * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_x + tile_properties.height/2 * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "platform" then
|
||||
local plat = Collision:New(
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
base_y + tile_properties.scale * 2,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/4 * tile_properties.scale + tile_properties.scale * 2
|
||||
)
|
||||
table.insert(LoadedObjects.Platforms,plat)
|
||||
|
||||
elseif type == "ramp2_bot_left_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * 2 * tileProperties.scale,
|
||||
base_y + k * tileProperties.scale
|
||||
base_y + k * tile_properties.scale - tile_properties.scale,
|
||||
base_x + k * 2 * tile_properties.scale,
|
||||
base_y + k * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
end
|
||||
-- fill lower half
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_y + tile_properties.height/2 * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "ramp2_bot_left_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * 2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale
|
||||
base_y + tile_properties.height/2 * tile_properties.scale + k * tile_properties.scale - tile_properties.scale,
|
||||
base_x + k * 2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale + k * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
@@ -452,32 +467,32 @@ function TileCreateObjects()
|
||||
elseif type == "ramp2_top_left_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - tile_properties.scale + k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale - (k-1) * 2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - tile_properties.scale + k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
end
|
||||
-- fill higher half
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "ramp2_top_left_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
base_y - tile_properties.scale + k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale - (k-1) * 2 * tile_properties.scale,
|
||||
base_y - tile_properties.scale + k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
@@ -486,32 +501,32 @@ function TileCreateObjects()
|
||||
elseif type == "ramp2_bot_right_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tile_properties.scale,
|
||||
base_y - tile_properties.scale + k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y - tile_properties.scale + k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
end
|
||||
-- fill lower half
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_y + tile_properties.height/2 * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
elseif type == "ramp2_bot_right_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - tile_properties.scale + k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - tile_properties.scale + k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
@@ -520,11 +535,11 @@ function TileCreateObjects()
|
||||
elseif type == "ramp2_top_right_half" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale - k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
@@ -533,21 +548,21 @@ function TileCreateObjects()
|
||||
elseif type == "ramp2_top_right_whole" then
|
||||
for k = 1, 8 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
base_x + (k-8) * -2 * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale
|
||||
local slope = Collision:new(
|
||||
base_x + (k-8) * -2 * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale + tile_properties.height/2 * tile_properties.scale - k * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale + tile_properties.height/2 * tile_properties.scale - k * tile_properties.scale + tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
end
|
||||
-- fill higher half
|
||||
local col = Collision:New(
|
||||
local col = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/2 * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/2 * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,col)
|
||||
|
||||
@@ -555,11 +570,11 @@ function TileCreateObjects()
|
||||
|
||||
for k = 1, 16 do
|
||||
-- do ramp owo
|
||||
local slope = Collision:New(
|
||||
local slope = Collision:new(
|
||||
base_x,
|
||||
base_y + k * tileProperties.scale - tileProperties.scale,
|
||||
base_x + k * tileProperties.scale,
|
||||
base_y + k * tileProperties.scale
|
||||
base_y + k * tile_properties.scale - tile_properties.scale,
|
||||
base_x + k * tile_properties.scale,
|
||||
base_y + k * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Collisions,slope)
|
||||
|
||||
@@ -567,70 +582,70 @@ function TileCreateObjects()
|
||||
|
||||
elseif type == "ladder_right" then
|
||||
|
||||
local ladder = Collision:New(
|
||||
base_x + (tileProperties.width-4)* tileProperties.scale,
|
||||
local ladder = Collision:new(
|
||||
base_x + (tile_properties.width-4)* tile_properties.scale,
|
||||
base_y,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Ladders,ladder)
|
||||
|
||||
elseif type == "ladder_platform_right" then
|
||||
|
||||
local ladder = Collision:New(
|
||||
base_x + (tileProperties.width-4)* tileProperties.scale,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
local ladder = Collision:new(
|
||||
base_x + (tile_properties.width-4)* tile_properties.scale,
|
||||
base_y + tile_properties.scale * 2,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Ladders,ladder)
|
||||
|
||||
local plat = Collision:New(
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
base_y + tile_properties.scale * 2,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/4 * tile_properties.scale + tile_properties.scale * 2
|
||||
)
|
||||
table.insert(LoadedObjects.Platforms,plat)
|
||||
|
||||
elseif type == "ladder_left" then
|
||||
|
||||
|
||||
local ladder = Collision:New(
|
||||
local ladder = Collision:new(
|
||||
base_x,
|
||||
base_y,
|
||||
base_x + tileProperties.scale * 4,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_x + tile_properties.scale * 4,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Ladders,ladder)
|
||||
|
||||
elseif type == "ladder_platform_left" then
|
||||
|
||||
|
||||
local ladder = Collision:New(
|
||||
local ladder = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.scale * 4,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_y + tile_properties.scale * 2,
|
||||
base_x + tile_properties.scale * 4,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Ladders,ladder)
|
||||
|
||||
local plat = Collision:New(
|
||||
local plat = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.scale * 2,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2
|
||||
base_y + tile_properties.scale * 2,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height/4 * tile_properties.scale + tile_properties.scale * 2
|
||||
)
|
||||
table.insert(LoadedObjects.Platforms,plat)
|
||||
|
||||
elseif type == "bottom_hazard" then
|
||||
|
||||
|
||||
local hazard = Collision:New(
|
||||
local hazard = Collision:new(
|
||||
base_x,
|
||||
base_y + tileProperties.height * 12/16 * tileProperties.scale,
|
||||
base_x + tileProperties.width * tileProperties.scale,
|
||||
base_y + tileProperties.height * tileProperties.scale
|
||||
base_y + tile_properties.height * 12/16 * tile_properties.scale,
|
||||
base_x + tile_properties.width * tile_properties.scale,
|
||||
base_y + tile_properties.height * tile_properties.scale
|
||||
)
|
||||
table.insert(LoadedObjects.Hazards,hazard)
|
||||
|
||||
@@ -641,7 +656,7 @@ function TileCreateObjects()
|
||||
--CreateCollisionTable()
|
||||
end
|
||||
|
||||
function AnimateTiles()
|
||||
function animateTiles()
|
||||
for _, Properties in pairs(TileData) do
|
||||
if Properties ~= nil then
|
||||
if Properties.animation ~= nil then
|
||||
@@ -661,40 +676,7 @@ function AnimateTiles()
|
||||
end
|
||||
end
|
||||
|
||||
function CreateCollisionTable()
|
||||
-- init table
|
||||
CollisionTable = {}
|
||||
for j=0, 16*LevelGetTileHeight()-1 do
|
||||
CollisionTable[j] = {}
|
||||
for i=0, 16*LevelGetTileWidth()-1 do
|
||||
CollisionTable[j][i] = false
|
||||
end
|
||||
end
|
||||
|
||||
for _, collision in pairs(LoadedObjects.Collisions) do
|
||||
for ci=0, math.floor(collision.width)-1 do
|
||||
for cj=0, math.floor(collision.height)-1 do
|
||||
print(ci..","..cj)
|
||||
CollisionTable[collision.from.y+cj][collision.from.x+ci] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DrawColisionTable()
|
||||
for j=1, #CollisionTable do
|
||||
for i=1, #CollisionTable[j] do
|
||||
if CollisionTable[j][i] then
|
||||
love.graphics.setColor(0,1,0,1)
|
||||
else
|
||||
love.graphics.setColor(1,0,0,1)
|
||||
end
|
||||
love.graphics.points(i,j)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DrawTile(tile,x,y,depth)
|
||||
function drawTile(tile,x,y,depth)
|
||||
local Properties = TileData[tile.id]
|
||||
|
||||
if Properties ~= nil then
|
||||
@@ -707,8 +689,8 @@ function DrawTile(tile,x,y,depth)
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
tile_properties.scale,
|
||||
tile_properties.scale
|
||||
)
|
||||
end
|
||||
elseif Properties.depth == depth then
|
||||
@@ -720,8 +702,8 @@ function DrawTile(tile,x,y,depth)
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
tile_properties.scale,
|
||||
tile_properties.scale
|
||||
)
|
||||
end
|
||||
else
|
||||
@@ -731,8 +713,8 @@ function DrawTile(tile,x,y,depth)
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
tile_properties.scale,
|
||||
tile_properties.scale
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -747,8 +729,8 @@ function DrawTile(tile,x,y,depth)
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
tile_properties.scale,
|
||||
tile_properties.scale
|
||||
)
|
||||
else
|
||||
love.graphics.draw(
|
||||
@@ -757,8 +739,8 @@ function DrawTile(tile,x,y,depth)
|
||||
x,
|
||||
y,
|
||||
0,
|
||||
tileProperties.scale,
|
||||
tileProperties.scale
|
||||
tile_properties.scale,
|
||||
tile_properties.scale
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,47 +1,89 @@
|
||||
Light = {}
|
||||
Light = class(nil, {
|
||||
type = "Light"
|
||||
})
|
||||
LoadedObjects.Lights = {}
|
||||
|
||||
function Light:New(x,y,range,flicker,color,lum)
|
||||
function Light:new(x,y,data)
|
||||
local o = {}
|
||||
o.pos = {
|
||||
x = x,
|
||||
y = y
|
||||
}
|
||||
o.range = range
|
||||
o.lum = lum or 1
|
||||
o.color = color or {1,1,1}
|
||||
o.flicker_value = flicker or 2
|
||||
o.flicker = 0
|
||||
o.radius = data.radius
|
||||
o.shine_radius = data.shine_radius or 0
|
||||
o.lum = data.lum or 1
|
||||
o.color = data.color or {1,1,1}
|
||||
o.flicker_amount = data.flicker or 2
|
||||
o.flicker_value = 0
|
||||
o.dim = 0
|
||||
o.flicker_time = 60/12
|
||||
o.flicker_timer = 0
|
||||
|
||||
table.insert(LoadedObjects.Lights,o)
|
||||
o.id = #LoadedObjects.Lights
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
table.insert(LoadedObjects.Lights,o)
|
||||
return o
|
||||
end
|
||||
|
||||
function Light:Kill()
|
||||
if self.id ~= nil then
|
||||
for _, e in pairs(LoadedObjects.Lights) do
|
||||
if e.id > self.id then
|
||||
e.id = e.id - 1
|
||||
end
|
||||
end
|
||||
table.remove(LoadedObjects.Lights,self.id)
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
function Light:Flicker()
|
||||
function Light:flicker()
|
||||
self.flicker_timer = self.flicker_timer + 1
|
||||
|
||||
if self.flicker_timer >= self.flicker_time then
|
||||
self.flicker_timer = self.flicker_timer - self.flicker_time
|
||||
self.flicker = math.random(0,1)
|
||||
self.flicker = math.min(math.max(self.flicker, -self.flicker_value), self.flicker_value)
|
||||
self.flicker_value = math.random(0,1)
|
||||
self.flicker_value = math.min(math.max(self.flicker_value, -self.flicker_amount), self.flicker_amount)
|
||||
end
|
||||
end
|
||||
|
||||
function Light:drawClear()
|
||||
if self.radius ~= 0 then
|
||||
local position = {
|
||||
x = (self.pos.x - Camera.pos.x) / game.scale,
|
||||
y = (self.pos.y - Camera.pos.y) / game.scale
|
||||
}
|
||||
local radius = (self.radius + self.flicker_value) / game.scale
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
position.x,
|
||||
position.y,
|
||||
radius
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function Light:drawShine()
|
||||
if self.radius ~= 0 then
|
||||
love.graphics.setColor(self.color[1],self.color[2],self.color[3],1)
|
||||
|
||||
shader.circle_gradient:send("pos_x",- Camera.pos.x + self.pos.x)
|
||||
shader.circle_gradient:send("pos_y",- Camera.pos.y + self.pos.y)
|
||||
shader.circle_gradient:send("radius",self.shine_radius)
|
||||
shader.circle_gradient:send("scale",game.scale)
|
||||
|
||||
love.graphics.setShader(shader.circle_gradient)
|
||||
love.graphics.circle(
|
||||
"fill",
|
||||
- Camera.pos.x + self.pos.x,
|
||||
- Camera.pos.y + self.pos.y,
|
||||
self.radius
|
||||
)
|
||||
love.graphics.setShader()
|
||||
end
|
||||
end
|
||||
|
||||
function Light:kill()
|
||||
self.dead = true
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
function cleanDeadLights()
|
||||
for i=1, #LoadedObjects.Lights do
|
||||
light = LoadedObjects.Lights[i]
|
||||
if light and light.dead then
|
||||
table.remove(LoadedObjects.Lights,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
function LocaleLoad(ISO639)
|
||||
function loadLocale(ISO639)
|
||||
local ISO639 = ISO639 or "ENG"
|
||||
dofile("data/locale/"..ISO639..".lua")
|
||||
dofile("data/dialog_sequences.lua")
|
||||
|
||||
@@ -8,20 +8,22 @@ function math.sign(x)
|
||||
end
|
||||
end
|
||||
|
||||
function Vector(init_x, init_y, final_x, final_y)
|
||||
local distance_x = final_x - init_x
|
||||
local distance_y = final_y - init_y
|
||||
return {distance_x, distance_y}
|
||||
function math.round(x)
|
||||
return math.floor(x+0.5)
|
||||
end
|
||||
|
||||
function GetVectorValue(vector)
|
||||
return math.sqrt(vector[1] ^ 2 + vector[2] ^ 2)
|
||||
function vector(x, y)
|
||||
return {x = x, y = y}
|
||||
end
|
||||
|
||||
function GetAngleFromVector(x,y)
|
||||
function getVectorValue(vector)
|
||||
return math.sqrt(vector.x ^ 2 + vector.y ^ 2)
|
||||
end
|
||||
|
||||
function getAngleFromVector(vector)
|
||||
local reduce = 0
|
||||
if x < 0 then
|
||||
if vector.x < 0 then
|
||||
reduce = math.rad(180)
|
||||
end
|
||||
return math.atan(y/x) - reduce
|
||||
return math.atan(vector.y/vector.x) - reduce
|
||||
end
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
function MenuDraw(menu)
|
||||
function drawMenu(menu)
|
||||
local font = love.graphics.getFont()
|
||||
love.graphics.setFont(LocaleFont)
|
||||
love.graphics.setFont(locale_font)
|
||||
|
||||
-- reset scale
|
||||
love.graphics.setScale()
|
||||
|
||||
if menu == "pause" then
|
||||
MenuDrawPauseScreen()
|
||||
drawMenuPauseScreen()
|
||||
elseif menu == "dialog" then
|
||||
MenuDrawDialog()
|
||||
drawMenuDialog()
|
||||
end
|
||||
|
||||
for _, element in pairs(UIElement) do
|
||||
element:Draw()
|
||||
element:draw()
|
||||
end
|
||||
|
||||
love.graphics.setFont(font)
|
||||
end
|
||||
|
||||
function MenuDrawPauseScreen()
|
||||
function drawMenuPauseScreen()
|
||||
-- Parameters
|
||||
local pauseWidth = 640
|
||||
local pauseHeight = 480
|
||||
@@ -32,10 +32,10 @@ function MenuDrawPauseScreen()
|
||||
love.graphics.rectangle("fill", pauseX, pauseY, pauseWidth, pauseHeight)
|
||||
end
|
||||
|
||||
function MenuDrawDialog()
|
||||
function drawMenuDialog()
|
||||
end
|
||||
|
||||
function MenuStep(menu)
|
||||
function stepMenu(menu)
|
||||
-- first get mouse
|
||||
local mouse_x, mouse_y = love.mouse.getPosition()
|
||||
for _, element in pairs(UIElement) do
|
||||
@@ -47,98 +47,98 @@ function MenuStep(menu)
|
||||
end
|
||||
if menu == 0 then
|
||||
elseif menu == "pause" then
|
||||
MenuStepPauseScreen()
|
||||
stepMenuPauseScreen()
|
||||
elseif menu == "dialog" then
|
||||
MenuStepDialog()
|
||||
stepMenuDialog()
|
||||
end
|
||||
end
|
||||
|
||||
function MenuStepPauseScreen()
|
||||
if PauseResume:getVariable() == true then
|
||||
PauseResume = nil
|
||||
PauseOptions = nil
|
||||
PauseExit = nil
|
||||
MenuExit()
|
||||
elseif PauseExit:getVariable() == true then
|
||||
function stepMenuPauseScreen()
|
||||
if pause_resume:getVariable() == true then
|
||||
pause_resume = nil
|
||||
pause_options = nil
|
||||
pause_exit = nil
|
||||
exitMenu()
|
||||
elseif pause_exit:getVariable() == true then
|
||||
love.event.quit()
|
||||
end
|
||||
end
|
||||
|
||||
function MenuStepDialog()
|
||||
if DialogContainer.value >= DialogContainer.target_value then
|
||||
DialogContainer = nil
|
||||
MenuExit()
|
||||
function stepMenuDialog()
|
||||
if dialog_container.value >= dialog_container.target_value then
|
||||
dialog_container = nil
|
||||
exitMenu()
|
||||
end
|
||||
end
|
||||
|
||||
function MenuClear()
|
||||
function clearMenu()
|
||||
for _, element in pairs(UIElement) do
|
||||
element = nil
|
||||
end
|
||||
UIElement = {}
|
||||
end
|
||||
|
||||
function MenuExit(to)
|
||||
MenuClear()
|
||||
function exitMenu(to)
|
||||
clearMenu()
|
||||
local to = to or "no"
|
||||
menu_type = to
|
||||
end
|
||||
|
||||
function MenuInit(menu,parameter)
|
||||
function initMenu(menu,parameter)
|
||||
-- main menu
|
||||
if menu == "pause" then
|
||||
MenuInitPauseScreen()
|
||||
initMenuPauseScreen()
|
||||
elseif menu == "dialog" then
|
||||
if parameter == nil then
|
||||
parameter = DialogSequence.Example
|
||||
parameter = dialog_sequence.Example
|
||||
end
|
||||
MenuInitDialog(parameter)
|
||||
initMenuDialog(parameter)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuInitDialog(parameter)
|
||||
DialogContainer = interfaceDialog:New()
|
||||
DialogContainer:loadSequence(parameter)
|
||||
function initMenuDialog(parameter)
|
||||
dialog_container = InterfaceDialog:new()
|
||||
dialog_container:loadSequence(parameter)
|
||||
end
|
||||
|
||||
function MenuInitPauseScreen()
|
||||
local buttonStandard = {width = 200, height = 30, separation = 10}
|
||||
function initMenuPauseScreen()
|
||||
local button_standard = {width = 200, height = 30, separation = 10}
|
||||
-- elements
|
||||
PauseResume = interfaceButton:New(
|
||||
pause_resume = InterfaceButton:new(
|
||||
game.width/2,
|
||||
game.height/2-buttonStandard.height-buttonStandard.separation,
|
||||
buttonStandard.width,
|
||||
buttonStandard.height,
|
||||
game.height/2-button_standard.height-button_standard.separation,
|
||||
button_standard.width,
|
||||
button_standard.height,
|
||||
{false,true},
|
||||
1,
|
||||
{
|
||||
text = Locale.ui.pause_screen_resume,
|
||||
text = locale.ui.pause_screen_resume,
|
||||
color = {0,0,0.5},
|
||||
color2 = {1,1,1}
|
||||
}
|
||||
)
|
||||
PauseOptions = interfaceButton:New(
|
||||
pause_options = InterfaceButton:new(
|
||||
game.width/2,
|
||||
game.height/2,
|
||||
buttonStandard.width,
|
||||
buttonStandard.height,
|
||||
button_standard.width,
|
||||
button_standard.height,
|
||||
{false,true},
|
||||
1,
|
||||
{
|
||||
text = Locale.ui.pause_screen_options,
|
||||
text = locale.ui.pause_screen_options,
|
||||
color = {0,0,0.5},
|
||||
color2 = {1,1,1}
|
||||
}
|
||||
)
|
||||
PauseExit = interfaceButton:New(
|
||||
pause_exit = InterfaceButton:new(
|
||||
game.width/2,
|
||||
game.height/2+buttonStandard.height+buttonStandard.separation,
|
||||
buttonStandard.width,
|
||||
buttonStandard.height,
|
||||
game.height/2+button_standard.height+button_standard.separation,
|
||||
button_standard.width,
|
||||
button_standard.height,
|
||||
{false,true},
|
||||
1,
|
||||
{
|
||||
text = Locale.ui.pause_screen_exit,
|
||||
text = locale.ui.pause_screen_exit,
|
||||
color = {0,0,0.5},
|
||||
color2 = {1,1,1}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,40 @@
|
||||
LoadedObjects = {}
|
||||
|
||||
-- level functions
|
||||
function LoadedObjects.DrawCollisions()
|
||||
function LoadedObjects.drawCollisions()
|
||||
for _, ladder in pairs(LoadedObjects.Collisions) do
|
||||
ladder:Draw(1)
|
||||
ladder:draw(1)
|
||||
end
|
||||
|
||||
for _, platform in pairs(LoadedObjects.Platforms) do
|
||||
if platform.disable == true then platform:Draw(2) end
|
||||
if platform.disable == false then platform:Draw(1) end
|
||||
if platform.is_disabled == true then platform:Draw(2) end
|
||||
if platform.is_disabled == false then platform:Draw(1) end
|
||||
end
|
||||
|
||||
for _, ladder in pairs(LoadedObjects.Ladders) do
|
||||
ladder:Draw(2)
|
||||
ladder:draw(2)
|
||||
end
|
||||
|
||||
for _, hazard in pairs(LoadedObjects.Hazards) do
|
||||
hazard:Draw(1)
|
||||
hazard:draw(1)
|
||||
end
|
||||
end
|
||||
|
||||
-- returns true if theres a collision at that point
|
||||
function isThereObjectAt(x,y,objectType)
|
||||
for _, object in pairs(objectType) do
|
||||
if object.disable then
|
||||
if object.is_disabled then
|
||||
-- Dont calculate if dissabled
|
||||
elseif x >= object.from.x
|
||||
and x <= object.to.x
|
||||
and y >= object.from.y
|
||||
and y <= object.to.y then
|
||||
object.isColliding = true
|
||||
elseif object:asRect():containsPoint(Point:new(x, y)) then
|
||||
object.is_colliding = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
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
|
||||
function SetCollisionFlags()
|
||||
function setCollisionFlags()
|
||||
local Check = {
|
||||
LoadedObjects.Collisions,
|
||||
LoadedObjects.Ladders,
|
||||
@@ -54,21 +43,21 @@ function SetCollisionFlags()
|
||||
}
|
||||
for _, type in pairs(Check) do
|
||||
for _, object in pairs(type) do
|
||||
object.isColliding = false
|
||||
object.is_colliding = false
|
||||
end
|
||||
end
|
||||
for _, platform in pairs(LoadedObjects.Platforms) do
|
||||
if main_Player.pos.y < platform.from.y then
|
||||
platform.disable = false
|
||||
if main_player.pos.y < platform.from.y then
|
||||
platform.is_disabled = false
|
||||
else
|
||||
platform.disable = true
|
||||
platform.is_disabled = true
|
||||
end
|
||||
end
|
||||
for _, platform in pairs(LoadedObjects.Hazards) do
|
||||
if main_Player.isOnGround then
|
||||
platform.disable = true
|
||||
if main_player.isOnGround then
|
||||
platform.is_disabled = true
|
||||
else
|
||||
platform.disable = false
|
||||
platform.is_disabled = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
Particle = Entity:New(x,y)
|
||||
|
||||
function Particle:New(x,y,particle_data)
|
||||
local o = Entity:New(x,y)
|
||||
|
||||
o.pos = {x = x, y = y}
|
||||
|
||||
|
||||
o.speed = particle_data.speed or 0
|
||||
o.direction = particle_data.direction or o.direction
|
||||
o.sprite_rotation = particle_data.sprite_rotation or o.sprite_rotation
|
||||
o.sprite_offset = particle_data.sprite_offset or o.sprite_offset
|
||||
o.sprite_scale = particle_data.sprite_scale or o.sprite_scale
|
||||
o.sprite_tint = particle_data.sprite_tint or o.sprite_tint
|
||||
o.sprite_alpha = particle_data.sprite_alpha or o.sprite_alpha
|
||||
o.sprite_alpha_base = o.sprite_alpha
|
||||
|
||||
o.sprite_flip = particle_data.sprite_flip or o.sprite_flip
|
||||
o.animation_active = particle_data.animation_active or false
|
||||
|
||||
o.time = 0.5
|
||||
o.timer = 0
|
||||
|
||||
o.vel = {
|
||||
x = o.speed * math.cos(o.direction),
|
||||
y = o.speed * math.sin(o.direction)
|
||||
}
|
||||
|
||||
if particle_data.light ~= nil then
|
||||
o.lightRange = particle_data.light
|
||||
o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange)
|
||||
end
|
||||
|
||||
-- animations
|
||||
o.body = Animation:New(particle_data.animation)
|
||||
o:centerOffset(o.body)
|
||||
if not o.animation_active then
|
||||
o.body.speed = 0
|
||||
end
|
||||
|
||||
table.insert(LoadedParticles,o)
|
||||
o.id = #LoadedParticles
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Particle:Kill()
|
||||
if self.light ~= nil then
|
||||
KillLight(self.light)
|
||||
end
|
||||
if self.id ~= nil then
|
||||
for _, e in pairs(LoadedParticles) do
|
||||
if e.id > self.id then
|
||||
e.id = e.id - 1
|
||||
end
|
||||
end
|
||||
table.remove(LoadedParticles,self.id)
|
||||
end
|
||||
self = nil
|
||||
end
|
||||
|
||||
function Particle:HandleAnimation()
|
||||
self.body:Animate()
|
||||
self.timer = self.timer + current_dt
|
||||
self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time
|
||||
if self.light ~= nil then
|
||||
self.light.range = self.lightRange * self.sprite_alpha/2
|
||||
end
|
||||
if self.sprite_alpha < 0 then self:Kill() end
|
||||
self:Draw(self.body)
|
||||
end
|
||||
|
||||
function Particle:DoPhysics()
|
||||
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, objects.collisions) then
|
||||
self.pos.x = self.pos.x + self.vel.x
|
||||
end
|
||||
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, objects.collisions) then
|
||||
self.pos.y = self.pos.y + self.vel.y
|
||||
end
|
||||
end
|
||||
37
code/point.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
Point = {}
|
||||
Point.__index = Point
|
||||
|
||||
function Point:new(x, y)
|
||||
local o = { x = x or 0, y = y or 0 }
|
||||
setmetatable(o, self)
|
||||
return o
|
||||
end
|
||||
|
||||
function Point:__add(other)
|
||||
return Point:new(self.x+other.x, self.y+other.y)
|
||||
end
|
||||
|
||||
function Point:__sub(other)
|
||||
return Point:new(self.x-other.x, self.y-other.y)
|
||||
end
|
||||
|
||||
function Point:__mul(n)
|
||||
return Point:new(self.x*n, self.y*n)
|
||||
end
|
||||
|
||||
function Point:__div(n)
|
||||
return Point:new(self.x/n, self.y/n)
|
||||
end
|
||||
|
||||
-- absolute value, or the distance from the origin
|
||||
function Point:abs()
|
||||
return math.sqrt(self.x ^ 2 + self.y ^ 2)
|
||||
end
|
||||
|
||||
function Point:__tostring()
|
||||
return "("..self.x..","..self.y..")"
|
||||
end
|
||||
|
||||
function Point:copy()
|
||||
return Point:new(self.x, self.y)
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
Queue = {}
|
||||
|
||||
function Queue:New()
|
||||
function Queue:new()
|
||||
local o = {head = nil, tail = nil}
|
||||
|
||||
setmetatable(o, self)
|
||||
@@ -8,7 +8,7 @@ function Queue:New()
|
||||
return o
|
||||
end
|
||||
|
||||
function Queue:Enqueue(item)
|
||||
function Queue:enqueue(item)
|
||||
local elem = {item = item}
|
||||
if self.head == nil then
|
||||
self.head = elem
|
||||
@@ -22,12 +22,12 @@ function Queue:Enqueue(item)
|
||||
return
|
||||
end
|
||||
|
||||
function Queue:Empty()
|
||||
function Queue:empty()
|
||||
return self.tail == nil
|
||||
end
|
||||
|
||||
function Queue:Dequeue()
|
||||
if self:Empty() then
|
||||
function Queue:dequeue()
|
||||
if self:empty() then
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -40,25 +40,25 @@ function Queue:Dequeue()
|
||||
return item
|
||||
end
|
||||
|
||||
local tq1 = Queue:New()
|
||||
tq1:Enqueue(5)
|
||||
local tq1 = Queue:new()
|
||||
tq1:enqueue(5)
|
||||
assert(tq1.head.item == 5)
|
||||
assert(tq1:Dequeue() == 5)
|
||||
assert(tq1:dequeue() == 5)
|
||||
|
||||
-- queue that keeps a rolling tally of its arguments
|
||||
AvgQueue = {}
|
||||
|
||||
function AvgQueue:New(n, initial)
|
||||
function AvgQueue:new(n, initial)
|
||||
local o = {}
|
||||
|
||||
o.n = n
|
||||
o.queue = Queue:New()
|
||||
o.queue = Queue:new()
|
||||
o.avg = initial
|
||||
|
||||
|
||||
local x = initial / n
|
||||
for _ = 1,n do
|
||||
o.queue:Enqueue(x)
|
||||
o.queue:enqueue(x)
|
||||
end
|
||||
|
||||
setmetatable(o, self)
|
||||
@@ -66,9 +66,9 @@ function AvgQueue:New(n, initial)
|
||||
return o
|
||||
end
|
||||
|
||||
function AvgQueue:Push(item)
|
||||
function AvgQueue:push(item)
|
||||
local x = item/self.n
|
||||
self.avg = self.avg + x - self.queue:Dequeue()
|
||||
self.queue:Enqueue(x)
|
||||
self.avg = self.avg + x - self.queue:dequeue()
|
||||
self.queue:enqueue(x)
|
||||
return self.avg
|
||||
end
|
||||
end
|
||||
|
||||
86
code/rect.lua
Normal 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
|
||||
@@ -7,12 +7,15 @@ require "data/sfx"
|
||||
require "code/locale"
|
||||
|
||||
-- support functions
|
||||
require "code/class"
|
||||
require "code/math"
|
||||
require "code/draw"
|
||||
require "code/hex"
|
||||
require "code/in_out"
|
||||
|
||||
-- classes
|
||||
require "code/point"
|
||||
require "code/rect"
|
||||
require "code/objects"
|
||||
require "code/level"
|
||||
require "code/camera"
|
||||
@@ -22,6 +25,7 @@ require "code/queue"
|
||||
|
||||
-- objects
|
||||
require "code/entity"
|
||||
require "code/spawn"
|
||||
require "code/canvas"
|
||||
require "code/collision"
|
||||
require "code/lights"
|
||||
|
||||
31
code/serialize.lua
Normal 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
|
||||
268
code/spawn.lua
Normal file
@@ -0,0 +1,268 @@
|
||||
LoadedObjects.Spawns = {}
|
||||
|
||||
function addSpawn(archetype, ...)
|
||||
local o = {
|
||||
archetype = archetype,
|
||||
args = {...}
|
||||
}
|
||||
table.insert(LoadedObjects.Spawns, o)
|
||||
end
|
||||
|
||||
function activateSpawns()
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
spawn.archetype:new(unpack(spawn.args))
|
||||
end
|
||||
end
|
||||
|
||||
function deselectSpawns()
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
spawn.selected = nil
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
local offset_x, offset_y = spawn.archetype.display:getCenteredOffset()
|
||||
local left = spawn.args[1] - Camera.pos.x - offset_x
|
||||
local top = spawn.args[2] - Camera.pos.y - offset_y
|
||||
local right = spawn.args[1] - Camera.pos.x + offset_x
|
||||
local bottom = spawn.args[2] - Camera.pos.y + offset_y
|
||||
|
||||
local spawn_rect = Rect:fromCoords(left, top, right, bottom)
|
||||
if spawn_rect:overlapsRect(select_rect) then
|
||||
spawn.selected = true
|
||||
end
|
||||
|
||||
if spawn.selected then
|
||||
love.graphics.setColor(0,1,1,1)
|
||||
else
|
||||
love.graphics.setColor(0,1,0,1)
|
||||
end
|
||||
|
||||
love.graphics.rectangle("fill",left-2,top-2,4,4)
|
||||
love.graphics.rectangle("fill",right-2,bottom-2,4,4)
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
end
|
||||
end
|
||||
|
||||
function moveSpawns(x,y)
|
||||
local move_x = nil
|
||||
local move_y = nil
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
if spawn.selected then
|
||||
local difference_x = math.floor((x/game.scale)+Camera.pos.x) - spawn.args[1]
|
||||
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
|
||||
|
||||
|
||||
function promptSpawnNew()
|
||||
Prompt:cancelActive()
|
||||
local text = ""
|
||||
local prompt = Prompt:new({
|
||||
name = "new spawn",
|
||||
input = text,
|
||||
func = function(prompt)
|
||||
local f = loadstring("return {"..prompt.input.."}")
|
||||
if f ~= nil then
|
||||
local succ, result = pcall(f)
|
||||
local arch = result[1]
|
||||
local args = {}
|
||||
if #result > 1 then
|
||||
for i=2, #result+1 do
|
||||
print("arg #"..i-1)
|
||||
args[i-1] = result[i]
|
||||
if i < 4 then
|
||||
args[i-1] = math.floor(args[i-1])
|
||||
end
|
||||
end
|
||||
else
|
||||
args = {0,0}
|
||||
end
|
||||
|
||||
print("new entity spawn --",succ)
|
||||
if not succ
|
||||
or checkArchetypeInvalid(arch)
|
||||
then
|
||||
print("invalid input for prompt "..prompt.name)
|
||||
else
|
||||
print("archetype: ",arch.type)
|
||||
print("args: ",unpack(args))
|
||||
addSpawn(arch, unpack(args))
|
||||
end
|
||||
else
|
||||
print("invalid input for prompt "..prompt.name)
|
||||
end
|
||||
end,
|
||||
})
|
||||
prompt.pos.x = 0
|
||||
prompt.pos.y = 10
|
||||
prompt:activate()
|
||||
end
|
||||
|
||||
function deleteSpawn()
|
||||
for i=1, #LoadedObjects.Spawns do
|
||||
if LoadedObjects.Spawns[i]
|
||||
and LoadedObjects.Spawns[i].selected then
|
||||
table.remove(LoadedObjects.Spawns,i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkArchetypeInvalid(arch)
|
||||
return type(arch) ~= "table" or type(arch.type) ~= "string"
|
||||
end
|
||||
|
||||
function promptSpawnArchetype()
|
||||
Prompt:cancelActive()
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
if spawn.selected then
|
||||
local offset_x, offset_y = spawn.archetype.display:getCenteredOffset()
|
||||
local text = ""
|
||||
for i=1, #spawn.args do
|
||||
if i > 1 then text = text .. ", " end
|
||||
text = text .. tostring(spawn.args[i])
|
||||
end
|
||||
local prompt = Prompt:new({
|
||||
name = "archetype",
|
||||
input = spawn.archetype.type,
|
||||
spawn = spawn,
|
||||
func = function(prompt)
|
||||
print("return "..prompt.input)
|
||||
local f = loadstring("return "..prompt.input)
|
||||
if f ~= nil then
|
||||
local succ, arch = pcall(f)
|
||||
print("archetype changed --",succ)
|
||||
print("from: ", spawn.archetype.type)
|
||||
if not succ
|
||||
or checkArchetypeInvalid(arch)
|
||||
then
|
||||
arch = spawn.archetype
|
||||
end
|
||||
print("to: ", arch.type)
|
||||
spawn.archetype = arch
|
||||
else
|
||||
print("invalid input for prompt "..prompt.name)
|
||||
end
|
||||
end,
|
||||
})
|
||||
prompt.pos.x = (spawn.args[1]-4)*game.scale - Camera.pos.x - offset_x
|
||||
prompt.pos.y = (spawn.args[2]-20)*game.scale - Camera.pos.y - offset_y
|
||||
prompt:activate()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function checkArgsInvalid(args)
|
||||
for _, arg in pairs(args) do
|
||||
-- this is checking the args are not nil variables
|
||||
if arg == nil
|
||||
or arg == ""
|
||||
then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function promptSpawnArgs()
|
||||
Prompt:cancelActive()
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
if spawn.selected then
|
||||
local offset_x, offset_y = spawn.archetype.display:getCenteredOffset()
|
||||
local text = ""
|
||||
for i=1, #spawn.args do
|
||||
if i > 1 then text = text .. ", " end
|
||||
text = text .. tostring(spawn.args[i])
|
||||
end
|
||||
local prompt = Prompt:new({
|
||||
name = "args",
|
||||
input = text,
|
||||
func = function(prompt)
|
||||
local f = loadstring("return {"..prompt.input.."}")
|
||||
if f ~= nil then
|
||||
local succ, args = pcall(f)
|
||||
print("args changed --",succ)
|
||||
print("from: ", unpack(args))
|
||||
if not succ
|
||||
or checkArgsInvalid(args)
|
||||
then
|
||||
args = spawn.args
|
||||
end
|
||||
print("to: ", unpack(args))
|
||||
spawn.args = args
|
||||
else
|
||||
print("invalid input for prompt "..prompt.name)
|
||||
end
|
||||
end,
|
||||
})
|
||||
prompt.pos.x = (spawn.args[1]-4)*game.scale - Camera.pos.x - offset_x
|
||||
prompt.pos.y = (spawn.args[2]-4)*game.scale - Camera.pos.y - offset_y
|
||||
prompt:activate()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function drawSpawns()
|
||||
for _, spawn in pairs(LoadedObjects.Spawns) do
|
||||
local offset_x, offset_y = spawn.archetype.display:getCenteredOffset()
|
||||
love.graphics.setColor(1,1,1,1)
|
||||
spawn.archetype.display:draw(
|
||||
spawn.args[1] - Camera.pos.x - offset_x,
|
||||
spawn.args[2] - Camera.pos.y - offset_y
|
||||
)
|
||||
|
||||
|
||||
if spawn.selected then
|
||||
love.graphics.setColor(0,1,1,1)
|
||||
else
|
||||
love.graphics.setColor(0,1,0,1)
|
||||
end
|
||||
|
||||
love.graphics.rectangle(
|
||||
"line",
|
||||
spawn.args[1] - Camera.pos.x - offset_x,
|
||||
spawn.args[2] - Camera.pos.y - offset_y,
|
||||
spawn.args[1] - Camera.pos.x + offset_x - (spawn.args[1] - Camera.pos.x - offset_x),
|
||||
spawn.args[2] - Camera.pos.y + offset_y - (spawn.args[2] - Camera.pos.y - offset_y)
|
||||
)
|
||||
|
||||
if spawn.selected then
|
||||
local text = spawn.archetype.type .."\n("
|
||||
local ancestors = getAncestors(spawn.archetype)
|
||||
for i=1, #ancestors do
|
||||
if i > 1 then text = text .. ", " end
|
||||
text = text .. ancestors[i].type
|
||||
end
|
||||
text = text ..")\n---\nPosition\n["..spawn.args[1]..","..spawn.args[2].."]"
|
||||
if #spawn.args > 2 then
|
||||
text = text .. "\n---\nData:\n"
|
||||
for i=3, #spawn.args do
|
||||
if i > 3 then text = text .. ", " end
|
||||
text = text .. tostring(spawn.args[i])
|
||||
end
|
||||
end
|
||||
drawTextBox(
|
||||
text,
|
||||
spawn.args[1] - Camera.pos.x + 20,
|
||||
spawn.args[2] - Camera.pos.y
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
37
code/ui.lua
@@ -1,9 +1,44 @@
|
||||
UIElement = {}
|
||||
|
||||
function AddElement(self)
|
||||
function addElement(self)
|
||||
table.insert(UIElement,self)
|
||||
self.id = #UIElement
|
||||
end
|
||||
|
||||
function drawTextBox(text,x,y,style)
|
||||
local style = style or {}
|
||||
local c1, c2, c3, a = love.graphics.getColor()
|
||||
local width = locale_font:getWidth(text)
|
||||
local height = locale_font:getHeight(text)
|
||||
|
||||
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
|
||||
for i in text:gmatch("\n") do
|
||||
lines = lines + 1
|
||||
end
|
||||
|
||||
love.graphics.setColor(unpack(color))
|
||||
love.graphics.rectangle("fill",
|
||||
x-1,
|
||||
y-1,
|
||||
width+margin*2+2,
|
||||
height*lines+margin*2+2
|
||||
)
|
||||
love.graphics.setColor(unpack(background_color))
|
||||
love.graphics.rectangle("fill",
|
||||
x,
|
||||
y,
|
||||
width+margin*2,
|
||||
height*lines+margin*2
|
||||
)
|
||||
love.graphics.setColor(unpack(color))
|
||||
love.graphics.print(text, x+margin, y+margin)
|
||||
love.graphics.setColor(c1,c2,c3,a)
|
||||
end
|
||||
|
||||
require "code/ui/button"
|
||||
require "code/ui/dialog"
|
||||
require "code/ui/prompt"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interfaceButton = {type = "Button"}
|
||||
InterfaceButton = {type = "Button"}
|
||||
|
||||
-- centered buttons
|
||||
function interfaceButton:New(x,y,w,h,table_values,value,style)
|
||||
function InterfaceButton:new(x,y,w,h,table_values,value,style)
|
||||
local o = {}
|
||||
|
||||
o.pos = {
|
||||
@@ -39,18 +39,18 @@ function interfaceButton:New(x,y,w,h,table_values,value,style)
|
||||
scale_proportion = 1.5
|
||||
}
|
||||
|
||||
AddElement(o)
|
||||
addElement(o)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function interfaceButton:getVariable()
|
||||
function InterfaceButton:getVariable()
|
||||
return self.target_variable
|
||||
end
|
||||
|
||||
function interfaceButton:checkMouse(mouse_x, mouse_y)
|
||||
function InterfaceButton:checkMouse(mouse_x, mouse_y)
|
||||
if not self.clicked
|
||||
and mouse_x < self.pos.x + self.size.w/2
|
||||
and mouse_x > self.pos.x - self.size.w/2
|
||||
@@ -71,7 +71,7 @@ function interfaceButton:checkMouse(mouse_x, mouse_y)
|
||||
end
|
||||
end
|
||||
|
||||
function interfaceButton:Draw()
|
||||
function InterfaceButton:draw()
|
||||
local c1, c2, c3, a = love.graphics.getColor()
|
||||
|
||||
love.graphics.setColor(self.style.color[1],self.style.color[2],self.style.color[3],self.style.alpha)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
interfaceDialog = {type = "Dialog"}
|
||||
InterfaceDialog = {type = "Dialog"}
|
||||
-- dialog boxes
|
||||
function interfaceDialog:New(style)
|
||||
function InterfaceDialog:new(style)
|
||||
local o = {}
|
||||
|
||||
o.pos = {
|
||||
@@ -29,14 +29,14 @@ function interfaceDialog:New(style)
|
||||
scale_proportion = 1
|
||||
}
|
||||
|
||||
AddElement(o)
|
||||
addElement(o)
|
||||
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function interfaceDialog:updateContents()
|
||||
function InterfaceDialog:updateContents()
|
||||
if self.value < self.target_value then
|
||||
self.contents = self.sequence[self.value]
|
||||
if self.contents[1] == nil then self.contents[1] = "" end
|
||||
@@ -45,14 +45,14 @@ function interfaceDialog:updateContents()
|
||||
end
|
||||
end
|
||||
|
||||
function interfaceDialog:loadSequence(sequence)
|
||||
function InterfaceDialog:loadSequence(sequence)
|
||||
self.sequence = sequence
|
||||
self.value = 1
|
||||
self.target_value = 1+#sequence
|
||||
self:updateContents()
|
||||
end
|
||||
|
||||
function interfaceDialog:checkConfirm()
|
||||
function InterfaceDialog:checkConfirm()
|
||||
if not self.clicked then
|
||||
if love.mouse.isDown(1) then
|
||||
self.clicked = true
|
||||
@@ -65,7 +65,7 @@ function interfaceDialog:checkConfirm()
|
||||
end
|
||||
end
|
||||
|
||||
function interfaceDialog:Draw()
|
||||
function InterfaceDialog:draw()
|
||||
local c1, c2, c3, a = love.graphics.getColor()
|
||||
|
||||
love.graphics.setColor(self.style.color[1],self.style.color[2],self.style.color[3],self.style.alpha)
|
||||
|
||||
80
code/ui/prompt.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
local utf8 = require("utf8")
|
||||
|
||||
local function backspace(text)
|
||||
local byteoffset = utf8.offset(text, -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(text, 1, -2).
|
||||
return string.sub(text, 1, byteoffset - 1)
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
Prompt = class(nil, {
|
||||
-- defaults for instance variables
|
||||
pos = { x = 10, y = 10 },
|
||||
input = "",
|
||||
name = "input",
|
||||
canceled = false,
|
||||
closing = false,
|
||||
color = {1,1,1,1},
|
||||
background_color = {0,0,0,1},
|
||||
active_prompt = nil,
|
||||
})
|
||||
function Prompt:cancelActive()
|
||||
if Prompt.active_prompt then
|
||||
Prompt.active_prompt.canceled = true
|
||||
end
|
||||
end
|
||||
|
||||
function Prompt:new(o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
return o
|
||||
end
|
||||
|
||||
function Prompt:keypressed(key, scancode, isrepeat)
|
||||
if key == "backspace" then
|
||||
self.input = backspace(self.input)
|
||||
elseif key == "return" or key == "kpenter" or key == "escape" then
|
||||
if key == "escape" then
|
||||
self.canceled = true
|
||||
end
|
||||
self.closing = true
|
||||
self:func()
|
||||
end
|
||||
end
|
||||
|
||||
function Prompt:update()
|
||||
|
||||
end
|
||||
|
||||
function Prompt:textinput(text)
|
||||
self.input = self.input .. text
|
||||
end
|
||||
|
||||
function Prompt:draw()
|
||||
drawTextBox(
|
||||
self.name .. ": " .. self.input,
|
||||
self.pos.x,
|
||||
self.pos.y,
|
||||
{
|
||||
color = self.color,
|
||||
background_color = self.background_color
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function Prompt:activate()
|
||||
Prompt.active_prompt = self
|
||||
love.keyboard.setTextInput(true)
|
||||
end
|
||||
|
||||
-- demonstration of how default values work
|
||||
local test_prompt = Prompt:new()
|
||||
assert(test_prompt.name == "input")
|
||||
test_prompt.name = "foobar"
|
||||
assert(Prompt.name == "input")
|
||||
@@ -35,11 +35,11 @@ animation.cursed_book.flying = {
|
||||
animation.cursed_book.spawn = {
|
||||
path = "assets/entities/cursed_book/spawn",
|
||||
frames = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
1/3,
|
||||
1/3,
|
||||
1/3,
|
||||
1/3,
|
||||
1/3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,15 @@ animation.moth_mask.fall = {
|
||||
1/8
|
||||
}
|
||||
}
|
||||
|
||||
animation.moth_mask.slide = {
|
||||
path = "assets/entities/nancy/moth_mask/slide",
|
||||
frames = {
|
||||
1/8,
|
||||
1/8,
|
||||
1/8
|
||||
}
|
||||
}
|
||||
animation.moth_mask.jump = {
|
||||
path = "assets/entities/nancy/moth_mask/jump",
|
||||
frames = {
|
||||
@@ -179,6 +188,14 @@ animation.nancy.fall = {
|
||||
1/8
|
||||
}
|
||||
}
|
||||
animation.nancy.slide = {
|
||||
path = "assets/entities/nancy/slide",
|
||||
frames = {
|
||||
1/8,
|
||||
1/8,
|
||||
1/8
|
||||
}
|
||||
}
|
||||
animation.nancy.jump = {
|
||||
path = "assets/entities/nancy/jump",
|
||||
frames = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
DialogSequence = {}
|
||||
dialog_sequence = {}
|
||||
|
||||
DialogSequence.Example = {
|
||||
{Locale.dialogue.example[1],Locale.name.fairy},
|
||||
{Locale.dialogue.example[2],Locale.name.chaos},
|
||||
{Locale.dialogue.example[3],Locale.name.life}
|
||||
dialog_sequence.example = {
|
||||
{locale.dialogue.example[1],locale.name.fairy},
|
||||
{locale.dialogue.example[2],locale.name.chaos},
|
||||
{locale.dialogue.example[3],locale.name.life}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
return {
|
||||
name = "test",
|
||||
name = "Dev Level",
|
||||
tileset = tileset.library,
|
||||
properties = {
|
||||
darkness = true
|
||||
@@ -24,9 +24,20 @@ return {
|
||||
{ 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}},
|
||||
{Candelabra,{328,297}}
|
||||
},
|
||||
rooms = {
|
||||
{{96,64},{544,320}},
|
||||
{{0,0},{112,176}}
|
||||
},
|
||||
},
|
||||
objects = {}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
LocaleFont = love.graphics.getFont()
|
||||
locale_font = love.graphics.getFont()
|
||||
|
||||
Locale = {}
|
||||
locale = {}
|
||||
|
||||
Locale.ui = {}
|
||||
Locale.ui.pause_screen_resume = "Resume"
|
||||
Locale.ui.pause_screen_options = "Options"
|
||||
Locale.ui.pause_screen_exit = "Exit"
|
||||
locale.ui = {}
|
||||
locale.ui.pause_screen_resume = "Resume"
|
||||
locale.ui.pause_screen_options = "Options"
|
||||
locale.ui.pause_screen_exit = "Exit"
|
||||
|
||||
Locale.name = {}
|
||||
Locale.name.fairy = "Ozy"
|
||||
Locale.name.chaos = "Aelato"
|
||||
Locale.name.life = "Olidia"
|
||||
locale.name = {}
|
||||
locale.name.fairy = "Ozy"
|
||||
locale.name.chaos = "Aelato"
|
||||
locale.name.life = "Olidia"
|
||||
|
||||
Locale.dialogue = {}
|
||||
Locale.dialogue.example = {"Hello!","Duh.","Lol"}
|
||||
locale.dialogue = {}
|
||||
locale.dialogue.example = {"Hello!","Duh.","Lol"}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
LocaleFont = love.graphics.newFont("assets/ui/fonts/heon.ttf",18)
|
||||
locale_font = love.graphics.newFont("assets/ui/fonts/heon.ttf",18)
|
||||
|
||||
Locale = {}
|
||||
locale = {}
|
||||
|
||||
Locale.ui = {}
|
||||
Locale.ui.pause_screen_resume = ""
|
||||
Locale.ui.pause_screen_options = ""
|
||||
Locale.ui.pause_screen_exit = ""
|
||||
locale.ui = {}
|
||||
locale.ui.pause_screen_resume = ""
|
||||
locale.ui.pause_screen_options = ""
|
||||
locale.ui.pause_screen_exit = ""
|
||||
|
||||
Locale.name = {}
|
||||
Locale.name.fairy = ""
|
||||
Locale.name.chaos = ""
|
||||
Locale.name.life = ""
|
||||
locale.name = {}
|
||||
locale.name.fairy = ""
|
||||
locale.name.chaos = ""
|
||||
locale.name.life = ""
|
||||
|
||||
Locale.dialogue = {}
|
||||
Locale.dialogue.example = {"","",""}
|
||||
locale.dialogue = {}
|
||||
locale.dialogue.example = {"","",""}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Shader = {}
|
||||
Shader.RadiusGradient = love.graphics.newShader[[
|
||||
shader = {}
|
||||
shader.circle_gradient = love.graphics.newShader[[
|
||||
uniform float pos_x;
|
||||
uniform float pos_y;
|
||||
uniform float range;
|
||||
uniform float radius;
|
||||
uniform float scale;
|
||||
|
||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){
|
||||
@@ -12,11 +12,13 @@ Shader.RadiusGradient = love.graphics.newShader[[
|
||||
float distance_x = pos_x - screen_coords.x / scale;
|
||||
float distance_y = pos_y - screen_coords.y / scale;
|
||||
float distance = sqrt( pow(distance_x,2) + pow(distance_y,2) ) ;
|
||||
if (distance < range){
|
||||
float alpha = 1-(5*distance/range);
|
||||
if (distance < radius){
|
||||
float alpha = 1-(5*distance/radius);
|
||||
if (pixel.a > alpha){
|
||||
pixel.a = alpha;
|
||||
}
|
||||
} else {
|
||||
pixel.a = 0;
|
||||
}
|
||||
return pixel * color * color;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
levelProperties = {
|
||||
level_properties = {
|
||||
pos = {
|
||||
x = 0,
|
||||
y = 0
|
||||
@@ -15,7 +15,7 @@ tileset = {
|
||||
library = love.graphics.newImage("assets/tileset/library.png")
|
||||
}
|
||||
|
||||
tileProperties = {
|
||||
tile_properties = {
|
||||
width = 16,
|
||||
height = 16,
|
||||
scale = 1,
|
||||
|
||||
136
main.lua
@@ -1,15 +1,17 @@
|
||||
function love.load()
|
||||
logging = true
|
||||
loveMemUsage = collectgarbage("count")
|
||||
loveInitLog = "love: "..loveMemUsage.." kB, time: "..os.clock().." seconds"
|
||||
arrow = 0
|
||||
local love_mem_usage = collectgarbage("count")
|
||||
local love_init_log = "love: "..love_mem_usage.." kB, time: "..os.clock().." seconds"
|
||||
|
||||
secs = 0
|
||||
|
||||
menu_type = "no"
|
||||
-- FIXME: this overrides a standard library!
|
||||
debug = false
|
||||
debug_collision = false
|
||||
editor_mode = false
|
||||
--editor_mode = false
|
||||
|
||||
textScale = 1
|
||||
text_size = 1
|
||||
|
||||
|
||||
love.graphics.setColor(1,1,1)
|
||||
@@ -17,7 +19,7 @@ function love.load()
|
||||
love.graphics.setDefaultFilter("nearest") -- good pixel
|
||||
|
||||
game = {
|
||||
secondsSinceStart = 0,
|
||||
seconds_since_start = 0,
|
||||
scale = 2,
|
||||
width = love.graphics.getWidth(),
|
||||
height = love.graphics.getHeight(),
|
||||
@@ -26,90 +28,126 @@ function love.load()
|
||||
|
||||
require "code/require"
|
||||
|
||||
fps_history = AvgQueue:New(30,60)
|
||||
fps_history = AvgQueue:new(30,60)
|
||||
|
||||
|
||||
logPrint(loveInitLog)
|
||||
loveInitLog = nil
|
||||
logPrint(love_init_log)
|
||||
love_init_log = nil
|
||||
|
||||
Camera.width = game.width
|
||||
Camera.height = game.height
|
||||
|
||||
levelList = scandir("./data/levels")
|
||||
levelNum = 1
|
||||
currLevel = levelList[levelNum]
|
||||
logPrint("currLevel: "..currLevel)
|
||||
LoadedParticles = {}
|
||||
LevelLoadTiles()
|
||||
level_list = scandir("./data/levels")
|
||||
level_current_num = 1
|
||||
level_current = level_list[level_current_num]
|
||||
logPrint("level_current: "..level_current)
|
||||
|
||||
loadLevelTiles()
|
||||
|
||||
language = "ENG"
|
||||
LocaleLoad(language)
|
||||
loadLocale(language)
|
||||
|
||||
gravity = 0.14
|
||||
-- Debug and log stuff
|
||||
memoryUsage, dtcount = 0, 0
|
||||
memory_usage, dtcount = 0, 0
|
||||
logPrint("mothback: "..collectgarbage("count").." kB, Loading time: "..os.clock().." seconds")
|
||||
|
||||
main_Player = Player:New(75,50)
|
||||
|
||||
--Kupo:New(100,150)
|
||||
--Kupo:New(300,150)
|
||||
HookAnchor:New(200,89)
|
||||
HookAnchor:New(400,89)
|
||||
Fairy:New(200,88)
|
||||
--CursedBook:New(180,68)
|
||||
main_player = Player:new(75,50)
|
||||
|
||||
activateSpawns()
|
||||
--love.audio.play(music.placeholder)
|
||||
end
|
||||
|
||||
function love.textinput(text)
|
||||
if Prompt.active_prompt then
|
||||
Prompt.active_prompt:textinput(text)
|
||||
end
|
||||
end
|
||||
|
||||
function love.keypressed(...)
|
||||
if Prompt.active_prompt then
|
||||
Prompt.active_prompt:keypressed(...)
|
||||
end
|
||||
end
|
||||
|
||||
function love.update(dt)
|
||||
-- audio update
|
||||
love.audio.update()
|
||||
-- fps counter
|
||||
fps_current = fps_history:Push(1/dt)
|
||||
fps_current = fps_history:push(1/dt)
|
||||
|
||||
current_dt = dt
|
||||
game.secondsSinceStart = game.secondsSinceStart + dt
|
||||
game.seconds_since_start = game.seconds_since_start + dt
|
||||
|
||||
if DemoRecording or DemoPlayback then Demo:Step() end
|
||||
if DemoRecording or DemoPlayback then Demo:step() end
|
||||
|
||||
-- things per second
|
||||
dtcount = dtcount + dt
|
||||
game.seconds_since_start = game.seconds_since_start + dt
|
||||
if dtcount >= 1 then
|
||||
if secs == nil then secs = 0 end
|
||||
secs = secs + 1
|
||||
dtcount = dtcount - 1
|
||||
if debug or logging then
|
||||
memoryUsage = math.floor(collectgarbage("count"))
|
||||
memory_usage = math.floor(collectgarbage("count"))
|
||||
end
|
||||
logWrite("Second "..secs..": "..memoryUsage.." kB")
|
||||
logWrite("Second "..secs..": "..memory_usage.." kB")
|
||||
end
|
||||
|
||||
if Prompt.active_prompt then
|
||||
-- try to stop the keypress that closed the menu from spilling into the rest of the game
|
||||
Keybind:checkPressed(Keybind.menu.pause)
|
||||
if Prompt.active_prompt.closing then
|
||||
Prompt.active_prompt = nil
|
||||
else
|
||||
Prompt.active_prompt:update()
|
||||
end
|
||||
return
|
||||
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
|
||||
local test_prompt = Prompt:new({
|
||||
name = "test prompt",
|
||||
func = function(prompt)
|
||||
print("test prompt got input: "..prompt.input)
|
||||
end,
|
||||
})
|
||||
test_prompt:activate()
|
||||
end
|
||||
|
||||
--keypressed
|
||||
if Keybind:CheckPressed(Keybind.menu.pause) then
|
||||
if do_pause then
|
||||
if Keybind:checkPressed(Keybind.menu.pause) then
|
||||
if do_pause then
|
||||
do_pause = false
|
||||
else
|
||||
menu_type = "pause"
|
||||
MenuInit(menu_type)
|
||||
initMenu(menu_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--MenuStep
|
||||
if menu_type ~= nil then MenuStep(menu_type) end
|
||||
if menu_type ~= nil then stepMenu(menu_type) end
|
||||
|
||||
--editor
|
||||
if editor_mode then
|
||||
EditorStep()
|
||||
if editor.active then
|
||||
stepEditor()
|
||||
else
|
||||
GameStep()
|
||||
stepGame()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function love.wheelmoved(_, y)
|
||||
if editor_mode then
|
||||
EditorScroll(y)
|
||||
if editor.active then
|
||||
scrollEditor(y)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -122,15 +160,21 @@ function love.draw()
|
||||
game_resize = false
|
||||
end
|
||||
|
||||
if editor_mode then
|
||||
EditorDraw()
|
||||
if editor.active then
|
||||
drawEditor()
|
||||
else
|
||||
GameDraw()
|
||||
drawGame()
|
||||
end
|
||||
|
||||
if menu_type ~= nil then MenuDraw(menu_type) end
|
||||
if menu_type ~= nil then drawMenu(menu_type) end
|
||||
|
||||
love.graphics.print(game.scale,10,40)
|
||||
|
||||
if DemoRecording or DemoPlayback then Demo:Draw() end
|
||||
if DemoRecording or DemoPlayback then Demo:draw() end
|
||||
|
||||
if Prompt.active_prompt then
|
||||
Prompt.active_prompt:draw()
|
||||
end
|
||||
|
||||
frameDebugFlush()
|
||||
end
|
||||
|
||||