Reading Gestures from the TouchPanel
Gestures provide a richer and higher level abstraction than the raw state data you can access by reading the TouchPanel
state. Gestures are performed by the user over time and require that
the system continuously process user input to determine whether an
enabled gesture has been performed. TouchPanel provides the capability to define which gestures should be tracked by using the EnabledGestures property and the GestureType enumeration flags. By default, the TouchPanel
has no gestures enabled because gesture processing requires additional
CPU processing. You should limit which gestures you enable to the
minimum you currently need to keep the processing cost to a minimum.
Table 5 contains the enumeration values for GamePadType.
Table 5. GestureType Enumeration
Name | Description |
---|
None | No gestures should be processed. |
Tap | A short touch at a single point on the screen. |
DoubleTap | Two repeated taps on the screen near a single point. |
Hold | One second touch at a single point on the screen. |
HorizontalDrag | A touch that moves horizontally across the screen without lifting the finger. |
VerticalDrag | A touch that moves vertically across the screen without lifting the finger. |
FreeDrag | A touch that moves across the screen without lifting the finger. |
Pinch | Two touch points that are pull closer or further away in a pinching motion. |
Flick | A touch that is quickly moved in a flicking motion across the screen. |
DragComplete | Used to signal when one of the drag gestures is completed. |
PinchComplete | Used to signal when the pinch gesture is completed. |
Enabling the gestures you want to respond to is a simple as combining multiple GestureType flags using the TouchPanel.EnabledGestures static property. The following lines of code enables two gestures:
TouchPanel.EnabledGestures = GestureType.Tap | GestureType.FreeDrag;
The gesture system
then continuously checks for the tap and free drag gestures while the
game runs. In our game’s input logic code, you then need to check to see
whether any gestures have been detected. This is done by calling the TouchPanel.IsGestureAvailable static property. This property returns true at least one gesture is ready to be processed. The TouchPanel.ReadGesture method is then used to read the next gesture in the queue and remove it from the queue.
The following code reads all of the available gestures from the TouchPanel.
// Loop while there are still gestures to read
while (TouchPanel.IsGestureAvailable)
{
// Read the next gesture
GestureSample gesture = TouchPanel.ReadGesture();
// Use a switch statement to detemine which type of gesture has been recieved
switch (gesture.GestureType)
{
case GestureType.Tap:
// Process tap gesture
break;
case GestureType.FreeDrag:
// Process free drag gesture
break;
}
}
After each GestureSample is read, the game can use the gesture input to take some type of action. A GestureSample
is a structure that holds all of the data relevant to a gesture. Using a
switch statement is helpful to determine which type of gesture is used
and to take different game actions based on the gesture.
Table 6 contains the properties exposed by the GestureSample structure.
Table 6. Properties of GestureSample
Property | Type | Description |
---|
GestureType | GestureType | The type of gesture that occurred |
Position | Vector2 | First touch location of the gesture |
Position2 | Vector2 | Second touch location of the gesture used in multiple point gestures like Pinch |
Delta | Vector2 | Delta information about the gesture such as the movement in a FreeDrag gesture |
Delta2 | Vector2 | Second delta information used in multiple point gestures |
Timestamp | Timespan | Span of time in which the gesture occurred |
Depending on the type of gesture, the different property values of the GestureSample can be used when taking action within your game. For example, if you use the Flick gesture in your game to scroll the map, you might care about only the Delta
property so you would know which direction the flick occurred in and
with how much velocity. In other situations, you might care about the
position of the gesture when using the DoubleTap gesture for selection. In that case, you would use the Position property.
Displaying GestureSample Data
Now that you have learned
how to enable and read gestures let’s create a simple application that
displays the last five gestures and all of their corresponding GestureSample properties.
First, you will need a List
to store all of the processed gestures in so you can print them later
when drawing. Add the following member variable to your game:
List<GestureSample> gestures = new List<GestureSample>();
Next, in your games Update method, add the following lines of code:
// Loop while there are still gestures to read
while (TouchPanel.IsGestureAvailable)
{
// Add each to the stack
gestures.Add(TouchPanel.ReadGesture());
}
This continuously reads all of the available gestures and adds them to the List for later processing.
Now in your games Draw method, add the following lines of code to loop over all of the gestures and write their values.
spriteBatch.Begin();
Vector2 textPosition = new Vector2(5, 5);
// Loop over all of the gestures and draw their information to the screen
for (int i = gestures.Count-1; i >= 0; i—)
{
// Draw all of the properties of the gesture
GestureSample gesture = gestures[i];
spriteBatch.DrawString(spriteFont, "GestureType: " +
gesture.GestureType.ToString(), textPosition,
Color.White);
textPosition.Y += 25;
spriteBatch.DrawString(spriteFont, "Position: " +
gesture.Position.ToString(), textPosition, Color.White);
textPosition.Y += 25;
spriteBatch.DrawString(spriteFont, "Position2: " +
gesture.Position2.ToString(), textPosition, Color.White);
textPosition.Y += 25;
spriteBatch.DrawString(spriteFont, "Delta: " +
gesture.Delta.ToString(), textPosition, Color.White);
textPosition.Y += 25;
spriteBatch.DrawString(spriteFont, "Delta2: " +
gesture.Delta2.ToString(), textPosition, Color.White);
textPosition.Y += 25;
spriteBatch.DrawString(spriteFont, "Timestamp: " +
gesture.Timestamp.ToString(), textPosition,
Color.White);
textPosition.Y += 40;
}
spriteBatch.End();
// Remove any gestures that wont print on the screen
if (gestures.Count > 5)
gestures.RemoveRange(0, gestures.Count - 5);
In the previous code, we loop over the List of GestureSample
structures in reverse order and write out each of the properties. We
then check the size of the list so that we can remove any gestures that
would not be displayed on the screen.
Running the sample shows results similar to those seen in Figure 1.