Logo
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
PREGNANCY
 
 
Windows Phone

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

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
- Windows Phone 7 Programming Model : Web Browser Control
- Windows Phone 7 Programming Model : Tasks
- Windows Phone 7 Programming Model : Application Data Persistence
- Windows Phone 7 Programming Model : Device Information
- iphone Programming : Mixing OpenGL ES and UIKit, Rendering Confetti, Fireworks, and More: Point Sprites
- iphone Programming : Animation with Sprite Sheets, Image Composition and a Taste of Multitexturing
- XNA Game Studio 3.0 : Creating Game Components - Adding Game Sounds
- Iphone Application : Using Gesture Recognizers (part 4)
- Iphone Application : Using Gesture Recognizers (part 3)
- Iphone Application : Using Gesture Recognizers (part 2)
 
 
Most view of day
- Customizing Windows 7 : Change the Windows 7 Color Scheme
- Microsoft Systems Management Server 2003 : Patch Management - The Need for Effective Patch Management, Introduction to the Patch Management Process
- Microsoft Exchange Server 2007 : Managing a Windows Server 2003 Cluster
- How to Troubleshoot USB Problems : How to Solve USB Driver and Hardware Problems, Understanding USB Limitations
- Conquering Malicious Software : Using Antivirus Software
- Windows Server 2008 R2 file and print services : Services for Network File System, Windows Search Service
- Configuring Startup and Troubleshooting Startup Issues : What’s New with Windows Vista Startup
- BizTalk 2006 : Getting Started with Pipeline Development (part 2) - Understanding Pipeline Execution, Understanding Interchanges
- Microsoft PowerPoint 2010 : Finalizing Your Slide Show - Setting Up a Slide Show
- Microsoft Excel 2010 : Inserting Blank Rows (part 1) - Separating Subtotaled Rows for Print
Top 10
- Integrating SharePoint 2013 with the Office Applications (part 10) - Microsoft Outlook - Lists and Libraries
- Integrating SharePoint 2013 with the Office Applications (part 9) - Microsoft InfoPath - Customizing the Document Information Panel and List Forms
- Integrating SharePoint 2013 with the Office Applications (part 8) - Microsoft InfoPath -Deploying a Form Via Central Administration, Rendering a Form Using the InfoPath Form Web Part
- Integrating SharePoint 2013 with the Office Applications (part 7) - Microsoft Access - Access Services
- Integrating SharePoint 2013 with the Office Applications (part 6) - Microsoft Access
- Integrating SharePoint 2013 with the Office Applications (part 5) - Microsoft OneNote
- Integrating SharePoint 2013 with the Office Applications (part 3) - Microsoft Excel
- Integrating SharePoint 2013 with the Office Applications (part 3) - Microsoft Excel
- Integrating SharePoint 2013 with the Office Applications (part 2) - Microsoft Word - Compare Document Versions, Quick Parts
- Integrating SharePoint 2013 with the Office Applications (part 1) - Microsoft Word - Writing Blog Posts
 
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro