Как реализовать механику ускорения змейки?

Пишу Змейку с использованием SFML, она у меня состоит из вектора прямоугольников sf::Rectangleshape. Реализовал движение, однако оно нормально работает, только если скорость равна размеру одной части змейки. При уменьшении - змея сужается, при ускорении - разъединяется. Я понял, что это происходит, ибо при движении у меня каждый сегмент меняет координаты с тем, что стоит впереди него, но не могу придумать, как исправить.

Snake.h

#include <SFML/Graphics.hpp>
#include <vector>
#include <string>

class Snake
{
private:
    int length = 15;
    sf::Vector2f size{ 20.f, 20.f };
    sf::Vector2f velocity{ 0.f, 0.f };
    float acceleration = 20;
    std::string direction;
    std::vector<sf::RectangleShape> snakeBody;

public:
    Snake(sf::RenderWindow& window);
    void snakeMove(sf::RenderWindow& window);
    void snakeUpdate();
    void drawSnake(sf::RenderWindow& window);
};

Snake.cpp

Snake::Snake(sf::RenderWindow& window)
{
    for (int bodypart = 0; bodypart < length; bodypart++)
    {
        sf::RectangleShape bp{ size };
        bp.setPosition({ float(window.getSize().x) / 2, float(window.getSize().y) / 2 });
        bp.setFillColor(sf::Color::Green);
        bp.setOutlineColor(sf::Color::Red);
        bp.setOutlineThickness(3.f);
        direction = "Up";
        velocity = {0.f, -acceleration};
        snakeBody.push_back(bp);
    }
}

void Snake::snakeMove(sf::RenderWindow& window)
{
    sf::RectangleShape newHead = snakeBody[0];
    newHead.move(velocity);
    //Check Borders;
    if (newHead.getPosition().x < 0) 
    {
        newHead.setPosition({ 0.f, snakeBody[0].getPosition().y});
    }
    else if (newHead.getPosition().x  > window.getSize().x - size.x)
    {
        newHead.setPosition({ window.getSize().x - size.x, snakeBody[0].getPosition().y });
    }
    else if (newHead.getPosition().y < 0)
    {
        newHead.setPosition({ snakeBody[0].getPosition().x, 0.f});
        
    }
    else if (newHead.getPosition().y  > window.getSize().y - size.y)
    {
        newHead.setPosition({snakeBody[0].getPosition().x, window.getSize().y - size.y});
    }


    for (int i = snakeBody.size() - 1; i > 0; i--)
    {
        float newPosX = snakeBody[i - 1].getPosition().x;
        float newPosY = snakeBody[i - 1].getPosition().y;
        snakeBody[i].setPosition({newPosX, newPosY});
    }
    snakeBody[0] = newHead;
}

void Snake::snakeUpdate() 
{
    //Define direction and velocity values
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && direction != "Down")
    {
        direction = "Up";
        velocity = { 0.f, -acceleration };
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S) && direction != "Up")
    {
        direction = "Down";
        velocity = { 0.f, acceleration };
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A) && direction != "Right")
    {
        direction = "Left";
        velocity = { -acceleration, 0.f };
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D) && direction != "Left")
    {
        direction = "Right";
        velocity = { acceleration, 0.f };
    }
}

void Snake::drawSnake(sf::RenderWindow& window) 
{
    for (const auto bodypart : snakeBody) 
    {
        window.draw(bodypart);
    }
}

Ответы (0 шт):