Starting the Zombie Arena game engine

In this game, we will need a slightly upgraded game engine in main. In particular, we will have an enumeration called state which will track what the current state of the game is. Then, throughout main, we can wrap parts of our code so that different things happen in different states.

Right-click on the HelloSFML file in the Solution Explorer and select Rename. Change the name to ZombieArena.cpp. This will be the file that contains our main function and the code that instantiates and controls all our classes.

We begin with the now familiar main function and some include directives. Note the addition of an include directive for the Player class.

Add the code following to the ZombieArena.cpp file:

#include "stdafx.h" 
#include <SFML/Graphics.hpp> 
#include "Player.h" 
 
using namespace sf; 
 
int main() 
{ 
 
   return 0; 
} 

The previous code has nothing new in it except that the #include "Player.h" line means we can now use the Player class within our code.

Let's flesh out some more of our game engine. This next code does quite a lot. Be sure to read the comments when you add the code to get an idea of what is going on. We will then go through it in detail.

Add the highlighted code at the start of the main function:

int main() 
{ 
   // The game will always be in one of four states   
   enum class State 
   { 
     PAUSED, LEVELING_UP, GAME_OVER, PLAYING 
   };
  
   // Start with the GAME_OVER state
   State state = State::GAME_OVER;

   // Get the screen resolution and create an SFML window
   Vector2f resolution;
   resolution.x = VideoMode::getDesktopMode().width;
   resolution.y = VideoMode::getDesktopMode().height;

   RenderWindow window(VideoMode(resolution.x, resolution.y),
     "Zombie Arena", Style::Fullscreen);

   // Create a an SFML View for the main action
   View mainView(sf::FloatRect(0, 0, resolution.x, resolution.y));
   // Here is our clock for timing everything
   Clock clock;

   // How long has the PLAYING state been active
   Time gameTimeTotal;
   
   // Where is the mouse in relation to world coordinates
   Vector2f mouseWorldPosition;   

   // Where is the mouse in relation to screen coordinates
   Vector2i mouseScreenPosition;

   // Create an instance of the Player class
   Player player;

   // The boundaries of the arena
   IntRect arena;

   // The main game loop
   while (window.isOpen())
   {

   } 
 
   return 0; 
} 

Let's run through each section of the code that we just entered. Just inside the main function we have this code:

// The game will always be in one of four states 
enum class State { PAUSED, LEVELING_UP, GAME_OVER, PLAYING }; 
// Start with the GAME_OVER state 
State state = State::GAME_OVER; 

The previous code creates a new enumeration class called State. Then the code creates an instance of State called state. The state enumeration can now be one of four values, as defined in the declaration. Those values are PAUSED, LEVELING_UP, GAME_OVER, and PLAYING. These four values will be just what we need for keeping track and responding to the different states that the game can be in at any given time. Note that it is not possible for state to hold more than one value at a time.

Immediately after, we add the following code:

// Get the screen resolution and create an SFML window 
Vector2f resolution; 
resolution.x = VideoMode::getDesktopMode().width; 
resolution.y = VideoMode::getDesktopMode().height; 
RenderWindow window(VideoMode(resolution.x, resolution.y),  
   "Zombie Arena", Style::Fullscreen); 

The previous code declares a Vector2f called resolution. We initialize the two variables of resolution (x and y) by calling the VideoMode::getDesktopMode function for both width and height. The resolution object now holds the resolution of the monitor on which the game is running. The final line of code creates a new RenderWindow called window using the appropriate resolution.

This next code creates an SFML View object. The view is positioned (initially) at the exact coordinates of the pixels of the monitor. If we were to use this View to do some drawing in this current position it would have no effect whatsoever. However, we will eventually start to move this view to focus on the parts of our game world that the player needs to see. Then, when we start to use a second View that remains fixed (for the HUD), we will see how this View can track the action while the other remains static to display the HUD:

// Create a an SFML View for the main action 
View mainView(sf::FloatRect(0, 0, resolution.x, resolution.y)); 

Next, we create a Clock to do our timing and a Time object called gameTimeTotal that will keep a running total of the game time that has elapsed. As the project progresses we will introduce more variables and objects to handle timing:

// Here is our clock for timing everything 
Clock clock; 
// How long has the PLAYING state been active 
Time gameTimeTotal; 

The next code declares two vectors. One holding two floats, called mouseWorldPosition, and one holding two integers, called mouseScreenPosition. The mouse pointer is something of an anomaly because it exists in two different coordinate spaces. You could think of these as parallel universes if you like. First, as the player moves around the world we will need to keep track of where the crosshair is in that world. These will be floating point coordinates and will be stored in mouseWorldCoordinates. Of course the actual pixel coordinates of the monitor itself never change. They will always be 0,0 to horizontal resolution-1, vertical resolution-1. We will track the mouse pointer position relative to this coordinate space using the integers stored in mouseScreenPosition:

// Where is the mouse in relation to world coordinates 
Vector2f mouseWorldPosition; 
// Where is the mouse in relation to screen coordinates 
Vector2i mouseScreenPosition; 

Finally, we get to use our Player class. This line of code will cause the constructor function (Player::Player) to execute. Refer to Player.cpp if you want to refresh your memory about this function:

// Create an instance of the Player class 
Player player; 

This IntRect object will hold starting horizontal and vertical coordinates as well as a width and a height. Once initialized, we will be able to access the size and location details of the current arena with code such as arena.left, arena.top, arena.width, and arena.height:

// The boundaries of the arena 
IntRect arena; 

The last part of the code that we added previously is, of course, our main game loop:

// The main game loop 
while (window.isOpen()) 
{ 
 
} 

You have probably noticed that the code is getting quite long. Let's talk about this inconvenience.

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

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