Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
manual:touch_events [2013/05/26 17:13]
daniel
manual:touch_events [2014/02/05 09:54] (current)
daniel
Line 1: Line 1:
 +===== Touch events =====
  
 +One of the most revolutionary features of the iPhone is that it allows you to control it with your fingers. No physical buttons, not even a stylus is required -- and you can even use several fingers simultaneously. Sparrow makes it easy for you to react to touches of one or more fingers.
 +
 +First of all: if you want to support multitouch, you need to enable it at Sparrow'​s SPViewController. If you are using the scaffold project, you should do that in the Application Delegate class.
 +
 +<code objc>
 +_viewController.multitouchEnabled = YES;
 +</​code>​
 +
 +When that's settled, you can listen to touch events on any object in your game by listening for events with the type ''​SP_EVENT_TYPE_TOUCH'':​
 +
 +<code objc>
 +[self addEventListener:​@selector(onTouch:​) atObject:​self forType:​SP_EVENT_TYPE_TOUCH];​
 +</​code>​
 +
 +Again, we added the listener to '​self',​ without ever dispatching a touch event ourselves. That's a strong indication that touch events are bubbling events --- and indeed, that's the case. If you think about it, that makes perfect sense:
 +
 +Remember our message box. When the user clicks on the text field, obviously anybody listening to touches on the text field must be notified. But the same is true for somebody listening for touch events on the message box --- the textfield is part of the message box, so the latter was touched as well. And if somebody listens to touch events on the stage, he will also be notified. The message box is part of the stage, after all.
 +
 +Now, how to handle touch events? Have a look at this sample code.
 +
 +<code objc>
 +- (void)onTouch:​(SPTouchEvent*)event
 +{
 +    SPTouch *touch = [[event touchesWithTarget:​self andPhase:​SPTouchPhaseBegan] anyObject];
 +    if (touch)
 +    {
 +        SPPoint *touchPosition = [touch locationInSpace:​self];​
 +        NSLog(@"​Touched position (%f, %f)",
 +            touchPosition.x,​ touchPosition.y);​
 +    }
 +}
 +</​code>​
 +
 +That's the most basic case: Find out if somebody touched the screen, and log the coordinates (relative to the current display object). The method "​touchesWithTarget:​andPhase:"​ is provided by SPTouchEvent and helps you find the touches you are interested in.
 +
 +The target "​self"​ means: find any touches that occurred on me (self) OR my children. Think back to our message box: the target "​self"​ would include the message box and the text field.
 +
 +The touch phase is "​touchPhaseBegan",​ thus the position will be logged the moment the finger touched the screen, but not while the finger moves around or leaves the screen. Those are the available touch phases. Their names should be self explanatory.
 +
 +  * ''​SPTouchPhaseBegan''​
 +  * ''​SPTouchPhaseMoved''​
 +  * ''​SPTouchPhaseStationary''​
 +  * ''​SPTouchPhaseEnded''​
 +
 +The method "​touchesWithTarget:​andPhase:"​ returns an NSSet containing suitable touches, which are encapsulated in SPTouch objects. The method "​locationInSpace:"​ of SPTouch returns the touch coordinates in just the coordinate system you need.
 +
 +So much for single touches. Multiple touches are handled just the same. The only difference is that the set returned by "​touchesWithTarget:​andPhase"​ contains multiple SPTouch objects.
 +
 +<code objc>
 +NSArray *touches = [[event touchesWithTarget:​self andPhase:​SPTouchPhaseMoved] allObjects];​
 +
 +if (touches.count == 1)
 +{
 +    // one finger touching
 +    SPTouch *touch = [touches objectAtIndex:​0];​
 +    SPPoint *currentPos = [touch locationInSpace:​self];​
 +    SPPoint *previousPos = [touch previousLocationInSpace:​self];​
 +    // ...
 +}
 +else if (touches.count >= 2)
 +{
 +    // at least two fingers touching
 +    SPTouch *touch1 = [touches objectAtIndex:​0];​
 +    SPTouch *touch2 = [touches objectAtIndex:​1];​
 +    // ...
 +}
 +</​code>​
 +
 +Notice the method "​previousLocationInSpace:"​ of SPTouch. In this sample, we requested touches with the phase SPTouchPhaseMoved. "​previousLocationInSpace"​ will return the point the touch had in previous frame. This comes in handy when you want to drag an object around: just move the object along the vector between the current and the last touch position.
 +
 +The demo application contains the class "​TouchSheet",​ which is used in the "​Multitouch"​ demo scene. It shows you how to let the user drag objects around, rotate and scale them.
 +
 +-------
 +
 +//Next Section: [[Animation]]
  manual/touch_events.txt · Last modified: 2014/02/05 09:54 by daniel
 
Powered by DokuWiki