Locating a Windows Phone with the Location Service
The Windows Phone
provides the capability to enable you to take your games on the go.
Games are no longer just played at your home on your Xbox 360 or Windows
PC. Because phones are so portable, the phone could be anywhere in the
world. This brings some new and interesting opportunities for games.
Having a portable and connected game device enables you to design games
that take the current location into account. You could also use it to
find other players of the game who are nearby. The accuracy of the
location information while affected by several environmental factors can
be quite accurate within a few meters.
Reading Location Data
Use the GeoCoordinateWatcher
class to report the phone’s current location. You need an instance of
the geo coordinate watcher along with the latest coordinate received and
the current status. Add the following variables to your game’s class:
GeoCoordinateWatcher geoWatcher;
GeoCoordinate currentCoordinate;
GeoPositionStatus geoStatus;
Similar to acceleration data, the geo coordinate data is returned though an event-based model from GeoCoordinateWatcher. You subscribe to two events. Use the StatusChanged
to tell you the current state of the location services. After you start
the location service, the status can change and this event gives you
information about the state the service is currently in. The PositionChanged returns when the location service detects that the phone moved to a new location. Create an instance of the GeoCoordinateWatcher and subscribe to these events. Add the following lines of code to your game’s Initialize method:
geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
geoWatcher.StatusChanged += new
EventHandler<GeoPositionStatusChangedEventArgs>(geoWatcher_StatusChanged);
geoWatcher.PositionChanged += new
EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
geoWatcher.MovementThreshold = 5;
geoWatcher.Start();
When you create the instance of GeoCoordinateWatcher, you can pass in a GeoPositionAccuracy enum value of High or Low. This tells the geo coordinate watcher which accuracy should be used when returning position changed locations. The MovementThreshold
property is in meters and refers to the distance the phone needs to
travel before the position changed event is fired. Setting this value
too low can result in many position changed events caused by noise in
the determined location of the device. Finally, call Start to start the geo coordinate watcher. Just like the accelerometer, you should call Start only after you are ready to receive data because it lowers the battery life of the device. You should also call Stop whenever you are finished tracking the user’s location.
Now that the StatusChanged and PositionChanged events are set, implement the geoWatcher_StatusChanged and geoWatcher_PositionChanged methods to handle these events. Add the following methods to your game class:
void geoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
// Check the current status
geoStatus = e.Status;
switch (geoStatus)
{
case GeoPositionStatus.Initializing:
// The location service is still starting up
break;
case GeoPositionStatus.Ready:
// The location service is running and returning location data
break;
case GeoPositionStatus.NoData:
// The locaiton has started but can not current find its location
break;
case GeoPositionStatus.Disabled:
if (geoWatcher.Permission == GeoPositionPermission.Denied)
{
// The user has turned off location services
}
else
{
// The location service failed to start
}
break;
}
}
void geoWatcher_PositionChanged(object sender,
GeoPositionChangedEventArgs<GeoCoordinate> e)
{
// Store the current coordinate
currentCoordinate = e.Position.Location;
}
Now, store the current location coordinate each time the location is updated. GeoCoordinate provides number properties that contain data about the phone’s current location. The Latitude and Longitude properties can be used to return their respective positions on the Earth. The Altitude property returns the current altitude in meters. The Course
property returns the current direction the phone is moving in. The
property returns a double value between 0 and 360 degrees. The Speed property returns the current speed of the phone in the course direction. The final two properties, HorizontalAccuracy and VerticalAccuracy,
return accuracy of the current coordinate. You can use these values to
determine whether you want to use a given point depending on the
accuracy needs of your application. To display these properties, add the
following code to your game’s Draw method:
string locationInfo = "Status: " + geoStatus.ToString() + "\n";
if (currentCoordinate != null)
{
locationInfo += "Latitude: " + currentCoordinate.Latitude.ToString("0.000") + "\n";
locationInfo += "Longitude: " + currentCoordinate.Longitude.ToString("0.000") + "\n";
locationInfo += "Altitude: " + currentCoordinate.Altitude.ToString("0.000") + "\n";
locationInfo += "Course: " + currentCoordinate.Course.ToString("0.000") + "\n";
locationInfo += "Speed: " + currentCoordinate.Speed.ToString("0.000") + "\n";
locationInfo += "HorizontalAccuracy: " +
currentCoordinate.HorizontalAccuracy.ToString("0.000") + "\n";
locationInfo += "VerticalAccuracy: " +
currentCoordinate.VerticalAccuracy.ToString("0.000") + "\n";
}
spriteBatch.Begin();
spriteBatch.DrawString(spriteFont, locationInfo, new Vector2(10, 50), Color.White);
spriteBatch.End();
The previous code requires that you have already added a SpriteFont to your project and it is loaded into the spriteFont variable.
Providing User Feedback using Vibration
The Xbox 360 gamepad is not the
only device that supports force feedback using vibration. The Windows
Phone provides the capability to start the vibration motor inside the
Windows Phone device. The VibrateController type provides both a Start and Stop method for controlling the vibration of the device. The Start method takes in a TimeSpan for the duration you want the device to vibrate. Although the vibration stops after the given TimeSpan, you can also call the Stop method to stop the vibration before the duration has expired. To add vibration to your game, you first need an instance of the VibrateController. You can obtain an instance by using the VibrateController.Default property. Add the following member variable to your game’s class:
VibrateController vibrateController;
In your game’s Initialize method, add the following line of code:
vibrateController = VibrateController.Default;
Now all that is left is to
start the vibration motors on the device. Use the following line of code
to have the device vibrate for three seconds:
vibrateController.Start(TimeSpan.FromSeconds(3));
If you need to stop the vibration that you have already started, call the Stop method using the following code:
vibrateController.Stop();