Drag an object along a specific path

Hey, I’m not sure if this is what you’re looking for now, because I’ve not read the whole conversation thread, but based on the thread title does this help? You’ll need the mathlib from here:

https://developer.coronalabs.com/code/maths-library

Tap on the screen to create points along a line. Touch and drag around the screen to have the closest point on the line highlighted.

If this is what you’re looking for but you want it with physics, let me know and I’ll make the appropriate adjustements.

main.lua:
[lua]
– move along path

require(“mathlib”)

– physics not doing anything yet
require(“physics”)
physics.start()
physics.setGravity(0,10)
physics.setDrawMode(“hybrid”)

sWidth, sHeight = display.contentWidth, display.contentHeight

gravity = {x=0,y=10}

dots = display.newGroup()
lines = display.newGroup()
tracker = display.newGroup()
tracker.line = display.newGroup()
tracker.dot = display.newCircle(tracker,0,0,10)

function tap(e)
local dot = display.newCircle(dots,e.x,e.y,15)
dot:setFillColor(0,0,0,0)
dot:setStrokeColor(0,255,0)
dot.strokeWidth = 5

while (lines.numChildren > 0) do
lines[1]:removeSelf()
end

if (dots.numChildren > 1) then
for i=2, dots.numChildren do
local line = display.newLine(lines,dots[i-1].x,dots[i-1].y,dots[i].x,dots[i].y)
line.width = 5
line:setColor(0,0,255)
end
end
return true
end
Runtime:addEventListener(“tap”,tap)

function findClosestPoint(e)
local closestDist = 1000000
local closestPt = nil

for i=2, dots.numChildren do
local pt = GetClosestPoint( dots[i-1], dots[i], e )
local len = lengthOf( pt, e )

if (len < closestDist) then
closestDist = len
closestPt = pt
end
end

return closestPt
end

function refreshTrack(e)
local pt = findClosestPoint(e)
tracker.dot.x, tracker.dot.y = pt.x, pt.y

tracker.line:removeSelf()
tracker.line = display.newLine(tracker,e.x,e.y,pt.x,pt.y)
end
function touch(e)
if (e.phase == “began”) then
tracker.alpha = 1
refreshTrack(e)
elseif (e.phase == “moved”) then
refreshTrack(e)
else
tracker.alpha = 0
end
return true
end
Runtime:addEventListener(“touch”,touch)
[/lua] [import]uid: 8271 topic_id: 35544 reply_id: 145182[/import]

Any ideas, horacebury?
 

Thanks Caleb.
I’ll give it a try and let you know how it goes.

@horacebury - Thanks for your suggestion.
Say I want to plot a few points to form lines, first of which starts at x = 500, y = 200 and ends at
x = 800, y = 200 … a second line/set of points that start at x = 800, y = 200 and ends x = 800, y = 600
Using your example, how then would I define the path between the points as the only path my ball can move along?
Skip to 1:08 for example of what I’m trying to mimic: http://www.youtube.com/watch?v=5QLOllCbAIE
Thanks for all your help guys. :slight_smile:

-Saer [import]uid: 148623 topic_id: 35544 reply_id: 145351[/import]

See if this helps:

main.lua:
[lua]
– move along path

require(“mathlib”)

require(“physics”)
physics.start()
physics.setGravity(0,0)
physics.setDrawMode(“hybrid”)

sWidth, sHeight = display.contentWidth, display.contentHeight

gravity = {x=0,y=10}

playerRadius = 10
joinThreshold = playerRadius

dots = display.newGroup()
lines = display.newGroup()
tracker = display.newGroup()
tracker.line = display.newGroup()
tracker.dot = display.newCircle(tracker,0,0,playerRadius)

physics.addBody(tracker.dot)
tracker.dot.linearDamping = 20
tracker.dot.lineIndex = 1

joint = physics.newJoint(“touch”,tracker.dot,tracker.dot.x,tracker.dot.y)

dot = tracker.dot

function findClosestLines()
local index, start, last = dot.lineIndex, dot.lineIndex, dot.lineIndex+1

if (index > 1 and lengthOf(dot,dots[index]) < joinThreshold) then
dot.lineIndex = dot.lineIndex - 1
return dot.lineIndex, last
end

if (index < dots.numChildren-1 and lengthOf( dot, dots[last] ) < joinThreshold) then
dot.lineIndex = dot.lineIndex + 1
return dot.lineIndex, dot.lineIndex + 1
end

return start, last
end

function findClosestPoint(e, start, last)
local start, last = findClosestLines()
local closestDist = 1000000
local closestPt = nil

if (start == last) then
return dots[start] – location of only dot
end

– find the line that the dot is on
for i=start, last-1 do
local pt = GetClosestPoint( dots[i], dots[i+1], e )
local len = lengthOf( pt, e )

if (len < closestDist) then
closestDist = len
closestPt = pt
end
end

return closestPt
end

function refreshTrack(e)
local pt = findClosestPoint(e)
joint:setTarget(pt.x,pt.y)

if (tracker.line) then tracker.line:removeSelf(); tracker.line = nil end
tracker.line = display.newLine(tracker,e.x,e.y,pt.x,pt.y)
end

function touch(e)
if (e.phase == “began”) then
refreshTrack(e)
elseif (e.phase == “moved”) then
refreshTrack(e)
else
if (tracker.line) then tracker.line:removeSelf() end
tracker.line = nil
end
return true
end

function tap(e)
local dot = display.newCircle(dots,e.x,e.y,15)
dot:setFillColor(0,0,0,0)
dot:setStrokeColor(0,255,0)
dot.strokeWidth = 5

while (lines.numChildren > 0) do
lines[1]:removeSelf()
end

if (dots.numChildren > 1) then
for i=2, dots.numChildren do
local line = display.newLine(lines,dots[i-1].x,dots[i-1].y,dots[i].x,dots[i].y)
line.width = 5
line:setColor(0,0,255)
end
end

if (dots.numChildren == 1) then
tracker.dot.x, tracker.dot.y = e.x,e.y
joint:setTarget(e.x,e.y)
elseif (dots.numChildren > 1) then
Runtime:addEventListener(“touch”,touch)
end

return true
end
Runtime:addEventListener(“tap”,tap)
[/lua] [import]uid: 8271 topic_id: 35544 reply_id: 145383[/import]

I tried your code in a new project, and got an error in the [lua] function findClosestLines() [/lua] line #45 - [lua] if (index < dots.numChildren-1 and lengthOf( dot, dots[last] ) < joinThreshold) then [/lua] lua:84>
?: in function
2013-03-08 12:38:41.085 Corona Simulator[4880:f03] Runtime error
…Desktop/Application Projects/LineFollowTest/main.lua:45: attempt to call global ‘lengthOf’ (a nil value)
stack traceback:
[C]: in function ‘lengthOf’
…Desktop/Application Projects/LineFollowTest/main.lua:45: in function ‘findClosestLines’
…Desktop/Application Projects/LineFollowTest/main.lua:54: in function ‘findClosestPoint’
…Desktop/Application Projects/LineFollowTest/main.lua:77: in function ‘refreshTrack’
…Desktop/Application Projects/LineFollowTest/main.lua:88: in function <…desktop projects></…desktop>

  • EDIT - I fixed it. I must have had an older version of the mathlib, because I copied&pasted the code from the link you posted above and it works fine now.

I’ll let you know if it will work for me.
Thanks again! -Saer [import]uid: 148623 topic_id: 35544 reply_id: 145443[/import]

Well after playing around with your code, it’s looking very promising! : D
Thank you!

Couple questions -

  1. How would I create&save a table of points defined by specific x,y coordinates?
    I am creating multiple levels, so I was thinking it would be nice to have some code that I could just plug-in to each .lua file and all I would have to do is change the x,y coordinates to match that level’s specific path.

  2. How would I mimic the rotating platform mechanics?
    I have a circular platform which rotates via touch, but I can’t figure out how to define the paths within the circle - again, similar to what is shown in the video.
    Would I add physics to the platform and then create physics holes where my path is?

EDIT - I shouldn’t say “similar to” because that maze in the video is exactly what I’m trying to replicate. :wink:

-Saer [import]uid: 148623 topic_id: 35544 reply_id: 145445[/import]

Any ideas, horacebury?