Making a splash

A splash menu adds a touch of class to your game and also does a little bragging. Typically, the splash screen shows off your company logo. In fact, many game projects have multiple studios that work on them, so there are often multiple splash screens. We will use just one!

It is important to get the splash screen up and running as soon as possible, so we will do that before we perform any other loading. Part of the function of a splash screen is to give the player something pretty to look at while the rest of the game is loading.

Creating the splash screen

It's up to you to create a splash screen that defines your game. For convenience, we have included one in the code resource package for this chapter called splash.png. Make sure you copy splash.png into your project. The only requirement for the splash image is that it is 800 x 600 pixels, the same resolution as our game screen.

Defining the splash screen

As with all images in this game, we will implement the splash screen as a sprite. Declare the splash sprite at the top of RoboRacer2D.cpp:

Sprite* splashScreen;

We also want to define some timers for the splash screen:

float splashDisplayTimer;
float splashDisplayThreshold;

As we want to define the splash screen separately, we will create a separate function just to load it. Create the LoadSplash function using the following code:

void LoadSplash()
{
  m_gameState = GameState::GS_Splash;
  
  splashScreen = new Sprite(1);
  splashScreen->SetFrameSize(800.0f, 600.0f);
  splashScreen->SetNumberOfFrames(1);
  splashScreen->AddTexture("resources/splash.png", false);
  splashScreen->IsActive(true);
  splashScreen->IsVisible(true);
}

We are not going to make a significant change to the StartGame function. We are going to only load the splash screen, and defer loading the other game resources. This will get our splash screen up as soon as possible. Change the StartGame function so that it looks like the following code:

void StartGame()
{
 LoadSplash();
 inputManager = new Input(hWnd);

 uiTimer = 0.0f;
 srand(time(NULL));

 pickupSpawnThreshold = 3.0f;
 pickupSpawnTimer = 0.0f;

 enemySpawnThreshold = 7.0f;
 enemySpawnTimer = 0.0f;

 splashDisplayTimer = 0.0f;
 splashDisplayThreshold = 5.0f;

}

Notice that we only load the splash resources and set a few variables here. We also set the splash timer so that it will show up for at least five seconds.

Next, modify the GS_Splash case in the Update function to look like the following code:

 switch (m_gameState)
 {
 case GameState::GS_Splash:
 case GameState::GS_Loading:
 {
  splashScreen->Update(p_deltaTime);
  splashDisplayTimer += p_deltaTime;
  if (splashDisplayTimer > splashDisplayThreshold)
  {
   m_gameState = GameState::GS_Menu;
  }
 }
 break;

This code updates the splash timer. When the timer exceeds our threshold, then the game state changes to GS_Menu. We will define the code to load the next menu.

Modify the GS_Splash case in the Render function to look like the following code:

case GameState::GS_Loading:
splashScreen->Render();
break;

Tip

As the splash sprite is only a static image, you may wonder why we update the splash sprite. While an update has no effect on our current code, consider a case where I wanted to implement a dynamic, animated splash screen.

Loading our resources

If you have been paying attention, then you should realize that we removed the LoadTextures call from the StartGame function. Instead, we are going to load the textures in the GameLoop function. Change GameLoop so that it looks like the following code:

void GameLoop(const float p_deltatTime)
{
  if (m_gameState == GameState::GS_Splash)
  {
    LoadTextures();
    m_gameState = GameState::GS_Loading;
  }
  Update(p_deltatTime);
  Render();
}

If you recall, GameLoop is called every frame. We need GameLoop to be running to display our splash screen, which we have already loaded. But on the first call to GameLoop, we haven't loaded our other resources.

We check to see whether our game state is GS_Splash. If it is, we call load textures, and immediately change the game state to GS_Loading. If we didn't change the game state, then the game would attempt to load the textures every frame, which would be a very bad thing! This is another practical example of why we define different game states in our state machine.

Tip

In a way, we haven't created a true splash screen. That is because our splash still depends on Windows and OpenGL initializing before the splash screen can even be loaded and rendered. True splash screens use a snippet of code that does not depend on all of this initialization so that they can load before everything else. Unfortunately, that level of detail is beyond the scope of our book. Sometimes, the splash screen will run on a separate thread so that it is independent of the startup code.

Loading our resources

When you run the game now, you should see the splash screen display, but then nothing else happens. This is because we changed the game state to GS_Menu in the Update function, and we have not coded for that game state yet! If you want to test your splash screen, change m_gameState = GameState::GS_Menu to m_gameState = GameState::GS_Running in the Update function. Just don't forget to change it back before you move on.

Tip

The ability to change your game state allows you to reroute the flow of your game. This is very useful, for example, when you are trying to code a new game state but you aren't ready to run it in the game yet. Once the new game state is coded, then you can wire it in.

..................Content has been hidden....................

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