Drag an object along a specific path

I chose Tiled because a) it’s simpler to use, b) we don’t need it to be extremely complicated, and c) it can do things extremely exactly.

So to start with, build a Tiled map. The tileset doesn’t really matter. It could even just be two images - a wall and your character.

Then, in your code, do an iteration so that if the data is 1 build a wall at that position, if the data is 2 build the character at that position.

There’s a simple framework.

I’ll build some code if you want me to :slight_smile:

Caleb [import]uid: 147322 topic_id: 35544 reply_id: 142921[/import]

Ok, I see now.

You could start with making a number of shapes that are built in certain paths/trails (like a bit of the Tiled maze example that I posted) and add them into their own group; when you want to rotate them, rotate the group. Or even make physics bodies that accomodate the ball/cube/whatever that you’re trying to move and use them.

C [import]uid: 147322 topic_id: 35544 reply_id: 144158[/import]

I have the rotating platforms with an image of what I want to use for the ‘track’ which rotates accordingly when I rotate the circular platform… The only two things I don’t have “coded” yet, are getting the ball to rotate if it is on the circular platfrom (I’m getting close to working that out), and getting the ball to follow the track when dragged.

Using your Tiled example, would I just place my ‘track’ objects where I want them and then code invisible walls to keep the ball moving steadily along the ‘track’?

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

Quite right - you’d create as many “track” physics bodies as you need and add the track image to a group with that physics body attached to it.

When your player enters the track, add the player to that group and rotate the group.

At least I think that would work… You might get a problem with different-group physics.

C [import]uid: 147322 topic_id: 35544 reply_id: 144267[/import]

  • Sorry for the delayed response -

Okay, sounds good.
I haven’t used Tiled before, so your assistance would be more than welcome! :smiley:

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

So here’s an example I put together:

https://www.dropbox.com/s/a3mb52ihagdlfqp/TiledMapDemo.zip

Let me know if there’s something you don’t understand :slight_smile:

C [import]uid: 147322 topic_id: 35544 reply_id: 143636[/import]

  • [import]uid: 148623 topic_id: 35544 reply_id: 143644[/import]

You could also try level director (www.retrofitproductions.com/level-director) as this allows you to create a bezier path and exports the points for you.
I actually use the curves with physics but it does contain an example that has a ball follow the path so it might be of some help to you.
[import]uid: 158620 topic_id: 35544 reply_id: 145123[/import]

Ok, I see what you mean. (By the way… I love The Room :slight_smile: )

So do you have a physics shape for that circle path? That’s what you’re going to need - a physics shape that “closes in” all of the paths, just like my tiled example has. You might want to go for a smaller size physics path, though.

C [import]uid: 147322 topic_id: 35544 reply_id: 145164[/import]

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]

Ok, I see now.

You could start with making a number of shapes that are built in certain paths/trails (like a bit of the Tiled maze example that I posted) and add them into their own group; when you want to rotate them, rotate the group. Or even make physics bodies that accomodate the ball/cube/whatever that you’re trying to move and use them.

C [import]uid: 147322 topic_id: 35544 reply_id: 144158[/import]

I have the rotating platforms with an image of what I want to use for the ‘track’ which rotates accordingly when I rotate the circular platform… The only two things I don’t have “coded” yet, are getting the ball to rotate if it is on the circular platfrom (I’m getting close to working that out), and getting the ball to follow the track when dragged.

Using your Tiled example, would I just place my ‘track’ objects where I want them and then code invisible walls to keep the ball moving steadily along the ‘track’?

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

Quite right - you’d create as many “track” physics bodies as you need and add the track image to a group with that physics body attached to it.

When your player enters the track, add the player to that group and rotate the group.

At least I think that would work… You might get a problem with different-group physics.

C [import]uid: 147322 topic_id: 35544 reply_id: 144267[/import]

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]

  • [import]uid: 148623 topic_id: 35544 reply_id: 143644[/import]

You could also try level director (www.retrofitproductions.com/level-director) as this allows you to create a bezier path and exports the points for you.
I actually use the curves with physics but it does contain an example that has a ball follow the path so it might be of some help to you.
[import]uid: 158620 topic_id: 35544 reply_id: 145123[/import]

Ok, I see what you mean. (By the way… I love The Room :slight_smile: )

So do you have a physics shape for that circle path? That’s what you’re going to need - a physics shape that “closes in” all of the paths, just like my tiled example has. You might want to go for a smaller size physics path, though.

C [import]uid: 147322 topic_id: 35544 reply_id: 145164[/import]