官术网_书友最值得收藏!

Building the game class

We've done a good job at wrapping up the basic functionality of our window class, but that's not the only chunk of code in need of refactoring. In Chapter 1, It's Alive! It's Alive! – Setup and First Program, we've discussed the main game loop and its contents, mainly processing input, updating the game world and the player, and finally, rendering everything on screen. Cramming all of that functionality into the game loop alone is generally known to produce spaghetti code, and since we want to move away from that, let's consider a better structure that would allow this kind of behavior:

#include "Game.h"

void main(int argc, void** argv[]){
    // Program entry point.
    Game game; // Creating our game object.
    while(!game.GetWindow()->IsDone()){
        // Game loop.
        game.HandleInput();
        game.Update();
        game.Render();
    }
}

The code above represents the entire content of our main.cpp file and perfectly illustrates the use of a properly structured game class, which doesn't go beyond calling the proper methods in the right order in an endless loop until the window is closed. Just for the sake of clarity, let's take a look at a simplified version of the game class header:

class Game{
public:
    Game();
    ~Game();

    void HandleInput();
    void Update();
    void Render();
    Window* GetWindow();
    ...
private:
    void MoveMushroom();
    Window m_window;
    ...
};

Note that the game class holds an instance of our window. It can be done differently, but for our current needs this will more than suffice.

Putting our code to work

We're now ready to re-implement the bouncing mushroom demo from Chapter 1, It's Alive! It's Alive! – Setup and First Program. Given how simple it is, we'll walk you through the entire process of adapting our previously written code to our new structure. Let's begin by setting up our window and graphics we'll be using:

Game::Game(): m_window("Chapter 2", sf::Vector2u(800,600)){
    // Setting up class members.
    m_mushroomTexture.loadFromFile("Mushroom.png");
    m_mushroom.setTexture(m_mushroomTexture);
    m_increment = sf::Vector2i(4,4);
}

Because we have nothing to clean up, our game destructor will remain empty for now:

Game::~Game(){}

We have no need to check for input for this example, so let's leave that method alone for now. What we will be doing, however, is updating the position of our sprite each frame:

void Game::Update(){
    m_window.Update(); // Update window events.
    MoveMushroom();
}
void Game::MoveMushroom(){
   sf::Vector2u l_windSize = m_window.GetWindowSize();
   sf::Vector2u l_textSize = m_mushroomTexture.getSize();

   if((m_mushroom.getPosition().x >
      l_windSize.x - l_textSize.x&&m_increment.x> 0) ||
      (m_mushroom.getPosition().x < 0 &&m_increment.x< 0)){
         m_increment.x = -m_increment.x;
   }

   if((m_mushroom.getPosition().y >
      l_windSize.y - l_textSize.y&&m_increment.y> 0) ||
      (m_mushroom.getPosition().y < 0 &&m_increment.y< 0)){
         m_increment.y = -m_increment.y;
   }

   m_mushroom.setPosition(
      m_mushroom.getPosition().x + m_increment.x, 
      m_mushroom.getPosition().y + m_increment.y);
}

Literally the first thing you'll probably notice is the update method call of our window class. We've already covered the importance of event processing in SFML, but it's still worthy to note that one more time. The rest of the code is pretty much the same, except we now have a separate method that is responsible for updating the position of the mushroom sprite. We used two local variables to hold the window and texture sizes in order to increase readability, but that's about it. Time to draw our sprite to the screen:

void Game::Render(){
    m_window.BeginDraw(); // Clear.
    m_window.Draw(m_mushroom);
    m_window.EndDraw(); // Display.
}

Once again, the code is fairly straight forward. Our window class does all the work, and all we have to do is call the Draw method and pass in our sf::Drawable right in between the wrapper methods for clearing the screen and displaying the changes.

Putting everything together and running it should produce the exact same bouncing mushroom we had back in Chapter 1, It's Alive! It's Alive! – Setup and First Program. However, you may have noticed that the sprite moves differently based on how busy your computer is. In this observation lies an important lesson about game development.

主站蜘蛛池模板: 宿州市| 包头市| 水城县| 房山区| 固安县| 兴业县| 吴川市| 龙川县| 德清县| 太仆寺旗| 黄石市| 林州市| 肥乡县| 澳门| 恩施市| 上高县| 体育| 南陵县| 新河县| 丹江口市| 宁南县| 施甸县| 东乡| 泊头市| 湖州市| 延庆县| 滕州市| 云南省| 古田县| 东安县| 固阳县| 兴海县| 盐亭县| 皋兰县| 刚察县| 库伦旗| 石台县| 太康县| 宁波市| 东莞市| 京山县|