WP7 Virtual GamePad usage
With the next release of the Indiefreaks Game Framework will come a new feature dedicated to the WP7 builds which will make IGF totally compatible with this platform:
The WP7 Virtual GamePad
The idea behind it is to map player touch input to screen areas which will then transform it into PlayerInput thumbstick directions, button pressed, hold and released states. The developer then has several options to skin a set of controls (Thumbstick, buttons) and define how they should be rendered on the screen.
Here is a video showing what it looks like at the current stage in Ace on Steroids:
As you can see, each control can have several options:
- Should it always render?
- What if the minimal and maximal opacity response to player input?
- Should it be static (set at a given position) or dynamic (depends where the player first touches the screen)?
All of it is builtin the InputManager WP7 virtual gamepad feature
Simple mapping setup…
One of the most important requirements I wanted for this feature was a really easy setup system and I’ll show you right here how an Indiefreaks Game Framework user would achieve similar result as in the above video. If you already played with the Windows virtual gamepad mapping, you know how easy it is to map your mouse or keys to it
The first thing you’ll want to do is define the TouchArea instances for the controls you want to provide in your WP7 game.
To do so, somewhere in your game code, ideally in an initialization phase, you’ll write the following code:
PlayerInput playerInputOne = Input.GetPlayerInput(PlayerIndex.One);
playerInputOne.UseWindowsPhoneTouch = true;
playerInputOne.VirtualGamePadMapping.LeftStick = new TouchMap {Static = false, TouchArea= new Rectangle(0, 0, TouchPanel.DisplayWidth/2, TouchPanel.DisplayHeight)};
playerInputOne.VirtualGamePadMapping.Start = new TouchMap { TouchArea = new Rectangle(bounds.Width - 32, 0, 32, 32) };
playerInputOne.VirtualGamePadMapping.A = new TouchMap { TouchArea = new Rectangle(TouchPanel.DisplayWidth -75, TouchPanel.DisplayHeight - 75, 60, 60) };
Let’s now go through this code line by line and explain what we’re doing:
The first line retrieves the PlayerInput instance we want to associate our virtual gamepad with. On WP7, there’s only 1 player in a game so you’ll simple call for the PlayerIndex.One associated instance.
PlayerInput playerInputOne = Input.GetPlayerInput(PlayerIndex.One);
Then we simply tell the PlayerInput instance to use the WP7 touch input. This will just allow the InputManager component to update the PlayerInput with a list of Touch instances retrieved from Xna.
playerInputOne.UseWindowsPhoneTouch = true;
LeftStick
Now comes the fun part ![]()
We’ll first start to create the TouchMap instance that will be used for the Left thumbstick. The TouchMap is a simple class that holds a few specific properties from which are computed all the Input logic and rendering.
playerInputOne.VirtualGamePadMapping.LeftStick = new TouchMap {Static = false, TouchArea= new Rectangle(0, 0, TouchPanel.DisplayWidth/2, TouchPanel.DisplayHeight)};
The TouchMap instance for our LeftStick will be set as Dynamic which means that we’ll wait for the player’s first touch in the screen to define where the thumbstick center will be; all values associated to it will be computed based on this center position until the player stops touching the screen. If we had set it to static, the player would have to touch a specific region where you’d probably always render the stick so that he can see which direction he wants to push it to.
The second property set for our LeftStick virtual gamepad mapping is a TouchArea which consists of a some Rectangle representing the region which will be considered to receive dispatched Touch events. In this case, we decided to use the whole left of the screen device.
TouchArea= new Rectangle(0, 0, TouchPanel.DisplayWidth/2, TouchPanel.DisplayHeight)
Note that I decided to make this stick dynamic and have a large TouchArea because the spaceship in my game may be placed behind the stick and therefore be very difficult to see what is going on with player’s input. In a FPS game, this won’t be necessary and the controls can be static and always render to the screen.
Start button
Like in many games, we’ll need a button to pause the game and it’s usually assigned to the Start button on Xbox 360 so we’ll use the same for our WP7 virtual gamepad. This is actually a pretty smart move as since IGF shares the same buttons and sticks for all platforms (Windows, Xbox 360 and WP7), the same code you write to react to a given input will be executed whatever the platform.
This time, we want our “pause” button to always be visible and static so the user knows exactly where to touch to pause his game session. We therefore simply create a TouchMap instance with solely a TouchArea which in our case is placed on the top right corner.
playerInputOne.VirtualGamePadMapping.Start = new TouchMap { TouchArea = new Rectangle(bounds.Width - 32, 0, 32, 32) };
A button
Now, I needed a button for the player to shoot and I decided to map it to the A button.
To do so, I decided to place it on the lower right corner of the screen as you’d expect it to be using a dedicated TouchMap instance.
playerInputOne.VirtualGamePadMapping.A = new TouchMap { TouchArea = new Rectangle(TouchPanel.DisplayWidth -75, TouchPanel.DisplayHeight - 75, 60, 60) };
And now our virtual gamepad is all set.
… and simple skinning setup!
But defining how input is mapped to our virtual gamepad isn’t enough: we also need to define its appearance and how it reacts visually to the player touches.
I maintained the same simplicity requirement as above yet wanted the developer to really be in total control on how it renders to the screen. Here is the code that I used to skin it in Ace on Steroids:
Input.VirtualGamePadSkin.LeftStick.SensibleVisibility = true;
Input.VirtualGamePadSkin.LeftStick.AreaTexture = Content.Load<Texture2D>("Textures/UI/thumbstickBase");
Input.VirtualGamePadSkin.LeftStick.ThumbStickTexture = Content.Load<Texture2D>("Textures/UI/thumbstick");
Input.VirtualGamePadSkin.LeftStick.MaxThumbStickDistance = 30f;
Input.VirtualGamePadSkin.Start.SensibleVisibility = false;
Input.VirtualGamePadSkin.Start.MaxOpacity = 0.5f;
Input.VirtualGamePadSkin.Start.NormalTexture = Content.Load<Texture2D>("Textures/UI/pausebutton");
Input.VirtualGamePadSkin.A.SensibleVisibility = true;
Input.VirtualGamePadSkin.A.MinOpacity = 0.25f;
Input.VirtualGamePadSkin.A.NormalTexture = Content.Load<Texture2D>("Textures/UI/shootbutton");
Simple and straightforward but let’s dig in each of these blocks.
LeftStick skinnning
The InputManager instance has a VirtualGamePadSkin which stores for each input control a set of properties to skin it.
One of the really important values is the SensibleVisibility property which accepts a boolean to tell InputManager if it should always render to the screen at MaxOpacity or only render it when the player touches the screen and slowly fades out to the MinOpacity property value (which ranges from 0 to 1). We’ll go slightly more in detail on the Min and MaxOpacity properties.
For the above mentioned reasons, we don’t want the LeftStick to be visible all the time so we set it to true. Then, it’ll only be visible when the player hits the screen and where he did. The MinOpacity defaults to 0 and the MaxOpacity defaults to 1 so we don’t need to set them manually.
Input.VirtualGamePadSkin.LeftStick.SensibleVisibility = false;
Then, we simply give to our LeftStick skin the paths to our Area and Thumbstick textures.
The LeftStick is actually splitted into 2 rendered controls, the one representing the base of the stick and another for the actual button where you place your thumb. The latter being the one that will move in the whole range of directions from the center of the stick.
Input.VirtualGamePadSkin.LeftStick.AreaTexture = Content.Load<Texture2D>("Textures/UI/thumbstickBase");
Input.VirtualGamePadSkin.LeftStick.ThumbStickTexture = Content.Load<Texture2D>("Textures/UI/thumbstick");
Here is what they look like individually:
![]()
![]()
Finally, the LeftStick skin has a specific property: MaxThumbStickDistance.
This property will tell the InputManager renderer how far from the center should the Thumbstick be allowed to render. The input for our Sticks will be handled until the player removes his finger from the screen so the player could potentially move his finger far away from the center of the stick and even outside of its TouchArea (the system is smart enough to identify which finger from the multitouch surface is associated to the stick input control). Therefore, you may don’t want the thumbstick to be synchronized to the player’s finger position on the screen and emulate a physical stick like I do in Ace on Steroids. That’s what this property serves for.
Setting its value to 30 means the thumbstick is only autorized to be rendered up to 30 pixels from the stick center.
Input.VirtualGamePadSkin.LeftStick.MaxThumbStickDistance = 30f;
Start button skinning
The Start button skinning is also setting its SensibleVisibility to false so that it always renders at MaxOpacity and is always visible to the player.
Input.VirtualGamePadSkin.Start.SensibleVisibility = false;
We set the MaxOpacity to 0.5 so that it doesn’t occlude what could be rendered behind it.
Input.VirtualGamePadSkin.Start.MaxOpacity = 0.5f;
Buttons in the WP7 virtual gamepad use the TouchArea defined in their VirtualGamePadMapping property as their rendering location so be sure to set them both accordingly: size of the texture should match the TouchArea rectangle width & height.
Finally, we provide the skin with the path to the normal state texture (you could also set a pressed state texture if you want to but we don’t use it in this specific example) which looks like this:
Input.VirtualGamePadSkin.Start.NormalTexture = Content.Load<Texture2D>("Textures/UI/pausebutton");
A button skinning
The A button skinning should now be quite easy to understand if you got previously explained concepts.
It is set to use SensibleVisibility so that it reacts to player’s input touches.
Input.VirtualGamePadSkin.A.SensibleVisibility = true;
However, we still want it to be slightly visible so the player knows where to hit the screen to shoot so we defined a low MinOpacity value. When it gets hit, the button uses its MaxOpacity value and then fades out to MinOpacity when the player removes his finger from the screen.
Input.VirtualGamePadSkin.A.MinOpacity = 0.25f;
And finally, we provide the skin with the path to the normal state texture:
Input.VirtualGamePadSkin.A.NormalTexture = Content.Load<Texture2D>("Textures/UI/shootbutton");
I hope it helps you understand how everything works. I expect this to be largely used as it is a common requirement for WP7 games.
This feature will be delivered within the next release of the Indiefreaks Game Framework. Until then, you can grab the latest changeset from http://igf.codeplex.com and start playing with it. It’s fully functionnal

