Windows Phone 7 Sensors and XNA
Orientation: XNA Orientation Demo
Back to main page

Release 1.0 (XNA V4.0)

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:

Pre-requisite: this tutorial assumes you have read through the Pinch Zoom Touch Panel Tutorial, in particular,

2. Demo Program Behavior


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.

Portrait Image
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:

Portrait Image
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:
Portrait Image
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 the orientation.

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:

4. Implementation Details:

4a. OrientationDemo.cs: (User Interaction Support)

An Image Image
The above listing shows a source code structure similar to the structure from the Pinch Zoom Touch Panel Tutorial. There are two main difference:
  1. Library references: at the very top of the file, we see that there are two extra library references:
    • 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).
  2. 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 to).
The Constructor:
An Image Image
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 Update() Function:
An Image Image
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 the orientations)

An Image Image
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.
An Image Image
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.
An Image Image
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).
An Image Image
Identical to SetToLandscape(), except in this case the mode is set to Portrait.
An Image Image
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).
An Image Image
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


Kelvin Sung
Computing and Software Systems
University of Washington, Bothell
Project home page: The Game-Themed Introductory Programming Project.

Microsoft Logo 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 Higher Education.