added a timer for cleaner execution, goodbye resolver!
This commit is contained in:
31
crate.lua
31
crate.lua
@@ -1,7 +1,9 @@
|
|||||||
-- Chuchu by Makaron
|
-- Chuchu by Makaron
|
||||||
-- Crates are the main thing so here we go
|
-- Crates are the main thing so here we go
|
||||||
|
local Timer = require('deps.knife.timer')
|
||||||
|
|
||||||
local CONST_ITERATIONS_RESOLVE = 1
|
local CONST_ITERATIONS_RESOLVE = .01
|
||||||
|
local CONST_TIME_TO_RELOAD = .4
|
||||||
|
|
||||||
local Crates = {
|
local Crates = {
|
||||||
world = nil,
|
world = nil,
|
||||||
@@ -22,15 +24,16 @@ function Crate.new(world, x, y)
|
|||||||
object.attached = false
|
object.attached = false
|
||||||
object.contact = { }
|
object.contact = { }
|
||||||
object.joint = nil
|
object.joint = nil
|
||||||
object.resolver = nil
|
|
||||||
|
|
||||||
object.collider:setPresolve(function (shape1, shape2, contact)
|
object.collider:setPresolve(function (shape1, shape2, contact)
|
||||||
print(shape2:getClass())
|
|
||||||
if shape2:getClass() == 'Player' and object.attached == false then
|
if shape2:getClass() == 'Player' and object.attached == false then
|
||||||
contact:setEnabled(false)
|
contact:setEnabled(false)
|
||||||
object.contact.x, object.contact.y = contact:getPositions()
|
object.contact.x, object.contact.y = contact:getPositions()
|
||||||
object.resolver = CONST_ITERATIONS_RESOLVE
|
|
||||||
object.attached = true
|
object.attached = true
|
||||||
|
Timer.after(CONST_ITERATIONS_RESOLVE, function ()
|
||||||
|
object.joint = Crates.world:addJoint('revolute', Crates.player.collider, object.collider, object.contact.x, object.contact.y, true)
|
||||||
|
table.insert(Crates.attached, object)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -49,23 +52,21 @@ function Crates:spawn(x, y)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Crates:update(dt)
|
function Crates:update(dt)
|
||||||
for key in pairs(self.list) do
|
Timer.update(dt)
|
||||||
if self.list[key].resolver ~= nil then
|
|
||||||
self.list[key].resolver = self.list[key].resolver - 1
|
|
||||||
if self.list[key].resolver <= 0 then
|
|
||||||
curContact = self.list[key].contact
|
|
||||||
self.world:addJoint('revolute', self.player.collider, self.list[key].collider, curContact.x, curContact.y, true)
|
|
||||||
self.list[key].resolver = nil
|
|
||||||
table.insert(self.attached, self.list[key])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Crates:getAttached()
|
function Crates:getAttached()
|
||||||
return self.attached
|
return self.attached
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Crates:detach(key)
|
||||||
|
self.attached[key].joint._joint:destroy()
|
||||||
|
Timer.after(CONST_TIME_TO_RELOAD, function ()
|
||||||
|
self.attached[key].attached = false
|
||||||
|
table.remove(self.attached, key)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
return setmetatable(Crates, {
|
return setmetatable(Crates, {
|
||||||
__call = function(_, ...) return new(...) end
|
__call = function(_, ...) return new(...) end
|
||||||
})
|
})
|
||||||
|
|||||||
244
deps/knife/timer.lua
vendored
Normal file
244
deps/knife/timer.lua
vendored
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
local Timer = {}
|
||||||
|
|
||||||
|
-- group management
|
||||||
|
|
||||||
|
local function detach (group, item)
|
||||||
|
local index = item.index
|
||||||
|
|
||||||
|
group[index] = group[#group]
|
||||||
|
group[index].index = index
|
||||||
|
group[#group] = nil
|
||||||
|
item.groupField = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function attach (group, item)
|
||||||
|
if item.groupField then
|
||||||
|
detach (item.groupField, item)
|
||||||
|
end
|
||||||
|
|
||||||
|
local index = #group + 1
|
||||||
|
|
||||||
|
item.index = index
|
||||||
|
group[index] = item
|
||||||
|
item.groupField = group
|
||||||
|
item.lastGroup = group
|
||||||
|
end
|
||||||
|
|
||||||
|
-- instance update methods
|
||||||
|
|
||||||
|
local function updateContinuous (self, dt)
|
||||||
|
local cutoff = self.cutoff
|
||||||
|
local elapsed = self.elapsed + dt
|
||||||
|
|
||||||
|
if self:callback(dt) == false or elapsed >= cutoff then
|
||||||
|
if self.finishField then
|
||||||
|
self:finishField(elapsed - cutoff)
|
||||||
|
end
|
||||||
|
self:remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.elapsed = elapsed
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateIntermittent (self, dt)
|
||||||
|
local duration = self.delay or self.interval
|
||||||
|
local elapsed = self.elapsed + dt
|
||||||
|
|
||||||
|
while elapsed >= duration do
|
||||||
|
elapsed = elapsed - duration
|
||||||
|
if self.limitField then
|
||||||
|
self.limitField = self.limitField - 1
|
||||||
|
end
|
||||||
|
if self:callback(elapsed) == false
|
||||||
|
or self.delay or self.limitField == 0 then
|
||||||
|
if self.finishField then
|
||||||
|
self:finishField(elapsed)
|
||||||
|
end
|
||||||
|
self:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.elapsed = elapsed
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateTween (self, dt)
|
||||||
|
local elapsed = self.elapsed + dt
|
||||||
|
local plan = self.plan
|
||||||
|
local duration = self.duration
|
||||||
|
|
||||||
|
self.elapsed = elapsed
|
||||||
|
|
||||||
|
if elapsed >= duration then
|
||||||
|
for index = 1, #plan do
|
||||||
|
local task = plan[index]
|
||||||
|
|
||||||
|
task.target[task.key] = task.final
|
||||||
|
end
|
||||||
|
if self.finishField then
|
||||||
|
self:finishField(elapsed - duration)
|
||||||
|
end
|
||||||
|
self:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ease = self.easeField
|
||||||
|
|
||||||
|
for index = 1, #plan do
|
||||||
|
local task = plan[index]
|
||||||
|
local target, key = task.target, task.key
|
||||||
|
local initial, change = task.initial, task.change
|
||||||
|
|
||||||
|
target[key] = ease(elapsed, initial, change, duration)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- shared instance methods
|
||||||
|
|
||||||
|
local defaultGroup = {}
|
||||||
|
|
||||||
|
local function group (self, group)
|
||||||
|
if not group then
|
||||||
|
group = defaultGroup
|
||||||
|
end
|
||||||
|
|
||||||
|
attach(group, self)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove (self)
|
||||||
|
if self.groupField then
|
||||||
|
detach(self.groupField, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function register (self)
|
||||||
|
attach(self.lastGroup, self)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function limit (self, limitField)
|
||||||
|
self.limitField = limitField
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function finish (self, finishField)
|
||||||
|
self.finishField = finishField
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ease (self, easeField)
|
||||||
|
self.easeField = easeField
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-- tweening helper functions
|
||||||
|
|
||||||
|
local function planTween (definition)
|
||||||
|
local plan = {}
|
||||||
|
|
||||||
|
for target, values in pairs(definition) do
|
||||||
|
for key, final in pairs(values) do
|
||||||
|
local initial = target[key]
|
||||||
|
|
||||||
|
plan[#plan + 1] = {
|
||||||
|
target = target,
|
||||||
|
key = key,
|
||||||
|
initial = initial,
|
||||||
|
final = final,
|
||||||
|
change = final - initial,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return plan
|
||||||
|
end
|
||||||
|
|
||||||
|
local function easeLinear (elapsed, initial, change, duration)
|
||||||
|
return change * elapsed / duration + initial
|
||||||
|
end
|
||||||
|
|
||||||
|
-- instance initializer
|
||||||
|
|
||||||
|
local function initialize (timer)
|
||||||
|
timer.elapsed = 0
|
||||||
|
timer.group = group
|
||||||
|
timer.remove = remove
|
||||||
|
timer.register = register
|
||||||
|
|
||||||
|
attach(defaultGroup, timer)
|
||||||
|
|
||||||
|
return timer
|
||||||
|
end
|
||||||
|
|
||||||
|
-- static api
|
||||||
|
|
||||||
|
function Timer.after (delay, callback)
|
||||||
|
return initialize {
|
||||||
|
delay = delay,
|
||||||
|
callback = callback,
|
||||||
|
update = updateIntermittent,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function Timer.every (interval, callback)
|
||||||
|
return initialize {
|
||||||
|
interval = interval,
|
||||||
|
callback = callback,
|
||||||
|
update = updateIntermittent,
|
||||||
|
limit = limit,
|
||||||
|
finish = finish,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function Timer.prior (cutoff, callback)
|
||||||
|
return initialize {
|
||||||
|
cutoff = cutoff,
|
||||||
|
callback = callback,
|
||||||
|
update = updateContinuous,
|
||||||
|
finish = finish,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function Timer.tween (duration, definition)
|
||||||
|
return initialize {
|
||||||
|
duration = duration,
|
||||||
|
plan = planTween(definition),
|
||||||
|
update = updateTween,
|
||||||
|
easeField = easeLinear,
|
||||||
|
ease = ease,
|
||||||
|
finish = finish,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function Timer.update (dt, group)
|
||||||
|
if not group then
|
||||||
|
group = defaultGroup
|
||||||
|
end
|
||||||
|
for index = #group, 1, -1 do
|
||||||
|
group[index]:update(dt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Timer.clear (group)
|
||||||
|
if not group then
|
||||||
|
group = defaultGroup
|
||||||
|
end
|
||||||
|
for i = 1, #group do
|
||||||
|
group[i] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Timer.defaultGroup = defaultGroup
|
||||||
|
|
||||||
|
return Timer
|
||||||
8
main.lua
8
main.lua
@@ -59,6 +59,7 @@ function love.load()
|
|||||||
input:bind(love.keyboard.getKeyFromScancode('d'), 'moveRight')
|
input:bind(love.keyboard.getKeyFromScancode('d'), 'moveRight')
|
||||||
input:bind(love.keyboard.getKeyFromScancode('s'), 'moveDown')
|
input:bind(love.keyboard.getKeyFromScancode('s'), 'moveDown')
|
||||||
input:bind(love.keyboard.getKeyFromScancode('space'), 'switch')
|
input:bind(love.keyboard.getKeyFromScancode('space'), 'switch')
|
||||||
|
input:bind(love.keyboard.getKeyFromScancode('lshift'), 'detach')
|
||||||
|
|
||||||
crates:init(world, magnet)
|
crates:init(world, magnet)
|
||||||
crates:spawn(120, 400)
|
crates:spawn(120, 400)
|
||||||
@@ -91,6 +92,13 @@ function love.update(dt)
|
|||||||
else
|
else
|
||||||
magnet.side = 'LEFT'
|
magnet.side = 'LEFT'
|
||||||
end
|
end
|
||||||
|
elseif input:pressed('detach') then
|
||||||
|
velocity = {0, 0}
|
||||||
|
|
||||||
|
local attached = crates:getAttached()
|
||||||
|
for key in pairs(attached) do
|
||||||
|
crates:detach(key)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if input:down('moveUp') or input:down('moveLeft') or input:down('moveRight') or input:down('moveDown') then
|
if input:down('moveUp') or input:down('moveLeft') or input:down('moveRight') or input:down('moveDown') then
|
||||||
if input:down('moveUp') then velocity[2] = -player.maxSpeed.y
|
if input:down('moveUp') then velocity[2] = -player.maxSpeed.y
|
||||||
|
|||||||
Reference in New Issue
Block a user