Time for action - implementing game states

  1. Add declarations to the Game1 class for our GameState enum:
    enum GameState { TitleScreen, Playing, PlayerDead, GameOver };
    GameState gameState = GameState.TitleScreen;
    
  2. Still in the declarations section of the Game1 class, add vectors for the display position of our text items, a texture to hold the title screen image, and the delay before respawn when the player dies:
    Vector2 gameOverPosition = new Vector2(350, 300);
    Vector2 livesPosition = new Vector2(600, 580);
    Texture2D titleScreen;
    float deathTimer = 0.0f;
    float deathDelay = 5.0f;
    
  3. We currently have temporary code in the LoadContent() method that loads straight into the first level of the game. Replace the current LoadContent() method with the following:
    protected override void LoadContent()
    {
    spriteBatch = new SpriteBatch(GraphicsDevice);
    TileMap.Initialize(
    Content.Load<Texture2D>(@"TexturesPlatformTiles"));
    TileMap.spriteFont =
    Content.Load<SpriteFont>(@"FontsPericles8");
    pericles8 = Content.Load<SpriteFont>(@"FontsPericles8");
    titleScreen = Content.Load<Texture2D>(@"TexturesTitleScreen");
    Camera.WorldRectangle = new Rectangle(0, 0, 160 * 48, 12 * 48);
    Camera.Position = Vector2.Zero;
    Camera.ViewPortWidth = 800;
    Camera.ViewPortHeight = 600;
    player = new Player(Content);
    LevelManager.Initialize(Content, player);
    }
    
  4. Add the StartNewGame() helper method to the Game1 class:
    private void StartNewGame()
    {
    player.Revive();
    player.LivesRemaining = 3;
    player.WorldLocation = Vector2.Zero;
    LevelManager.LoadLevel(0);
    }
    
  5. Replace the Update() method with the following to remove any temporary code and implement the game state logic:
    protected override void Update(GameTime gameTime)
    {
    // Allows the game to exit
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
    ButtonState.Pressed)
    this.Exit();
    KeyboardState keyState = Keyboard.GetState();
    GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
    if (gameState == GameState.TitleScreen)
    {
    if (keyState.IsKeyDown(Keys.Space) ||
    gamepadState.Buttons.A == ButtonState.Pressed)
    {
    StartNewGame();
    gameState = GameState.Playing;
    }
    }
    if (gameState == GameState.Playing)
    {
    player.Update(gameTime);
    LevelManager.Update(gameTime);
    if (player.Dead)
    {
    if (player.LivesRemaining > 0)
    {
    gameState = GameState.PlayerDead;
    deathTimer = 0.0f;
    }
    else
    {
    gameState = GameState.GameOver;
    deathTimer = 0.0f;
    }
    }
    }
    if (gameState == GameState.PlayerDead)
    {
    player.Update(gameTime);
    LevelManager.Update(gameTime);
    deathTimer += elapsed;
    if (deathTimer > deathDelay)
    {
    player.WorldLocation = Vector2.Zero;
    LevelManager.ReloadLevel();
    player.Revive();
    gameState = GameState.Playing;
    }
    }
    if (gameState == GameState.GameOver)
    {
    deathTimer += elapsed;
    if (deathTimer > deathDelay)
    {
    gameState = GameState.TitleScreen;
    }
    }
    base.Update(gameTime);
    }
    
  6. Replace the Draw() method with the following:
    protected override void Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.Black);
    spriteBatch.Begin(
    SpriteSortMode.BackToFront,
    BlendState.AlphaBlend);
    if (gameState == GameState.TitleScreen)
    {
    spriteBatch.Draw(titleScreen, Vector2.Zero, Color.White);
    }
    if ((gameState == GameState.Playing) ||
    (gameState == GameState.PlayerDead) ||
    (gameState == GameState.GameOver))
    {
    TileMap.Draw(spriteBatch);
    player.Draw(spriteBatch);
    LevelManager.Draw(spriteBatch);
    spriteBatch.DrawString(
    pericles8,
    "Score: " + player.Score.ToString(),
    scorePosition,
    Color.White);
    spriteBatch.DrawString(
    pericles8,
    "Lives Remaining: " + player.LivesRemaining.ToString(),
    livesPosition,
    Color.White);
    }
    if (gameState == GameState.PlayerDead)
    {
    }
    if (gameState == GameState.GameOver)
    {
    spriteBatch.DrawString(
    pericles8,
    "G A M E O V E R !",
    gameOverPosition,
    Color.White);
    }
    spriteBatch.End();
    base.Draw(gameTime);
    }
    
  7. Execute the Gemstone Hunter game!

What just happened?

Much as we did in our previous games, we defined a limited set of game states, beginning the game in TitleScreen mode. The Update() and Draw() methods are segmented to take different actions based on the current gameState value.

Non-interactive game states (PlayerDead and GameOver) are controlled by our standard timing mechanism, allowing the game to advance after a preset period of time has elapsed (five seconds in this case).

Have a go hero -

Of all of the games presented in this book, Gemstone Hunter is perhaps the most open for customization and expansion. Here are just a handful of suggestions for implementing enhancements to Gemstone Hunter based on things you have learned building the games in this book:

  • There are three other types of monster sprites included with the Platform Starter Kit. Modify the Enemy class to randomly select a monster type when a monster is spawned.
  • Alternatively, modify the Enemy type to accept an additional parameter indicating which of the four types of monsters should be spawned, and create new codes in the Level Editor for each different type of monster. You can then specify exactly which type of monster you wish to appear in each location.
  • As with Robot Rampage, Gemstone Hunter is currently silent. Add the sound system from Asteroid Belt Assault to Gemstone Hunter and generate appropriate sound effects for things like picking up gems and squishing zombies.
  • Expand on the tile images provided with Gemstone Hunter to add items such as spiked pits and background details such as clouds, hills, and roots for underground areas.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.12.172