Arrow Rotation Towards Moving Object

Hello, Ive been trying to create a game where a lot is happening at once and there’s an exclamation mark that indicates where needs to be tapped.

What im wanting to happen is that the arrow (“pointer” in code) rotates properly around the exclamation not just kind of work and then randomly keep rotating. Ive included both images im using and a link to a gif I made to help show what the issue im having is. Also the more I move the arrow (“pointer” in code) the more it rotates, so it pretty much just spins

Gif Link : http://imgur.com/0XohFmV

Any help would be much appreated

Many Thanks

pointer = display.newImage("arrow.png") -- Might had fixed it pointer.x = centerX pointer.y = 40 pointer.anchorY = 0.5 -- Anchor point idk if working --------------- pointer.anchorX = 0.5 --[print (exclamationMark.x) pointer.rotation = exclamationMark.y pointer.rotation = exclamationMark.x transition.to(pointer, {rotation=rotateValue, time = 250, transition.inOutCubic}) --]] --[[if exclamationMark.x \> width/2 or height/2 then pointer.yScale = 1 else pointer.yScale = -1 end pointer.rotation = exclamationMark.x else pointer.rotation = exclamationMark.y----------------------- end --]]

So just to be clear, you are saying you want the arrow to always point at the exclamation mark?  

What you need to do is calculate the angle between the arrow and the exclamation mark, rather than setting the rotation to be the same as the XY of the exclamation mark.

Here is a simple sample that has an image and a circle. Drag the image around and it will always point towards the circle (just insert your own images into the newImageRect functions). The update function is where all of the rotation magic happens:

local pointer = display.newImageRect("assets/images/pointer.png", 128, 128) pointer.x, pointer.y = display.contentWidth \* 0.5, display.contentHeight \* 0.25 function pointer:touch(e) if e.phase == "began" then display.getCurrentStage():setFocus(e.target, e.id) elseif e.phase == "moved" then pointer.x, pointer.y = e.x, e.y elseif e.phase == "ended" then display.getCurrentStage():setFocus(nil) end return true end pointer:addEventListener( "touch", pointer ) local exclamationMark = display.newImageRect("assets/images/exclamationMark.png", 128, 128) exclamationMark.x, exclamationMark.y = display.contentWidth \* 0.5, display.contentHeight \* 0.5 local function update(e) --find the distance between the 2 objects local deltaX = pointer.x - exclamationMark.x local deltaY = pointer.y - exclamationMark.y --calculate the angle between them, and convert from radians to degrees pointer.rotation = math.deg(math.atan2(deltaY, deltaX)) print("rotation = ", pointer.rotation) --depending on the rotation of the image inside your image file you may need to offset the calculated rotation like the commented line below --pointer.rotation = pointer.rotation + 90 end Runtime:addEventListener( "enterFrame", update )

Hello, thanks for the help although its not quite fully what I need. I will continue to edit it as well but I was hoping that the arrow would always point at the exclamation mark. I have included a link to a gif showing what im talking about

http://i.imgur.com/9kxspjE.gif

I want it to always act as if the arrow were to be right up against the exclamation mark. Pretty much what im saying is that the movement of the arrow should me very accurate and fast

I thank you for your help so far it has been much appreciated 

OK so it looks like the rotation is off by -90 degrees, which will be determined by the rotation of the arrow within the image file itself. If you take a look at the last part of my function I mention that this can be offset. Uncomment this line:

--pointer.rotation = pointer.rotation + 90

and change the + 90 to - 90

--pointer.rotation = pointer.rotation - 90 

That should have it almost perfectly pointing towards the exclamationMark.

However the rotation looks slightly off (if you’re using my code in that gif), am I right in guessing that the anchorY for the exclamationMark is set to 1 and not 0.5?

If so you’ll need to offset the deltaY by half of the object’s height, so that the arrow always points to the center of the exclamationMark and not the bottom of it (and do the same for X if the anchorX is 1). Try changing the deltaX and delta Y so that it now does this:

local centerX = exclamationMark.x - (exclamationMark.width \* 0.5) local centerY = exclamationMark.y - (exclamationMark.height \* 0.5) local deltaX = (pointer.x - ) - centerX local deltaY = pointer.y - centerY

I’ve tested both bits of code out and it always points towards the object as expected. 

With regards to the second part of your message:

I want it to always act as if the arrow were to be right up against the exclamation mark. Pretty much what im saying is that the movement of the arrow should me very accurate and fast

I’m not sure exactly what you mean. The rotation of the arrow is calculated every frame using my code, so your game can’t do it any faster than that. If you calculate the xy movement in the same function then that will happen every frame too, so will be as fast as possible.

Thank you sooo much for the help once I rotated it by -90 it worked fine. I would up vote your reply but sadly theres no option for that. As a thanks do you mind if I credit you in the credits of the game? if so is there a username I could you and is it fine for me to include your code if I intend to sell the app?

Yes of course you can use this code. It’s not “my code” so to speak, it’s just some basic trigonometry to work out the angles.  

I’m not a lawyer but as a general rule you can probably assume that if someone posts some code on the forums to help you, it’s ok to use in your app.

Just FYI, there should be a button that says something like “mark resolved” on my posts, so that in future people who have the same problem can see the answer that was given (I’d suggest clicking it on my first post rather than second, since that actually had the rotation offset in it too).

That’s kind of you to offer to put my name in the credits, I certainly wasn’t expecting that. I’m happy to have “Alan QuizTix” in there (I’ll be listed as Managing Director I assume  :stuck_out_tongue: )

So just to be clear, you are saying you want the arrow to always point at the exclamation mark?  

What you need to do is calculate the angle between the arrow and the exclamation mark, rather than setting the rotation to be the same as the XY of the exclamation mark.

Here is a simple sample that has an image and a circle. Drag the image around and it will always point towards the circle (just insert your own images into the newImageRect functions). The update function is where all of the rotation magic happens:

local pointer = display.newImageRect("assets/images/pointer.png", 128, 128) pointer.x, pointer.y = display.contentWidth \* 0.5, display.contentHeight \* 0.25 function pointer:touch(e) if e.phase == "began" then display.getCurrentStage():setFocus(e.target, e.id) elseif e.phase == "moved" then pointer.x, pointer.y = e.x, e.y elseif e.phase == "ended" then display.getCurrentStage():setFocus(nil) end return true end pointer:addEventListener( "touch", pointer ) local exclamationMark = display.newImageRect("assets/images/exclamationMark.png", 128, 128) exclamationMark.x, exclamationMark.y = display.contentWidth \* 0.5, display.contentHeight \* 0.5 local function update(e) --find the distance between the 2 objects local deltaX = pointer.x - exclamationMark.x local deltaY = pointer.y - exclamationMark.y --calculate the angle between them, and convert from radians to degrees pointer.rotation = math.deg(math.atan2(deltaY, deltaX)) print("rotation = ", pointer.rotation) --depending on the rotation of the image inside your image file you may need to offset the calculated rotation like the commented line below --pointer.rotation = pointer.rotation + 90 end Runtime:addEventListener( "enterFrame", update )

Hello, thanks for the help although its not quite fully what I need. I will continue to edit it as well but I was hoping that the arrow would always point at the exclamation mark. I have included a link to a gif showing what im talking about

http://i.imgur.com/9kxspjE.gif

I want it to always act as if the arrow were to be right up against the exclamation mark. Pretty much what im saying is that the movement of the arrow should me very accurate and fast

I thank you for your help so far it has been much appreciated 

OK so it looks like the rotation is off by -90 degrees, which will be determined by the rotation of the arrow within the image file itself. If you take a look at the last part of my function I mention that this can be offset. Uncomment this line:

--pointer.rotation = pointer.rotation + 90

and change the + 90 to - 90

--pointer.rotation = pointer.rotation - 90 

That should have it almost perfectly pointing towards the exclamationMark.

However the rotation looks slightly off (if you’re using my code in that gif), am I right in guessing that the anchorY for the exclamationMark is set to 1 and not 0.5?

If so you’ll need to offset the deltaY by half of the object’s height, so that the arrow always points to the center of the exclamationMark and not the bottom of it (and do the same for X if the anchorX is 1). Try changing the deltaX and delta Y so that it now does this:

local centerX = exclamationMark.x - (exclamationMark.width \* 0.5) local centerY = exclamationMark.y - (exclamationMark.height \* 0.5) local deltaX = (pointer.x - ) - centerX local deltaY = pointer.y - centerY

I’ve tested both bits of code out and it always points towards the object as expected. 

With regards to the second part of your message:

I want it to always act as if the arrow were to be right up against the exclamation mark. Pretty much what im saying is that the movement of the arrow should me very accurate and fast

I’m not sure exactly what you mean. The rotation of the arrow is calculated every frame using my code, so your game can’t do it any faster than that. If you calculate the xy movement in the same function then that will happen every frame too, so will be as fast as possible.

Thank you sooo much for the help once I rotated it by -90 it worked fine. I would up vote your reply but sadly theres no option for that. As a thanks do you mind if I credit you in the credits of the game? if so is there a username I could you and is it fine for me to include your code if I intend to sell the app?

Yes of course you can use this code. It’s not “my code” so to speak, it’s just some basic trigonometry to work out the angles.  

I’m not a lawyer but as a general rule you can probably assume that if someone posts some code on the forums to help you, it’s ok to use in your app.

Just FYI, there should be a button that says something like “mark resolved” on my posts, so that in future people who have the same problem can see the answer that was given (I’d suggest clicking it on my first post rather than second, since that actually had the rotation offset in it too).

That’s kind of you to offer to put my name in the credits, I certainly wasn’t expecting that. I’m happy to have “Alan QuizTix” in there (I’ll be listed as Managing Director I assume  :stuck_out_tongue: )