Skip to content

Commit c86e7ee

Browse files
Input and done (#56)
* Input and done
1 parent 8b63f25 commit c86e7ee

File tree

6 files changed

+421
-3
lines changed

6 files changed

+421
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
title: Detecting input from a GamePad
3+
description: The code in this topic describes how to detect input on a GamePad.
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
By using [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) a game can determine which buttons are being held down. A game often needs to detect when a user has pressed or released a button. For example, there is the case of an action title that requires users to press and release keys in rapid succession. The example uses a cached [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) object to determine if buttons were pressed or released in a given frame.
10+
11+
Unlike Keyboards however, multiple GamePads can be connected to a computer or console at the same time, so the [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) call requires an Index parameter for which controller is being polled. You also need to query the system the game is currently on for its [GamePad.MaximumGamePadCount](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_MaximumGamePadCount) to determine how many controllers are supported and how many need to be polled for each frame. Also unlike GamePads, GamePads can be disconnected (especially if the battery dies) at any time and most consoles require you to validate this to avoid player issues.
12+
13+
> [!NOTE]
14+
> It is also worth noting, that when maintaining the state of connected gamepads, most console vendors **REQUIRE** your game to mange GamePad disconnection states (because it was unplugged, lost power, etc), ensuring the user experience is managed when the user CANNOT play.
15+
16+
Depending on game design, there may be times when checking for a button press needs to occur more frequently, and other times it does not. It is possible in the case of very fast button presses that more than one key press could occur within one frame. In such a case, the last button press is returned. Writing code that checks as often as possible for button presses is the best way to handle this case.
17+
18+
## Types of GamePad input
19+
20+
Most GamePads include a variety of different input options, including (but not limited to)
21+
22+
- Thumbsticks - providing ranged motion in two axis.
23+
- Buttons (including buttons on the Thumbsticks) - Digital on/off buttons (similar to keyboard keys)
24+
- Triggers - providing ranged motion in a singular axis.
25+
- Touchpads - in some advanced controllers (such as the PlayStation Dual Shock controller) include a small touchpad.
26+
27+
Additionally, most controllers also support haptic feedback (vibration) in the controller, which is different depending on the controller being used and for which system.
28+
29+
> [!NOTE]
30+
> Joysticks also work the same as GamePads, but use their own [Joystick](xref:Microsoft.Xna.Framework.Input.Joystick) and [JoystickState](xref:Microsoft.Xna.Framework.Input.JoystickState) classes. Operationally however, they work the same as GamePads.
31+
32+
## Detecting input changes on a GamePad
33+
34+
1. Declare a [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) object to hold the last known GamePad state (in this example, the **oldState** object).
35+
36+
2. Assign this object a value in your constructor.
37+
38+
3. Call [GamePad.GetState](xref:Microsoft.Xna.Framework.Input.GamePad#Microsoft_Xna_Framework_Input_GamePad_GetState_System_Int32_) to retrieve the current GamePad state (in this example, the **newState** object).
39+
40+
4. Compare the values in your **newState** object to the values in the **oldState** object.
41+
42+
Buttons pressed in the **newState** object that were not pressed in the **oldState** object were pressed during this frame. Conversely, buttons pressed in the **oldState** object that are not pressed in the **newState** object were released during this frame.
43+
44+
> For Thumbsticks and Triggers, it is not necessary to compare to the previous value unless you also need to calculate the difference, e.g. Was the variable controller moved fast or slow. Reading just the current value is usually enough.
45+
46+
5. Update **oldState** object to the **newState** object before leaving **Update**.
47+
48+
```csharp
49+
using Microsoft.Xna.Framework;
50+
using Microsoft.Xna.Framework.Input;
51+
52+
namespace GamePadInput
53+
{
54+
public class Game1 : Microsoft.Xna.Framework.Game
55+
{
56+
GraphicsDeviceManager graphics;
57+
GamePadState oldState;
58+
59+
public Game1()
60+
{
61+
graphics = new GraphicsDeviceManager(this);
62+
}
63+
64+
protected override void Initialize()
65+
{
66+
base.Initialize();
67+
oldState = GamePad.GetState(PlayerIndex.One);
68+
}
69+
70+
protected override void Update(GameTime gameTime)
71+
{
72+
// Allows the game to exit
73+
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
74+
{
75+
this.Exit();
76+
}
77+
78+
UpdateInput();
79+
80+
base.Update(gameTime);
81+
}
82+
83+
private void UpdateInput()
84+
{
85+
GamePadState newState = GamePad.GetState(PlayerIndex.One);
86+
87+
// Is the A Button down?
88+
if (newState.IsButtonDown(Buttons.A))
89+
{
90+
if (!oldState.IsButtonDown(Buttons.A))
91+
{
92+
// If not down last update, the button has just been pressed.
93+
}
94+
}
95+
else if (oldState.IsButtonDown(Buttons.A))
96+
{
97+
// Button was down last update, but not down now, so it has just been released.
98+
}
99+
100+
// Which direction is the right thumbstick being moved?
101+
Vector2 direction = newState.ThumbSticks.Right;
102+
103+
// How much is the left trigger being squeezed?
104+
float leftTriggerAmount = newState.Triggers.Left;
105+
106+
// Update saved state.
107+
oldState = newState;
108+
}
109+
110+
protected override void Draw(GameTime gameTime)
111+
{
112+
base.Draw(gameTime);
113+
}
114+
}
115+
}
116+
```
117+
118+
The above sample demonstrates sampling just the first connected controller, to support multiple controllers, you will need to sample from all connected controllers (as well as managing their connected state in case one is disconnected) and use an array of [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState) to maintain the cache of all controllers.
119+
120+
> [!NOTE]
121+
> P.S. Most mobiles these days can support Bluetooth GamePads, so make sure you also support them if you intend to ship your game on mobile!!
122+
123+
## See Also
124+
125+
- [Detecting a Key Press](HowTo_DetectKeyPress.md)
126+
- [Working with Touch Input](HowTo_UseMultiTouchInput.md)
127+
128+
### Reference
129+
130+
- [Microsoft.Xna.Framework.Input](xref:Microsoft.Xna.Framework.Input)
131+
- [GamePadState](xref:Microsoft.Xna.Framework.Input.GamePadState)
132+
- [JoystickState](xref:Microsoft.Xna.Framework.Input.JoystickState)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
title: Detecting a Key Press
3+
description: The code in this topic describes how to detect a key press or release on the keyboard.
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
By using [Keyboard.GetState](xref:Microsoft.Xna.Framework.Input.Keyboard.GetState) a game can determine which keys are being held down. A game often needs to detect when a user has pressed or released a key. For example, there is the case of an action title that requires users to press and release keys in rapid succession. The example uses a cached [KeyboardState](xref:Microsoft.Xna.Framework.Input.KeyboardState) object to determine if keys were pressed or released in a given frame.
10+
11+
Depending on game design, there may be times when checking for a key press needs to occur more frequently, and other times it does not. It is possible in the case of very fast key presses that more than one key press could occur within one frame. In such a case, the last key press is returned. Writing code that checks as often as possible for key presses is the best way to handle this case.
12+
13+
## Detecting a Key Press or Release
14+
15+
1. Declare a [KeyboardState](xref:Microsoft.Xna.Framework.Input.KeyboardState) object to hold the last known keyboard state (in this example, the **oldState** object).
16+
17+
2. Assign this object a value in your constructor.
18+
19+
3. Call [GetState](xref:Microsoft.Xna.Framework.Input.Keyboard.GetState) to retrieve the current keyboard state (in this example, the **newState** object).
20+
21+
4. Compare the values in your **newState** object to the values in the **oldState** object.
22+
23+
Keys pressed in the **newState** object that were not pressed in the **oldState** object were pressed during this frame. Conversely, keys pressed in the **oldState** object that are not pressed in the **newState** object were released during this frame.
24+
25+
5. Update **oldState** object to the **newState** object before leaving **Update**.
26+
27+
```csharp
28+
using Microsoft.Xna.Framework;
29+
using Microsoft.Xna.Framework.Input;
30+
31+
namespace Keypress
32+
{
33+
public class Game1 : Microsoft.Xna.Framework.Game
34+
{
35+
GraphicsDeviceManager graphics;
36+
KeyboardState oldState;
37+
38+
public Game1()
39+
{
40+
graphics = new GraphicsDeviceManager(this);
41+
}
42+
43+
protected override void Initialize()
44+
{
45+
base.Initialize();
46+
oldState = Keyboard.GetState();
47+
}
48+
49+
protected override void Update(GameTime gameTime)
50+
{
51+
// Allows the game to exit
52+
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
53+
{
54+
this.Exit();
55+
}
56+
57+
UpdateInput();
58+
59+
base.Update(gameTime);
60+
}
61+
62+
private void UpdateInput()
63+
{
64+
KeyboardState newState = Keyboard.GetState();
65+
66+
// Is the SPACE key down?
67+
if (newState.IsKeyDown(Keys.Space))
68+
{
69+
if (!oldState.IsKeyDown(Keys.Space))
70+
{
71+
// If not down last update, key has just been pressed.
72+
}
73+
else
74+
{
75+
// If down last update, key is being held.
76+
}
77+
78+
}
79+
else if (oldState.IsKeyDown(Keys.Space))
80+
{
81+
// Key was down last update, but not down now, so it has just been released.
82+
}
83+
84+
// Update saved state.
85+
oldState = newState;
86+
}
87+
88+
protected override void Draw(GameTime gameTime)
89+
{
90+
base.Draw(gameTime);
91+
}
92+
}
93+
}
94+
```
95+
96+
## See Also
97+
98+
- [Detecting a Button Press](HowTo_DetectGamePadInput.md)
99+
- [Working with Touch Input](HowTo_UseMultiTouchInput.md)
100+
101+
### Reference
102+
103+
- [Microsoft.Xna.Framework.Input](xref:Microsoft.Xna.Framework.Input)
104+
- [KeyboardState](xref:Microsoft.Xna.Framework.Input.KeyboardState)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: Detecting Gestures on a multi-touch Screen
3+
description: This topic demonstrates how to detect and use multi-touch gestures in a MonoGame game.
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
The code in this topic shows you the technique for detecting and using multi-touch gestures. You can download a complete code sample for this topic, including full source code and any additional supporting files required by the sample.
10+
11+
MonoGame supports multi-touch gesture-based input on Mobile. The primary class that provides this support is [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which provides the ability to:
12+
13+
- Designate which gestures should be detected.
14+
- Query to see if any gestures are available for processing.
15+
16+
> [!NOTE]
17+
> Gesture support is provided as a convenient subset of the features possible on a multi-touch input device. For more information about general multi-touch programming, see [Working with Touch Input](HowTo_UseMultiTouchInput.md).
18+
19+
## How to detect Gestures on a multi-touch Screen
20+
21+
1. Set the gestures to enable with [TouchPanel.EnabledGestures](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel). This can be one value, or a combination of values, in the [GestureType](xref:Microsoft.Xna.Framework.Input.Touch) enumeration. Performance can be decreased by enabling all gestures, so it is a good practice to enable only the gestures you will be using in your game.
22+
23+
2. During your game loop, check to see if any gestures are available with [TouchPanel.IsGestureAvailable](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable). When [IsGestureAvailable](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.IsGestureAvailable) is **false**, there are no more gestures in the queue.
24+
25+
3. If gestures are available, call [TouchPanel.ReadGesture](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get a [GestureSample](xref:Microsoft.Xna.Framework.Input.Touch) that contains the data for the gesture.
26+
27+
> Some gestures will be preceded by another gesture that begins the gesture. For instance, a **DoubleTap** gesture is always preceded by a **Tap** gesture. For more information about the various gesture types supported, see [GestureType](xref:Microsoft.Xna.Framework.Input.Touch).
28+
29+
## Example
30+
31+
The following code illustrates the procedure for detecting gestures on a multi-touch screen.
32+
33+
- Enabling gestures in the game's constructor:
34+
35+
```csharp
36+
// set up touch gesture support: make vertical drag and flick the
37+
// gestures that we are interested in.
38+
TouchPanel.EnabledGestures =
39+
GestureType.VerticalDrag | GestureType.Flick;
40+
```
41+
42+
- Detecting gestures in the game's Update method:
43+
44+
```csharp
45+
// get any gestures that are ready.
46+
while (TouchPanel.IsGestureAvailable)
47+
{
48+
GestureSample gs = TouchPanel.ReadGesture();
49+
switch (gs.GestureType)
50+
{
51+
case GestureType.VerticalDrag:
52+
// move the poem screen vertically by the drag delta amount.
53+
poem.offset.Y -= gs.Delta.Y;
54+
break;
55+
56+
case GestureType.Flick:
57+
// add velocity to the poem screen (only interested in changes to Y velocity).
58+
poem.velocity.Y += gs.Delta.Y;
59+
break;
60+
}
61+
}
62+
```
63+
64+
## See Also
65+
66+
- [Working with Touch Input](HowTo_UseMultiTouchInput.md)
67+
68+
### Reference
69+
70+
- [Microsoft.Xna.Framework.Input.Touch](xref:Microsoft.Xna.Framework.Input.Touch)
71+
- [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel)
72+
- [GestureType](xref:Microsoft.Xna.Framework.Input.Touch.GestureType)
73+
- [GestureSample](xref:Microsoft.Xna.Framework.Input.Touch.GestureSample)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
title: How to work with Touch Input
3+
description: This topic demonstrates how to detect and use multi-touch input in a MonoGame game.
4+
requireMSLicense: true
5+
---
6+
7+
## Overview
8+
9+
MonoGame supports multi-touch input on Mobile. The primary class that provides this support is [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which can:
10+
11+
* Determine the touch capabilities of the current device.
12+
* Get the current state of the touch panel.
13+
* Detect touch gestures such as flicks, pinches, and drags. (For more information, see [Detecting Gestures on a multi-touch Screen](HowTo_Detect_Gestures.md).)
14+
15+
## Determining the Capabilities of the Touch Input Device
16+
17+
By using [TouchPanel.GetCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel.GetCapabilities) you can determine if the touch panel is available. You also can determine the maximum touch count (the number of touches that can be detected simultaneously).
18+
19+
## To determine the capabilities of the touch device
20+
21+
1. Call [TouchPanel.GetCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel), which returns a [TouchPanelCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) structure.
22+
23+
2. Ensure [TouchPanelCapabilities.IsConnected](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) is **true**, indicating that the touch panel is available for reading.
24+
25+
3. You then can use the [TouchPanelCapabilities.MaximumTouchCount](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) property to determine how many touch points are supported by the touch panel.
26+
27+
> All touch panels for mobile return a [MaximumTouchCount](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities) value of 4 in MonoGame.
28+
29+
The following code demonstrates how to determine if the touch panel is connected, and then reads the maximum touch count.
30+
31+
```csharp
32+
TouchPanelCapabilities tc = TouchPanel.GetCapabilities();
33+
if(tc.IsConnected)
34+
{
35+
return tc.MaximumTouchCount;
36+
}
37+
```
38+
39+
## Getting multi-touch Data from the Touch Input Device
40+
41+
You can use [TouchPanel.GetState](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get the current state of the touch input device. It returns a [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection) structure that contains a set of [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation) structures, each containing information about position and state for a single touch point on the screen.
42+
43+
## To read multi-touch data from the touch input device
44+
45+
1. Call [TouchPanel.GetState](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel) to get a [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection) representing the current state of the device.
46+
47+
2. For each [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation) in the [TouchCollection](xref:Microsoft.Xna.Framework.Input.Touch.TouchCollection), read the location and state data provided for each touch point.
48+
49+
The following code demonstrates how to get the current state of the touch input device and read touch data from each [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation). It checks to see if a touch location has been pressed or has moved since the last frame, and if so, draws a sprite at the touch location.
50+
51+
```csharp
52+
// Process touch events
53+
TouchCollection touchCollection = TouchPanel.GetState();
54+
foreach (TouchLocation tl in touchCollection)
55+
{
56+
if ((tl.State == TouchLocationState.Pressed)
57+
|| (tl.State == TouchLocationState.Moved))
58+
{
59+
60+
// add sparkles based on the touch location
61+
sparkles.Add(new Sparkle(tl.Position.X,
62+
tl.Position.Y, ttms));
63+
64+
}
65+
}
66+
```
67+
68+
## See Also
69+
70+
- [Detecting Gestures on a Multi-touch Screen](HowTo_Detect_Gestures.md)
71+
- [Detecting a Key Press](HowTo_DetectKeyPress.md)
72+
- [Detecting a Button Press](HowTo_DetectGamePadInput.md)
73+
74+
### Reference
75+
76+
- [Microsoft.Xna.Framework.Input.Touch](xref:Microsoft.Xna.Framework.Input.Touch)
77+
- [TouchPanel](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanel)
78+
- [TouchPanelCapabilities](xref:Microsoft.Xna.Framework.Input.Touch.TouchPanelCapabilities)
79+
- [TouchLocation](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocation)
80+
- [TouchLocationState](xref:Microsoft.Xna.Framework.Input.Touch.TouchLocationState)

0 commit comments

Comments
 (0)