IT tutorials
 
Mobile
 

Windows Phone 7 : Building 2D Games with the XNA Framework - AlienShooter Game Play (part 4) - Hero Ship Class

5/22/2013 4:16:22 AM
- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire

4. Hero Ship Class

We create another class named UserGameObject that inherits from the GameObject class. This class represents the player, which is the Hero Ship in AlienShooter, which makes it unique to the other classes since it takes user input in the form of accelerometer and touch. The accelerometer input will move the ship left or right by tilting the phone. It has a window so that if the phone is relatively flat the ship does not move. Touching the screen will fire missiles.

4.1. User Input

By default, the Game Management sample does not include support for Accelerometer input. The GamePlayScreen class has a HandleInput method that takes a parameter of type InputState, which is a class that captures keyboard, controller, and touch input. It does not capture Accelerometer input by default.

Example 2. AccelerometerState Class File
public class AccelerometerState
{
  public double X;
  public double Y;
  public double Z;
  public DateTimeOffset Timestamp;
}

The modifications to the InputState class are pretty straightforward:

//robcamer - Add a private instance of AccelerometerState
public AccelerometerState CurrentAccelerometerState { get; private set; }
//robcamer - Add private field for the accelerometer
private Accelerometer accelerometer;

The constructor for the InputState class is modified to instantiate the previous two private variables, as well as add an event handler to the Accelerometer:

CurrentAccelerometerState = new AccelerometerState();
//Robcamer - initialize accelerometer
accelerometer = new Accelerometer();
accelerometer.ReadingChanged +=
  new System.EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
accelerometer.Start();

					  

The values of CurrentAccelerometerState are updated in the accelerometer_ReadingChanged event handler:

void accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
  CurrentAccelerometerState.X = e.X;
  CurrentAccelerometerState.Y = e.Y;
  CurrentAccelerometerState.Y = e.Z;
  CurrentAccelerometerState.Timestamp = e.Timestamp;
}

					  

4.2. Processing Input

Now that we have the modifications in place for the InputState class, two private fields related to user input are added to the UserGameObject class.

private AccelerometerState _accelerometerState;
private Vector2 _leftRightVector = new Vector2(5, 0);

The _accelerometerState and _leftRightVector fields are modified in the UserGameObject.HandleInput method.

public void HandleInput(InputState input)
{
  //Must check for TouchLocationState as wel as Count
  //Otherwise, FireMissile will be called twice

//Once for 'Pressed' and once for 'Released'
  if ((input.TouchState.Count > 0) &&
    input.TouchState[0].State == TouchLocationState.Pressed)
  {
    FireMissile();
  }

  _accelerometerState = input.CurrentAccelerometerState;
  if (_accelerometerState.X > .1)
  {
    Velocity = _leftRightVector;
  }
  if (_accelerometerState.X < -.1)
  {
    Velocity = -_leftRightVector;
  }
  //near Zero tilt left or right so
  //set velocity to zero
  if ((_accelerometerState.X < .1) &&
    (_accelerometerState.X > -.1))
    Velocity = Vector2.Zero;
}

If the _accelerometerStateX component is greater than .1, a positive or negative velocity is applied to the Velocity vector via the leftRightVector variable in the proper tilt direction. Likewise, if the user holds the phone close to neutral, Velocity is set to zero. If you don't like how it responds, play with the .1 value to see what feels good to you.

The other part of the HandleInput session is to detect if the screen is touched. Each touch fires to TouchState values, one for TouchLocationState.Pressed and one for TouchLocationState.Released. If the screen is touched the FireMissile method is fired.

The UserGameObject class manages a collection of Missile objects since they are closely associated with the hero ship:

public List<MissileGameObject> Missiles;
public int MaxNumberofMissiles;

The Missile related properties are public properties because the GameplayScreen will need to check collisions between missiles and enemy alien ships. Also, the number of available missiles could be adjusted dynamically as part of game play for a "blitz" mode, where the hero ship can fire more than three at a time as an example. The Missiles collection is instantiated in the UserGameObject constructor:

MaxNumberofMissiles = 3;
Missiles = new List<MissileGameObject>();
for (int i=0;i < MaxNumberofMissiles; i++)
  Missiles.Add(new MissileGameObject(loadedTexture,"missile",screenRect));

When the screen is touched, the FireMissile method code searches for an available missile. Only three are available by default, and sets the missile property to Alive and the MissilePosition property to the same Position value for the hero ship / UserGameObject class. Note that once the Missile is set to Alive, it automatically starts moving based on the default logic implemented in the GameObject class.

4.3. UserGameObject Class Core Methods

The UserGameObject class overrides the Update method with custom code to position the spaceship correctly with user input. It also manages the Missiles collection by calling Update for missiles where Alive is true, i.e., they are in flight. Here is the UserGameObject.Update method:

public override void Update(GameTime gameTime)
{
  base.Update(gameTime);

  if (Position.X < SpriteCenter.X)
    Position = new Vector2(SpriteCenter.X,Position.Y);
  if (Position.X > (_screenRect.Width - SpriteCenter.X))
    Position = new Vector2(_screenRect.Width-SpriteCenter.X,Position.Y);


  for (int i = 0; i < MaxNumberofMissiles; i++)
  {
    if (Missiles[i].Alive == true)
      Missiles[i].Update(gameTime);
  }
}

The Draw method is overridden as well:

public override void Draw(GameTime gameTime, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
  for (int i = 0; i < MaxNumberofMissiles; i++)
  {
    if (Missiles[i].Alive == true)
      Missiles[i].Draw(gameTime, spriteBatch);
  }
  base.Draw(gameTime, spriteBatch);
}

					  

The Draw method checks to see if each Missile is Alive and then calls Draw for the Missile object. The last item in the UserGameObject class to cover is the LoadContent method. In this method, the ContentManager instance is passed in so that the UserGameObject can make a sound effect when a missile is fired from the hero ship. Here is the method:

public void LoadContent(ContentManager content)
{
  _missileLaunchSoundEffect =
                content.Load<SoundEffect>("SoundEffects/MissileLaunch");
}

4.4. Sound Effects

XNA Game Studio has very rich audio mixing capabilities to support Dolby quality sound. For our game the SoundEffect class provides a quick and easy way to play audio during a game with the Play method. We add three sound effects to the AlienShooterContent project in the SoundEffects folder:

  • Explosion.wma

  • HeroShipDamage.wma

  • MissileLaunch.wma

One item to note is that I recorded the sounds using the Windows 7 Recorder tool, which generates a .wma file. When added to the Content project the XNA Framework automatically chose the Song - XNA Framework Content Processor. This format cannot be played by the SoundEffect class. Simply change the Content Processor to Sound Effect - XNA Framework and the audio plays fine.

Let's now move on to a discussion of the Missile class.

 
Others
 
- Windows Phone 7 : Building 2D Games with the XNA Framework - AlienShooter Game Play (part 3) - Enemy Class
- Windows Phone 7 : Building 2D Games with the XNA Framework - AlienShooter Game Play (part 2) - Game Object Class
- Windows Phone 7 : Building 2D Games with the XNA Framework - AlienShooter Game Play (part 1) - Sprite Animation
- BlackBerry Bold 9700 and 9650 Series : Connect as a Tethered Modem (part 3) - Using Desktop Manager for Mac
- BlackBerry Bold 9700 and 9650 Series : Connect as a Tethered Modem (part 2) - Using Desktop Manager for Windows
- BlackBerry Bold 9700 and 9650 Series : Connect as a Tethered Modem (part 1) - Understanding the Options for Tethering
- Android 3 : Employing Basic Widgets - Fleeting Images, Fields of Green...or Other Colors
- Android 3 : Employing Basic Widgets - Assigning Labels
- Symbian OS : Security - Buckle
- Symbian OS : Security - Secure Agent
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
programming4us programming4us
 
Popular tags
 
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS