1. Topics Covered
This program demonstrates XNA support for the changing of the phone orientation.
You may wish to download the source code,
open the project and refer to the source code while follow the discussion. Topics
covered in this tutorial includes:
- Application locking and controlling orientation (and ignores the actual phone orientation).
- Application respect the physical phone orientation and adjusts reference coordinate
system system accordingly.
Pre-requisite: this tutorial assumes you have read through the
Pinch Zoom Touch Panel Tutorial, in particular,
2. Demo Program Behavior
- Double tab: to switch between phone or application control of orientation settings.
- When under phone control: the application's orientation setting will respect that
of the physical phone, the balloon will always move upwards.
- When under orientation is under application control (orientation locked):
- Press and Hold (for 1 second): to set orientation to portrait
- Horizontal drag (in the x-direction of the current orientation): to set orientation
to Left Landscape
- Vertical drag (in the y-direction of the current orientation): to set orientation
to Right Landscape.
Here are the details: You will see screens similar to the following when you compile
the attached source code, dispatch to WP7 device/emulator, and run the program.
The above image shows the application in the Portrait orientation. Notice
the white square label underneath the help message in the top-left corner, this
white square label is drawn at coordinate location (0,0). In similar fashion, the
"W" and "H" labels are drawn at coordinate
locations (W,0) and (0,H) correspondingly. W and H are the width and height of the
phone screen size. These three labels tells us that, in the portrait orientation,
the top-left corner is the origin, and x-axis (width) increase towards the right
direction, while y-axis (height) increases towards the down direction. You should
see the balloon ascend continuously "up wards."
If you drag your finger in the "horizontally" (along the x-direction),
you will see the "Left Landscape" orientation, as follow:
Notice in this orientation, the origin (white square label) is still at the top-left
corner, while the W and H labels continue to locate at the corresponding locations
of "towards the right" and "towards the down direction".
Now drag your finger in the "vertical" direction (along the y-direction,
or along the motion of the balloon), you will see the "Right Landscape"
orientation as follows:
Once again, notice that the origin, H, and W labels are all located at the corresponding
corners that intuitively makes sense. If you press the screen and hold (for about
1 sec), the application will change the orientation back to portrait again.
In addition, notice that the application ignores the orientation of the physical
phone. For example, turn your phone to see that the application does not response
to the actual phone orientation changes. In this case, the application has locked
Double tap on the phone to unlock the orientation. Now turn your phone
around to see the application response to the physical phone orientation accordingly.
The following discuss the implementation details.
3. Solution Structure and External Environment
As discussed, the solution structure of this tutorial is similar to the
solution structure of the Pinch Zoom Touch Panel tutorial, where SimpleLibrary
is referenced for the image and font output. The following are the differences:
- Source code files: The implementation are contain in two files:
In our discussion, we will first look at user interaction (in OrientationDemo.cs)
and then examine the actual changing of orientation in the graphics device.
- OrientationDemo.cs: implements the main XNA framework functions that supports
- OrientatoinDemo_Compute.cs: implements the actual code that switches the
graphics device orientation.
- External Resources: there are the usual background music and sound effect
files. In this application there are 6 image objects: the three labels (origin,
H, and W markers), the balloon, and the two background images (for landscape and
4. Implementation Details:
4a. OrientationDemo.cs: (User Interaction Support)
The above listing shows a source code structure similar to the
structure from the Pinch Zoom Touch Panel Tutorial. There are two main difference:
- Library references: at the very top of the file, we see that there are two extra
- System.Windows: for Deployment class to support thread-safe function call
(more details later).
- Microsoft.Devices: for VibrateController class to support vibrating the device
(as an echo to double tap).
- Instance variables supporting user interactions (under Label E):
- mLockedOrientation: indicating if the orientation is locked by the application
- mNoActiveDrag: indicating if we have already responded to user's current
drag action (to avoid constantly changing an orientation which we have already responded
The Update() Function:
The above listing shows the constructor, where under Label F1, we lock the
application's orientation setting by specifying the preferred back buffer resolution
(to 480x800) and that the only supported orientation mode is Portrait.
The above listing shows that, beside detecting the quit condition (Label U3), the
update() function only needs to perform two main functions, decode the user's action
(under Label U1) and update the balloon position (Label U2). The following listings
focus on the code under each of these two labels.
4b. OrientationDemo_Compute.cs: (Code that modifies
This file implements the actual code that changes orientation and the event service
routine when the phone controls the orientation. The following explains each function
in this file according to their order in the above listing.
After each orientation changes, this function ensure the balloon remains in the
middle (in x-direction) of the screen, and can never be lower than the current orientation
height (e.g., when the balloon is located near y=800, a change from portrait to
landscape mode means the balloon will be underneath the bottom of the screen and
will not be visible for a short while). This function also re-computes the (W,0)
and (0,H) positions for the W and H markers.
Sets the current orientation to either Left or Right landscape mode. Since the SupportedOrientations
is set to only one mode. The application will behaves as though this is the
only mode (thus appears as though the orientation is locked).
Identical to SetToLandscape(), except in this case the mode is set to Portrait.
When the application wants to support more than one orientation modes, it is important
to determine the current phone orientation (by checking the Windows.CurrentOrientation
and response accordingly. This function should be called each time the phone's orientation
changes. In our case, this function is called from the phone orientation change
event service routine (refer to the following).
This is the event service routine we have registered with the GameWindow class under
Label U1b. This function is called from a different thread
asynchronously whenever the phone orientation changes. Notice that since this is
called from another thread, we should not access the instance variables in this
method. In this case, we constructed a Lamba object and calls ChooseBackground()
in a thread-safe manner.
5. Self Test and Exercises
- What is a C# Partial class? Answer: C# language mechanism that allows the source
to one class be separated into multiple files.
- Why are the source code to this tutorial separated into two files? Answer: only
reason is for easier comprehension.
- How does the application lock the screen orientation? Answer: by setting GraphicsDeviceManager's
PreferredBackBuffer Width/Height and SupportedOrientations to one of the three supported
- How can my application unlock the orientation control and only support Left/Right
Landscape orientation and not the Portrait orientation? Answer: by setting GraphicsDeviceManager's
SupportedOrientations to "DisplayOrientation.LandscapeRight | DisplayOrientation.LandscapeLeft"
(without the Portrait option).
- Practice Project: modify the provided source code such that the origin marker is
drawn in the lower left corner (as in the case of Cartesian Coordinate System).
- Practice Project: modify the provided source code such that the balloon always moves
diagonally up-wards towards the upper right corner in all orientations.
- Practice Project: modify the provided source code to use the portrait background
image for all orientations. In the case of landscape orientations, display only
the bottom portion of the image to ensure no image distortion occurs.
Computing and Software Systems
University of Washington, Bothell
Project home page:
The Game-Themed Introductory Programming Project.
This work is supported in part by Microsoft Research under the Computer
Gaming Curriculum in Computer Science RFP, Award Number 15871 and 16531, and Microsoft