Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Windows Phone 7 : AlienShooter Enhancements (part 1) - Load and Save Game State

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
4/28/2013 11:20:09 AM

In this section we add support for functionality you would expect to see if this was a real Windows Phone 7 game. We first implement how to load and save game state. We modify the main menu game screen to have both new game and resume game menu items in the event that previous game state is present.

We next implement tombstoning support so that the user is restored to the main menu screen and has a chance to click resume to restart game play. The last section covers how to create a basic particle system that simulates expositions when a hero ship missile collides with an alien enemy spaceship.

1. Load and Save Game State

For our game, we automatically save game state when the user backs out of the GameplayScreen with a game in progress. The main menu screen is modified to include both New Game and Resume Game menu options that will resume an existing game if saved state is present. Automatic save keeps things simple and is a typical state management approach for many game developers.

We set about modifying the MainMenuScreen class, renaming the playGameMenuEntry object to newGameMenuEntry and adding another MenuEntry named resumeGameMenuEntry. Here is the modified constructor MainMenuScreen():

public MainMenuScreen()
  : base("Main Menu")
{

// Create our menu entries.
  MenuEntry newGameMenuEntry = new MenuEntry("New Game");
  MenuEntry optionsMenuEntry = new MenuEntry("Game Options");

  // Hook up menu event handlers.
  newGameMenuEntry.Selected += newGameMenuEntrySelected;
  optionsMenuEntry.Selected += OptionsMenuEntrySelected;

  // Add entries to the menu.
  MenuEntries.Add(newGameMenuEntry);
  MenuEntries.Add(optionsMenuEntry);

  //robcamer - Only display resume game menu opion
  //if saved state is present.
  using (IsolatedStorageFile gameStorage = IsolatedStorageFile.GetUserStoreForApplication())
  {
    if (gameStorage.FileExists(AlienShooterStateFileName))
    {
      MenuEntry resumeGameMenuEntry = new MenuEntry("Resume Game");
      resumeGameMenuEntry.Selected += resumeGameMenuEntry_Selected;
      MenuEntries.Add(resumeGameMenuEntry);
    }
  }
}

					  

We want to display the "Resume Game" menu option only when there is game state present, so in the MainMenu there is a FileExists check to determine if game state is present. We add a using System.IO.IsolatedStorage statement to the top of MainMenuScreen.cs as well as a constant declaration of the state filename to wire things up:

const string AlienShooterStateFileName = "AlienShooter.dat";

We modify the new game selected event handler named newGameMenuEntrySelected to delete any saved game state since a new game is desired:

void newGameMenuEntrySelected(object sender, PlayerIndexEventArgs e)
{
  //
  using (IsolatedStorageFile gameStorage = IsolatedStorageFile.GetUserStoreForApplication())
  {
    if (gameStorage.FileExists(AlienShooterStateFileName))
    {
      gameStorage.DeleteFile(AlienShooterStateFileName);
    }
  }

  LoadingScreen.Load(ScreenManager, true, e.PlayerIndex,
                      new GameplayScreen());
}

					  

This sets things up for the GameplayScreen to load saved state or start a new game depending on what option is chosen in the MainMenuScreen UI. In the GameplayScreen object we create two new public methods to load and save state. For load state, we do the following:

  • Check for saved state; if not present, initialize the variables as before.

  • If saved state is present, restore saved state and begin game play.

To save state, we use a System.IO.StreamWriter object. We don't use object serialization because we need to instantiate the GameObject classes normally, just like when LoadContent is called. Instead, we simply save off the important state values to a text file in Isolated Storage such as the Position and Velocity vector values, the status board game score and remaining lives, and so on. The SaveAlienShooterState method always deletes the file first before saving. Also, the method does not save state if the game is over. Listing 1 shows the GameplayScreen. SaveAlienShooterState method.

Example 1. GameplayScreen. SaveAlienShooterState
public void SaveAlienShooterState()
{
  //Only save game if not GameOver
  using (IsolatedStorageFile gameStorage =
    IsolatedStorageFile.GetUserStoreForApplication())
  {
    //Overwrite existing saved game state
    if (gameStorage.FileExists(AlienShooterStateFileName))
    {
      gameStorage.DeleteFile(AlienShooterStateFileName);
    }
    if (!statusBoard.GameOver)
    {
      using (IsolatedStorageFileStream fs =
        gameStorage.OpenFile(AlienShooterStateFileName,
                              System.IO.FileMode.Create))
      {
        using (StreamWriter streamWriter = new StreamWriter(fs))
        {
          //Only serialize interesting state
          //Other state MUST be initialized each time
          streamWriter.WriteLine(heroShip.Position.X);
          streamWriter.WriteLine(heroShip.Position.Y);
          streamWriter.WriteLine(heroShip.Velocity.X);
          streamWriter.WriteLine(heroShip.Velocity.Y);
          streamWriter.WriteLine(statusBoard.Score);
          streamWriter.WriteLine(statusBoard.Lives);
          for (int i = 0; i < maxEnemies; i++)
          {
            streamWriter.WriteLine(enemies[i].Alive);
            streamWriter.WriteLine(enemies[i].Position.X);
            streamWriter.WriteLine(enemies[i].Position.Y);
            streamWriter.WriteLine(enemies[i].Velocity.X);
            streamWriter.WriteLine(enemies[i].Velocity.Y);
          }
          streamWriter.Flush();
          streamWriter.Close();
        }
      }
    }
  }
}

					  

The GameplayScreen.LoadAlienShooterState method instantiates the GameObjects and classes, i.e., heroShip. statusBoardGameStatus object, and the enemies alien ship collection. This code was cut from the GameplayScreen.LoadContent method and pasted into the GameplayScreen.LoadAlienShooterState method shown in Listing 2.

Example 2. GameplayScreen.LoadAlienShooterState Method
public void LoadAlienShooterState()
{
  using (IsolatedStorageFile gameStorage = IsolatedStorageFile.GetUserStoreForApplication())
  {
    //Initialize all objects as before
    enemies = new List<AlienGameObject>();
    for (int i = 0; i < maxEnemies; i++)
    {
      enemies.Add(new AlienGameObject(alienShooterSpriteSheet, "spaceship", screenRect));
    }

    //Initialize Player Object
    heroShip = new UserGameObject(alienShooterSpriteSheet, "heroship", screenRect, maxMissiles);
    heroShip.Position = new Vector2(screenRect.Width / 2, 720);
    heroShip.LoadContent(content);

    //Initialize Status Board
    statusBoard = new GameStatusBoard(gameFont);
    statusBoard.LoadContent(content);

    //Set saved state on objects
    if (gameStorage.FileExists(AlienShooterStateFileName))
    {
      using (IsolatedStorageFileStream fs =
      gameStorage.OpenFile(AlienShooterStateFileName, System.IO.FileMode.Open))
      {
        using (StreamReader streamReader = new StreamReader(fs))
        {
          heroShip.Position = new Vector2(
            (float)Convert.ToDouble(streamReader.ReadLine()),
            (float)Convert.ToDouble(streamReader.ReadLine()));
          heroShip.Velocity = new Vector2(
            (float)Convert.ToDouble(streamReader.ReadLine()),
            (float)Convert.ToDouble(streamReader.ReadLine()));
          statusBoard.Score = Convert.ToInt32(streamReader.ReadLine());
          statusBoard.Lives = Convert.ToInt32(streamReader.ReadLine());
          for (int i = 0; i < maxEnemies; i++)
          {
            enemies[i].Alive = Convert.ToBoolean(streamReader.ReadLine());
            enemies[i].Position = new Vector2(
              (float)Convert.ToDouble(streamReader.ReadLine()),
              (float)Convert.ToDouble(streamReader.ReadLine()));
            enemies[i].Velocity = new Vector2(
              (float)Convert.ToDouble(streamReader.ReadLine()),
              (float)Convert.ToDouble(streamReader.ReadLine()));
          }
          streamReader.Close();

					  

}
      }
    }
  }
}

The Save and Load code isn't the most elegant code you will ever see but it is simple and works fine. With this code in place, when you hit the Back hard button when playing the game, you get a Resume menu item. Figure 1 shows the updated MainMenuScreen class UI.

Figure 1. Updated main menu screen with Resume Game menu option

If you play the game until all of your lives are consumed and then hit the back button, the Resume Game menu option is not present, because there isn't any saved state.

One issue that remains is, if you are playing the game and then hit the Start button and then the Back button, the game resets to a new game on the GameplayScreen UI. What we want to happen is for state to be saved and the game resume back on the main menu screen, so that the user has a chance to get ready to play and then tap the Resume Game menu option. We cover how to implement tombstone support in the next section.

Other -----------------
- Windows Phone 7 Programming Model : Application Execution Model
- Windows Phone 7 Programming Model : Bing Maps Control
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 4) - Working with Behaviors
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 3) - Creating Animations
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 2) - Brushes
- Windows Phone 8 : Designing for the Phone - Blend Basics (part 1) - Layout
- Windows Phone 8 : Designing for the Phone - Microsoft Expression Blend
- Windows Phone 7 Programming Model : Asynchronous Programming - Background Threads
- Windows Phone 8 : Designing for the Phone - Deciding on an Application Paradigm
- Windows Phone 8 : Designing for the Phone - The Third Screen
 
 
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
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server