Share Your Code

Rotate object with finger

Posted by ChunkyApps, Posted on July 14, 2011

I have been trying to figure out how to rotate an object with my finger by moving it in clockwise or counter-clockwise position. After much Math searching and confusion, I think I got it. Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
local function rotateObj(event)
        local t = event.target
        local phase = event.phase
        
        if (phase == "began") then
                display.getCurrentStage():setFocus( t )
                t.isFocus = true
                
                -- Store initial position of finger
                t.x1 = event.x
                t.y1 = event.y
                
        elseif t.isFocus then
                if (phase == "moved") then
                        t.x2 = event.x
                        t.y2 = event.y
                        
                        angle1 = 180/math.pi * math.atan2(t.y1 - t.y , t.x1 - t.x)
                        angle2 = 180/math.pi * math.atan2(t.y2 - t.y , t.x2 - t.x)
                        print("angle1 = "..angle1)
                        rotationAmt = angle1 - angle2
 
                        --rotate it
                        t.rotation = t.rotation - rotationAmt
                        print ("t.rotation = "..t.rotation)
                        
                        t.x1 = t.x2
                        t.y1 = t.y2
                        
                elseif (phase == "ended") then
                        
                        display.getCurrentStage():setFocus( nil )
                        t.isFocus = false
                end
        end
        
        -- Stop further propagation of touch event
        return true
end
yourObject:addEventListener("touch", rotateObj)


Replies

MarkHenryC
User offline. Last seen 1 year 5 weeks ago. Offline
Joined: 11 Nov 2009

Very handy. Thanks.

culutas
User offline. Last seen 44 weeks 3 days ago. Offline
Joined: 19 Mar 2011

Thank you, nice code.

However, I saw no reason for the "focus" thing and I removed all focus related lines, and I also removed the last "return true" line, and still it seems working as expected. Can you explain why you felt the need for focus lines and "return true"?

doubleslashdesign
User offline. Last seen 13 hours 59 min ago. Offline
Joined: 27 Nov 2010

thanks so much - very cool

mike4
User offline. Last seen 42 weeks 9 hours ago. Offline
Joined: 22 Feb 2010

I believe the setFocus allows you to drag your finger away from the object and still pass events to it.

The "return true" keeps the touch event from falling through the object you are touching to objects that are below it.

ChunkyApps
User offline. Last seen 4 days 21 hours ago. Offline
Joined: 19 Jan 2011

Y'know I just used it because I was looking at Ansca Docs while I did it.

I knew the "return true" stopped propagation of the event but I was actually unclear on the setFocus. Makes sense what you said mike4.

@culutas
When you removed it, can you still drag your finger away from the object or does it stop working when you do?

culutas
User offline. Last seen 44 weeks 3 days ago. Offline
Joined: 19 Mar 2011

@mike4
thanks for explanation, useful info.

@ChunkyApps
Now I checked it, and no it does not trigger the event if you move away your finger without focus.

nicholasclayg
User offline. Last seen 21 hours 40 min ago. Offline
Joined: 16 May 2011

This was very cool. I haven't figured out what to do with it, but I added it to my toolbox of codes that do what I want :)

I like this, it's fun to twirl things around lol.

ng

nicholasclayg
User offline. Last seen 21 hours 40 min ago. Offline
Joined: 16 May 2011

Ok, now the question would be how would I initiate a touch on the object and have it rotate 45 degrees?

Think bubble ball, you can touch objects and they rotate a fixed amount of degrees.

I'm off to go research this, if someone knows post. I'll post if I figure it out too :)

I like challenges.

ng

ne.hannah
User offline. Last seen 4 days 6 hours ago. Offline
Joined: 18 Jan 2011

you could just use the tap and increment it by 45 degrees each time, using multitouch you can drag an object with 1 finger and then put two fingers on to rotate it. That is what I have done and it seems to work best for being able to drag and control angles.

Dhennrich
User offline. Last seen 4 weeks 4 days ago. Offline
Joined: 20 Jan 2011

How can I move another object with your amazing code?

It's like... you use your code in objectA and rotate this just like your code do, and in the same time, you move the objectB up and down

how can I do that?

thanks

a.lepel
User offline. Last seen 5 hours 34 min ago. Offline
Joined: 28 Nov 2011

I just started reading about tan() and writing code like this when I found your posting.
I only adapted the code for turning the objects with a max speed of 4 degrees per frame in the desired direction (my objects should not turn too fast).

Thank you very much!
Best,
Andreas

stevecross
User offline. Last seen 24 weeks 2 days ago. Offline
Joined: 19 Oct 2010

Many thanks to Chunky for this great code snippet!

I also have a situation where the object should not rotate too quickly so I think Andreas has the answer I need but I am afraid I don't understand how it was done.

Any way you could post a code snippet that shows how you slow down the rotation as you described?

Thanks!

a.lepel
User offline. Last seen 5 hours 34 min ago. Offline
Joined: 28 Nov 2011

Hi Steve,

no problem, I just inserted a few lines that check for an angle of more than 4 degrees. Adapt the 4 degrees to your needs.

Best,
Andreas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
local function rotateObj(event)
        local t = event.target
        local phase = event.phase
 
        if (phase == "began") then
                display.getCurrentStage():setFocus( t )
                t.isFocus = true
 
                -- Store initial position of finger
                t.x1 = event.x
                t.y1 = event.y
 
        elseif t.isFocus then
                if (phase == "moved") then
                        t.x2 = event.x
                        t.y2 = event.y
 
                        angle1 = 180/math.pi * math.atan2(t.y1 - t.y , t.x1 - t.x)
                        angle2 = 180/math.pi * math.atan2(t.y2 - t.y , t.x2 - t.x)
                        
                        print("angle1 = "..angle1)
                        
                        rotationAmt = angle1 - angle2
 
                        if rotationAmt < -4 then
                                rotationAmt = -4
                        elseif rotationAmt > 4 then
                                rotationAmt = 4
                        end                        
 
                        --rotate it
                        t.rotation = t.rotation - rotationAmt
                        print ("t.rotation = "..t.rotation)
 
                        t.x1 = t.x2
                        t.y1 = t.y2
 
                elseif (phase == "ended") then
 
                        display.getCurrentStage():setFocus( nil )
                        t.isFocus = false
                end
        end
 
        -- Stop further propagation of touch event
        return true
end
yourObject:addEventListener("touch", rotateObj)

Wooderson
User offline. Last seen 17 weeks 4 days ago. Offline
Joined: 26 Dec 2012

Hi, I know this was posted awhile ago but i just came across it the other day and it is exactly what I was looking for. I am just wondering is anyone knows of, or could make a code just like this one. But instead of spinning, the object would slide up and down or left and right?

Dhennrich
User offline. Last seen 4 weeks 4 days ago. Offline
Joined: 20 Jan 2011

1
2
3
4
5
6
7
8
9
10
11
12
local obj
 
obj = display.newRect( 50, 50, 100, 100 )
 
local moveObj = function(e)
      if e.phase == "moved" then
           obj.x = e.x
           obj.y = e.y
     end
end
 
obj:addEventListener( "touch", moveObj )

something like that... now you just modify what you want.

for example to move only left or right just remove obj.y = e.y

Wooderson
User offline. Last seen 17 weeks 4 days ago. Offline
Joined: 26 Dec 2012

Thank you :)

Do you have a code to allow the movement even if the finger is off of the object, but still clicked?

Never mind, I figured it out. Thanks :)

b.tarun
User offline. Last seen 1 year 18 weeks ago. Offline
Joined: 6 Feb 2013

How would you still be able to rotate the object but instead of touching the object to activate the rotation you just touch the empty space on the screen and still rotate the object to that direction?

drnelson
User offline. Last seen 49 weeks 3 days ago. Offline
Joined: 25 Jan 2011

why not just do something like:

1
local rotation = 90 + math.deg(math.atan2(event.yStart - rotObj.y, event.xStart - rotObj.x))

Where rotObj is the object you want to rotate and the event.yStart and event.xStart is the touch starting coordinates (could use .x and .y as well)

The + 90 is to fix the quadrants. Is this not correct? Is there a problem with this approach? Just curious if my math is off as this works, is less code, and hopefully not problematic somewhere I'm not seeing it to be.