Ideally I would create a closed path using curves in a vector program, and then somehow use this path to script a sprite to move. Is this the way to do this, any libraries, etc that can read in a vector file?
May need to give us more info, but a starting point might be the DefTimeLine library (Def Timeline) – it lets you define a path with a simple sequence of t.add(...)
calls:
local t = timeline.new()
t.add(".", "position.x", nil, 150, nil, 2, nil,'label_1')
t.add(".", "position.y", nil, 150, nil, 2, nil, 'label_1')
t.add(".", "position.y", nil, 0, nil, nil, 2)
t.play()
I also hacked together a bezier curve animation (GitHub - jbp4444/bzAnim: A Lua/Defold-based animation library for bezier curve animations) which can accept sequences of animations – but it is not as polished as DefTimeline.
1 Like
I ended up making my own spline library
-- Put functions in this file to use them in several other scripts.
-- To get access to the functions, you need to put:
-- require "my_directory.my_file"
-- in any script using the functions.
local M = {}
function M.get_point(t, control_points)
local num_control_points = #control_points
local index = math.floor(t * (num_control_points - 1)) + 1
local local_t = t * (num_control_points - 1) - index + 1
local p0 = control_points[(index - 2) % num_control_points + 1]
local p1 = control_points[(index - 1) % num_control_points + 1]
local p2 = control_points[index % num_control_points + 1]
local p3 = control_points[(index + 1) % num_control_points + 1]
return catmull_rom(p0, p1, p2, p3, local_t)
end
function catmull_rom(p0, p1, p2, p3, t)
local t2 = t * t
local t3 = t2 * t
local m0 = (p2 - p0) / 2
local m1 = (p3 - p1) / 2
local a = 2 * t3 - 3 * t2 + 1
local b = t3 - 2 * t2 + t
local c = t3 - t2
local d = -2 * t3 + 3 * t2
return a * p1 + b * m0 + c * m1 + d * p2
end
function M.draw_spline(control_points, screen_x, screen_y)
local scale = vmath.vector3(screen_x, screen_y, 1)
print(scale)
for t = 0, 1, .01 do
local point = M.get_point(t, control_points)
point.x = point.x * scale.x
point.y = point.y * scale.y
local next_t = t + .01
if next_t <= 1 then
local next_point = M.get_point(next_t, control_points)
next_point.x = next_point.x * scale.x
next_point.y = next_point.y * scale.y
msg.post("@render:", "draw_line",
{ start_point = point, end_point = next_point, color = vmath.vector4(1, 0, 0, 1) })
end
end
-- Draw straight lines between control points
for i = 1, #control_points - 1 do
local start_point = control_points[i]
local end_point = control_points[i + 1]
msg.post("@render:", "draw_line",
{ start_point = start_point, end_point = end_point, color = vmath.vector4(0, 1, 0, 1) })
end
end
return M
2 Likes