|Windows Phone 7 Sensors and XNA|
|Orientation: XNA Orientation Demo|
|Back to main page||
Release 1.0 (XNA V4.0)
Pre-requisite: this tutorial assumes you have read through the Pinch Zoom Touch Panel Tutorial, in particular,
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 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.
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:
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 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).
- 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 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.
We see that the decoding of user's action is divided to user's attempt to set the application orientation (Label U1a) and user's attempt to switch between locking/unlocking orientation.
When the application has locked the orientation, we will follow user's gestures and call respective functions to either SetToLanscape() mode or SetToPortrait(). These two functions are implemented in the OrientationDemo_Compute.cs file and will be described later in this tutorial here. The mLockedOrientation test in each of the cases say that if the application has not locked the orientation, all user gestures will be ignored (and thus the orientation will be under the control of the physical devices' actual orientation).
See that to unclock the orientation, we simply tell the GraphicsDeviceManager that the SupportedOrientations modes are the combination of all three: Portrait, LandscapeRight, and LandscapeLeft. We also register an event service routine (PhoneOrientationChanged) with the current GameWindow such that when the physical orientation changes, the event service routine can be invoked to change the graphics device setting to support the new orientation. The details of PhoneOrientationChange function is implemented in the OrientationDemo_Compute.cs file will be described later in this tutorial here.
To change back to locked orientation, we simply set the SupportedOrientations mode to one single mode. In this case, we set it to the current GameWindow orientation (current orientation of the physical phone).
Notice that it is important to call the ApplyChange() funciton to activate the new orientation setting.
Updates the balloon position and wraps around in Y if moved beyond the top of the application screen.
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.
|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.|