your-own-drum/marble.lua

122 lines
3.3 KiB
Lua
Raw Normal View History

2023-01-13 20:05:19 +00:00
--Character controller. Renders point particle.
local love = love
2023-01-13 21:34:01 +00:00
local oldBuffer = love.graphics.newCanvas()
local newBuffer = love.graphics.newCanvas()
local oldState, curState, newState
local FRICTION = 0.01
local MAXSPEED = 5.0
local ddx, ddy = 0.0, 0.0
local function State( )
return { t = 0, x = 0, y = 0, dx = 0, dy = 0 }
end
2023-01-13 20:05:19 +00:00
local function Current() return curState end
local function Next() return newState end
local function Integrate( step )
newState.t = love.timer.getTime()
newState.dx = (1.0 - FRICTION) * curState.dx + FRICTION * ddx
newState.dy = (1.0 - FRICTION) * curState.dy + FRICTION * ddy
newState.x = curState.x + newState.dx * step * MAXSPEED
newState.y = curState.y + newState.dy * step * MAXSPEED
end
2023-01-13 20:05:19 +00:00
local function OnImpact( impact )
--Adjust current trajectory according to collision.
2023-01-14 14:54:32 +00:00
if not impact.dt then return end
return Integrate( impact.dt ) --Hmm! Maybe this should be a fixed step instead for stability's sake.
end
2023-01-13 20:05:19 +00:00
local function Update()
--Roll the log.
for k, v in pairs( oldState ) do
oldState[k] = curState[k]
curState[k] = newState[k]
end
end
2023-01-13 20:05:19 +00:00
local function OnKey()
ddx = (love.keyboard.isScancodeDown( "d" ) and 1.0 or 0.0) - (love.keyboard.isScancodeDown( "a" ) and 1.0 or 0.0)
ddy = (love.keyboard.isScancodeDown( "w" ) and 1.0 or 0.0) - (love.keyboard.isScancodeDown( "s" ) and 1.0 or 0.0)
2023-01-13 20:05:19 +00:00
local n = math.sqrt( ddx * ddx + ddy * ddy )
if n < 0.001 then return end
ddx, ddy = ddx / n, ddy / n
end
local function Draw()
--Extrapolate forward for slightly smoother rendering.
local dt = love.timer.getTime() - curState.t
Integrate( dt + 1 / 60.0 )
local xp, yp = transform:transformPoint( oldState.x, oldState.y )
local xc, yc = transform:transformPoint( curState.x, curState.y )
local xn, yn = transform:transformPoint( newState.x, newState.y )
2023-01-13 21:34:01 +00:00
love.graphics.setCanvas( newBuffer )
love.graphics.setColor( 1.0, 1.0, 1.0 , 0.99 ) -- White.
2023-01-13 21:34:01 +00:00
love.graphics.draw( oldBuffer ) --Time-dependent fade: overlay canvas over itself.
--Render latest segment in trail.
love.graphics.setColor( 245 / 255, 169 / 255, 184 / 255, 1.0 ) --Trans pink.
--love.graphics.line( xi, yi, xf, yf )
--Segment stuff:
love.graphics.setLineJoin( "bevel" )
love.graphics.setLineStyle( "smooth" )
love.graphics.setLineWidth( 8.0 )
love.graphics.line( xp, yp, xc, yc, xn, yn)
love.graphics.circle( "fill", xn, yn, 4.0 )
2023-01-13 21:34:01 +00:00
love.graphics.setCanvas( oldBuffer )
love.graphics.clear( 1.0, 1.0, 1.0, 0.0 )
--Render circle directly to screen.
love.graphics.setCanvas()
love.graphics.draw( newBuffer )
love.graphics.setColor( 1, 1, 1, 1.0 ) --White.
2023-01-14 14:54:32 +00:00
love.graphics.setLineWidth( 1.0 )
love.graphics.circle( "line", xn, yn, 4 )
2023-01-13 21:34:01 +00:00
oldBuffer, newBuffer = newBuffer, oldBuffer
2023-01-13 20:05:19 +00:00
end
local function Impact( impact )
end
2023-01-13 21:34:01 +00:00
--Window resize.
local function Resize()
newBuffer = love.graphics.newCanvas()
--TODO: render oldBuffer to new newBuffer, but scaled down.
oldBuffer = love.graphics.newCanvas()
2023-01-13 21:34:01 +00:00
2023-01-13 21:34:01 +00:00
end
local function Reset()
oldState, curState, newState = State(), State(), State()
Resize()
2023-01-13 20:05:19 +00:00
end
2023-01-13 21:34:01 +00:00
2023-01-13 20:05:19 +00:00
Reset()
return {
Integrate = Integrate,
OnImpact = OnImpact,
2023-01-13 20:05:19 +00:00
Update = Update,
OnKey = OnKey,
Draw = Draw,
Impact = Impact,
Reset = Reset,
Resize = Resize,
Current = Current,
Next = Next,
2023-01-13 20:05:19 +00:00
}