If you want to play around, I've made a very, very simple and rough demo /s:
Feel free to check out the source code if you need more info or want to "borrow" some code, I worked pretty hard on making this "tech demo" as unnecessarily pretty as possible (credits appreciated but not required. Same for the library itself). I will warn, however, that my code is probably a mess, so if anyone wants some clarification or better in-code commenting, feel free to let me know
Here's the "library" itself:
Code: Select all
function newAnimation(...)
local args = {...}
local self = {}
local function errHand(t)
if #t < 4 then
error("Too few points to create animation")
elseif math.mod(#t, 2) ~= 0 then
error("Odd number of coordinates, a pair of numbers for each point is required")
else
for i, v in ipairs(t) do
if type(v) ~= "number" then
error("Bad argument #" .. i .. " to 'newAnimation' (number expected, got " .. type(v) .. ")")
end
end
end
end
if type(args[1]) == "table" then
errHand(args[1])
self.path = {unpack(args[1])}
else
errHand(args)
self.path = {unpack(args)}
end
function self.point(pos, n)
return self.path[(pos+1)*2 - (4-n)]
end
function self.distance(x1, y1, x2, y2)
return math.sqrt((x1-x2)^2 + (y1-y2)^2)
end
self.dists = {}
for i = 3, #self.path-1, 2 do
table.insert(self.dists, self.distance(self.path[i-2], self.path[i-1], self.path[i], self.path[i+1]))
end
self.sum = 0
self.dsums = {}
for i, v in ipairs(self.dists) do
self.sum = self.sum + v
table.insert(self.dsums, self.sum)
end
function self.getPoint(n)
return self.path[(n-1)*2+1], self.path[(n-1)*2+2]
end
function self.getPos(f)
if type(f) ~= "number" then
error("Bad argument #1 to 'getPos' (number expected, got " .. type(f) .. ")")
end
if self.sum == 0 then
--NO DIVIDING BY 0! My computer doesn't like that for *some* reason...
return self.path[1], self.path[2]
end
local f = math.max(0, math.min(1, f))
local pos = 1
while pos < #self.dsums and f*self.sum > self.dsums[pos] do
pos = pos + 1
end
local st = 0
if pos > 1 then
st = self.dsums[pos-1]
end
local nf = f - (st/self.sum)
nf = nf / (self.dists[pos]/self.sum)
local px = self.point(pos, 1) + ( self.point(pos, 3) - self.point(pos, 1) )*nf
local py = self.point(pos, 2) + ( self.point(pos, 4) - self.point(pos, 2) )*nf
return px, py
end
return self
end
Basically, you create an animation path at your load function:
Code: Select all
function love.load()
myAnim = newAnimation(50, 50, 150, 150, 300, 100, 150, 50, 50, 50)
end
newAnimation({x1, y1, x2, y2, x3, y3...})
(It supports both raw arguments or a single table)
Later on, you can retrieve coordinates from the path based on a given time position. This is given via the myAnim.getPos(n), where n is a number between 0 and 1. You may set an independent timer and get the position based on it:
Code: Select all
function love.load()
myAnim = newAnimation(50, 50, 150, 150, 300, 100, 150, 50, 50, 50)
myTimer = {0, 3}
end
function love.update(dt)
myTimer[1] = math.mod(myTimer[1] + dt, myTimer[2])
end
function love.draw()
local factor = myTimer[1]/myTimer[2]
local x, y = myAnim.getPos(factor)
love.graphics.circle("fill", x, y, 5, 16)
end
Code: Select all
function love.load()
myAnim = newAnimation(50, 50, 150, 150, 300, 100, 150, 50, 50, 50)
--code to change animation path
myAnim = newAnimation(50, 50, 50, 200, 300, 100, 150, 50, 50, 50)
end
[/size][/b]
Demo changelog:
Code: Select all
version 1.1
- Ctrl+Z and Ctrl+Y for undoing/redoing changes to the path;
- Increased the maximum number of coordinates to 50;
- Fixed a bug with removing the starting point from a looped path;
- Right-clicking a point on a looped path sets it to the new origin point;
- Quitting the demo now saves how you left it, so when you re-open it, it's just like you left it;
- Added a "Clear data" button to reset the demo from the previously-mentioned saved data;
- Added a small notification system.
version 1.0
- Released