Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Flickering movement from drawing rectangleshape for snake game  (Read 1006 times)

0 Members and 1 Guest are viewing this topic.

JohnSnow007

  • Newbie
  • *
  • Posts: 15
    • View Profile
Flickering movement from drawing rectangleshape for snake game
« on: November 14, 2020, 01:19:25 am »
I keep getting weird flickering when it's draws the movement for the snake.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <deque>
#include <cassert>
#include <random>
#include <ctime>

constexpr int PIXEL_WIDTH{ 32 };
constexpr int PIXEL_HEIGHT{ 32 };
constexpr int SCREEN_WIDTH{ 800 };
constexpr int SCREEN_HEIGHT{ 600 };
constexpr int MAP_WIDTH{ SCREEN_WIDTH / PIXEL_WIDTH };
constexpr int MAP_HEIGHT{ SCREEN_HEIGHT / PIXEL_HEIGHT };


class Snake
{
private:
        std::deque<sf::Vector2f> m_snake{ sf::Vector2f(10, 10), sf::Vector2f(9, 10), sf::Vector2f(8, 10) };

        sf::RectangleShape m_cell{ sf::Vector2f(MAP_WIDTH, MAP_HEIGHT) };

        bool growing{ false };
public:
        Snake()
        {
                m_cell.setFillColor(sf::Color::Green);
        }

        Snake(const Snake& snake) = delete;

        ~Snake()
        {
        }
       
        void move(sf::Vector2f goToPos)
        {
                if (!growing)
                        m_snake.pop_back();

                growing = false;

                m_snake.emplace_front(goToPos);
        }

        void draw(sf::RenderWindow& window)
        {
                for (auto& body : m_snake)
                {
                        m_cell.setPosition(body.x * MAP_WIDTH, body.y * MAP_HEIGHT);
                        window.draw(m_cell);
                }
        }

        sf::Vector2f& operator[](int index)
        {
                assert(index >= 0 && index < m_snake.size());
                return m_snake[index];
        }

        std::deque<sf::Vector2f> getSnake() { return m_snake; }
};


void changeDirections(Snake& snake, const Directions& d)
{
        switch (d)
        {
        case Directions::UP:
                snake.move(sf::Vector2f(snake[0].x, snake[0].y - 1));
                break;
        case Directions::DOWN:
                snake.move(sf::Vector2f(snake[0].x, snake[0].y + 1));
                break;
        case Directions::LEFT:
                snake.move(sf::Vector2f(snake[0].x - 1, snake[0].y));
                break;
        case Directions::RIGHT:
                snake.move(sf::Vector2f(snake[0].x + 1, snake[0].y));
                break;
        default:
                break;
        }
}


int main()
{
        sf::RenderWindow window{ sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Snake" };

        sf::Event event{};

        float timeTaken{ 0.0f };
        const float TIME_PER_UPDATE{ 0.5f };
        // Timer starts here
        sf::Clock clock;

        std::vector<int> grid(MAP_WIDTH * MAP_HEIGHT);
        bool GameStart{ true };
        Snake snake{};

        for (int i{ 0 }; i < 10; ++i)
        {
                int value = getRandomNumber(grid.size() - 1);
                std::cout << value << '\n';
                grid[value] = -1;
        }

        Directions state{ Directions::RIGHT };
        while (window.isOpen())
        {
                timeTaken += clock.getElapsedTime().asSeconds();
                clock.restart();

                while (TIME_PER_UPDATE <= timeTaken)
                {
                        timeTaken -= TIME_PER_UPDATE;
                        while (window.pollEvent(event))
                        {
                                switch (event.type)
                                {
                                case sf::Event::Closed:
                                        window.close();
                                        break;
                                case sf::Event::KeyPressed:
                                        switch (event.key.code)
                                        {
                                        case sf::Keyboard::Up:
                                                state = Directions::UP;
                                                break;
                                        case sf::Keyboard::Down:
                                                state = Directions::DOWN;
                                                break;
                                        case sf::Keyboard::Left:
                                                state = Directions::UP;
                                                break;
                                        case sf::Keyboard::Right:
                                                state = Directions::RIGHT;
                                                break;
                                        default:
                                                break;
                                        }
                                        break;
                                }
                        }

                        window.clear(sf::Color::Black);
                        changeDirections(snake, state);
                        snake.draw(window);
                }
                window.display();

        }
        return 0;
}
 

I also tried implementing sprite with IntRect but nothing was shown. What could I use or improve to remove the flickering? If you run the code, you'll see what I mean.

Stauricus

  • Sr. Member
  • ****
  • Posts: 369
    • View Profile
    • A Mafia Graphic Novel
    • Email
Re: Flickering movement from drawing rectangleshape for snake game
« Reply #1 on: November 14, 2020, 03:46:57 am »
clearing and drawing to the window should be done every loop. you have this:
window.clear(sf::Color::Black);
changeDirections(snake, state);
snake.draw(window);
inside this while loop:
while (TIME_PER_UPDATE <= timeTaken)
meaning that the window will be cleared and the snake drawn only when this loop runs, which isn't every time. try to move window.clear(sf::Color::Black); and snake.draw(window); to just above window.display();, like this:

                        changeDirections(snake, state)
                }
window.clear(sf::Color::Black);
snake.draw(window);
window.display();
« Last Edit: November 14, 2020, 03:50:07 am by Stauricus »
Visit my game site (and hopefully help funding it? )
Website | IndieDB