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

Time to integrate

Much like how a hammer is useless without someone using it, so are our two classes without being properly adopted by the Game class. Since we didn't write all that code just to practise typing, let's work on putting all the pieces together. First, we need to actually add two new members to the Game class, and you might already have guessed what they are:

class Game{
...
private:
...
    World m_world;
    Snake m_snake;
};

Next, let's initialize these members. Since both of them have constructors that take arguments, it's the time for initializer list:

Game::Game(): m_window("Snake", sf::Vector2u(800, 600)),m_snake(m_world.GetBlockSize()),m_world(sf::Vector2u(800,600))
{
    ...
}

Next, we need to process some input. As you may recall from the previous chapters, utilizing events for live input is really delayed and should never be used for anything else but checking for key presses that aren't time sensitive. Luckily, SFML provides means of obtaining the real-time state of the keyboard through the sf::Keyboard class. It only contains the static functions and is never meant to be initialized. One of those functions is exactly what we need here: isKeyPressed(sf::Keyboard::Key). The sole argument that it takes is the actual key you want to check the state of, which can be obtained through the use of the sf::Keyboard::Key enumeration, as follows:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) 
   && m_snake.GetDirection() != Direction::Down)
{
   m_snake.SetDirection(Direction::Up);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) 
   && m_snake.GetDirection() != Direction::Up)
{
   m_snake.SetDirection(Direction::Down);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) 
   && m_snake.GetDirection() != Direction::Right)
{
   m_snake.SetDirection(Direction::Left);
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) 
   && m_snake.GetDirection() != Direction::Left)
{
   m_snake.SetDirection(Direction::Right);
}

Something we don't want the snake to do is to go in the direction that is opposite to its current one. At any given time, there should only be three directions it can go in, and the use of the GetDirection() method ensures that we don't send the snake in reverse, essentially eating itself. If we have the proper combination of input and its current direction, it's safe to adjust its direction through the use of the SetDirection() method.

Let's get things moving by updating both our classes:

void Game::Update(){
...
    float timestep = 1.0f / m_snake.GetSpeed();

    if(m_elapsed >= timestep){
        m_snake.Tick();
        m_world.Update(m_snake);
        m_elapsed -= timestep;
        if(m_snake.HasLost()){
            m_snake.Reset();
        }
    }
...
}

As mentioned previously, we're using fixed time-step here, which incorporates the snake speed in order to update the appropriate amount of times per second. This is also where we check if the player has lost the game and reset the snake if he has.

We're really close now. Time to draw everything on screen:

void Game::Render(){
    m_window.BeginDraw();
    // Render here.
    m_world.Render(*m_window.GetRenderWindow());
    m_snake.Render(*m_window.GetRenderWindow());

    m_window.EndDraw();
}

Much like before, we simply invoke the Render methods of both our classes and pass in a reference to sf::RenderWindow. With that, our game is actually playable! Upon successful compilation and execution of our project, we should end up with something looking like this following image:

The snake will be still at first, until one of the four arrow keys is pressed. Once it does start moving, it will be able to eat the apple and grow by one segment, collide with its own tail and lose it twice before it dies, and end the game if the player crashes into a wall. The core version of our game is complete! Pat yourself on the back, as you just created your first game.

主站蜘蛛池模板: 綦江县| 从江县| 祥云县| 玉屏| 会宁县| 栾川县| 昂仁县| 香格里拉县| 肃南| 屏边| 昌江| 黔西县| 嘉义县| 五大连池市| 龙海市| 汤阴县| 行唐县| 临漳县| 华蓥市| 炎陵县| 孝义市| 崇礼县| 东乡县| 布尔津县| 扶风县| 樟树市| 巴彦县| 西盟| 丰顺县| 德昌县| 凤城市| 滦平县| 台江县| 新密市| 德钦县| 上犹县| 新沂市| 板桥市| 舟山市| 黔西| 绥棱县|