If I wanted to have objects spawn on the outside of a circle and have them move toward the center, how would I go about doing that?
(Tip [not a snub]: Bookmark this page: https://docs.coronalabs.com/daily/api/ ; I’m linking to key references below, but they all came from here or the plugins link at the top. I use this page constantly, but find some users don’t know it exists.)
-
Determine radius of NO-SPAWN circle. (i.e.; Don’t spawn inside this area).
-
Select a random angle. with math.random(0,360)
-
Use math2d library function angle2Vector() to convert that angle into a vector.
-
Scale that vector by the radius + an offset using the math2d scale() function.
-
Add the x and y components of the vector from step 4 to the < x, y > position of the circle.
-
Create your spawned object at the new position specified by the <x, y> from step 5.
No Physics
- Use transition.to() and move the spawned object to the <x, y> position of the circle with some time you choose.
With Physics
-
Add a body to the spawned object with addBody().
-
Scale the vector from step #3 by -X (where X is the number of pixels per second speed you want; be sure you use a negative value to point in the opposite direction). This will produce a new vector < vx, vy >
-
Call obj:setLinearVelocity( vx, vy ) on the spawned object.
Spawn anywhere around the circle? Or just on one point?
okay thank you, very helpful. Is it possible to make the spawned objects move toward the center in a sin wave like path instead of just a straight line?
randomly around the circle
This is pretty easy to do. I would help but my set up is not up. If no one helps I’ll be back.
I’d greatly appreciate your help. Get back to me when you are available, thanks!
Yes, although you need to use a custom local coordinate system rather than the x- and y-axes with (0, 0) as the origin.
Your new origin would be wherever the circle starts.
The “x-axis” would be the vector from there to the center: (center.x - start.x, center.y - start.y). To avoid some ambiguity, call this “forward”.
You’ll probably want one step forward to cover the same distance as, say, one step to the right, rather than all the way to the center. From roaminggamer’s library, then, you would do:
local to\_center = math2d.sub(center, start) -- two points with x and y local distance = math2d.length(to\_center) -- save this for later local forward = math2d.normalize(to\_center)
You’ll also want a y-axis, so you can use another function (not documented, but available last I checked):
local up = math2d.normals(forward)
Despite the similar names, these are different things. “Normalize” means to reduce the length to 1, whereas “normal” (which name I believe comes from a drafting tool) refers to a perpendicular vector.
To find a point along the wave, then, do the following:
local function GetPoint (t) -- t goes from 0 to distance local x = math2d.scale(forward, t) -- Distance along "x-axis" local forward\_pos = math2d.add(start, x) -- Displace from "origin" local height = math.sin(t) -- scale the sin for more pronounced wave local y = math2d.scale(up, height) -- Distance along "y-axis" return math2d.add(forward\_pos, y) -- Final displacement end
and then update t from 0 to distance in your enterFrame handler or a timer, calling GetPoint() at each iteration.
None of the code is tested, but it should convey the general idea.
(Tip [not a snub]: Bookmark this page: https://docs.coronalabs.com/daily/api/ ; I’m linking to key references below, but they all came from here or the plugins link at the top. I use this page constantly, but find some users don’t know it exists.)
-
Determine radius of NO-SPAWN circle. (i.e.; Don’t spawn inside this area).
-
Select a random angle. with math.random(0,360)
-
Use math2d library function angle2Vector() to convert that angle into a vector.
-
Scale that vector by the radius + an offset using the math2d scale() function.
-
Add the x and y components of the vector from step 4 to the < x, y > position of the circle.
-
Create your spawned object at the new position specified by the <x, y> from step 5.
No Physics
- Use transition.to() and move the spawned object to the <x, y> position of the circle with some time you choose.
With Physics
-
Add a body to the spawned object with addBody().
-
Scale the vector from step #3 by -X (where X is the number of pixels per second speed you want; be sure you use a negative value to point in the opposite direction). This will produce a new vector < vx, vy >
-
Call obj:setLinearVelocity( vx, vy ) on the spawned object.
Spawn anywhere around the circle? Or just on one point?
okay thank you, very helpful. Is it possible to make the spawned objects move toward the center in a sin wave like path instead of just a straight line?
randomly around the circle
This is pretty easy to do. I would help but my set up is not up. If no one helps I’ll be back.
I’d greatly appreciate your help. Get back to me when you are available, thanks!
Yes, although you need to use a custom local coordinate system rather than the x- and y-axes with (0, 0) as the origin.
Your new origin would be wherever the circle starts.
The “x-axis” would be the vector from there to the center: (center.x - start.x, center.y - start.y). To avoid some ambiguity, call this “forward”.
You’ll probably want one step forward to cover the same distance as, say, one step to the right, rather than all the way to the center. From roaminggamer’s library, then, you would do:
local to\_center = math2d.sub(center, start) -- two points with x and y local distance = math2d.length(to\_center) -- save this for later local forward = math2d.normalize(to\_center)
You’ll also want a y-axis, so you can use another function (not documented, but available last I checked):
local up = math2d.normals(forward)
Despite the similar names, these are different things. “Normalize” means to reduce the length to 1, whereas “normal” (which name I believe comes from a drafting tool) refers to a perpendicular vector.
To find a point along the wave, then, do the following:
local function GetPoint (t) -- t goes from 0 to distance local x = math2d.scale(forward, t) -- Distance along "x-axis" local forward\_pos = math2d.add(start, x) -- Displace from "origin" local height = math.sin(t) -- scale the sin for more pronounced wave local y = math2d.scale(up, height) -- Distance along "y-axis" return math2d.add(forward\_pos, y) -- Final displacement end
and then update t from 0 to distance in your enterFrame handler or a timer, calling GetPoint() at each iteration.
None of the code is tested, but it should convey the general idea.