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

Author Topic: Use console and the game window at the same time  (Read 1444 times)

0 Members and 1 Guest are viewing this topic.

JohnSnow007

  • Newbie
  • *
  • Posts: 15
    • View Profile
Use console and the game window at the same time
« on: October 19, 2020, 10:58:27 pm »
Hi, I'm a new programmer and I have made this hangman game. I am trying to make the user input at the console and the animation to move on the game window simultaneously.

However, when the user is needed to make an input for the console, the game window only shows the first still sprite image and animate through the row.

void DrawHangman(Animation& animation, sf::RenderWindow& window, sf::Clock& clock, float& deltaTime, int totalWrong)
{
        deltaTime += clock.getElapsedTime().asSeconds();
        clock.restart();

        if (deltaTime >= 0.25f)
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }
                }

                animation.update(deltaTime, totalWrong);

                window.clear();
                animation.draw(window);
                window.display();

                deltaTime = 0.0f;
        }
}

int main()
{
        unsigned int videoWidth{ 900 };
        unsigned int videoHeight{ 500 };
       
        sf::RenderWindow window(sf::VideoMode(videoWidth, videoHeight), "Skipping");

        Animation skipper(std::string("Sprites/blueskipper.png"), 4, 4, sf::Vector2f(200, 220));

        float deltaTime{ 0.0f };

        sf::Clock clock;
       
        // Picks a random word from wordlist.txt
        WordMap word;
        const std::string wordToGuess = word.getRandomWord();
        Game game(wordToGuess);


        while (window.isOpen())
        {
                //Draw sprite
                DrawHangman(skipper, window, clock, deltaTime, game.get_CurrentWrongLetters());
               
                // Main game that happens in console
                if (!game.playGame())
                        break;
        }
        return 0;
}

This is the playGame() function.
bool Game::playGame()
{
    system("cls");
    std::cout << "Guessed Letters: " << guessedLetters << '\n';
    std::cout << progress;

    char guess = getGuess();
    IsContains(guess);
    return ((wrongLetters < maxWrongGuesses) && (progress != word));
}

update function
void Animation::update(float deltaTime, int totalWrong)
{
        m_timeTaken += deltaTime;
        if (m_timeTaken >= 0)
        {
                m_source.x++;
               
                if (m_source.x >= m_column)
                {
                        m_source.y++;
                        m_source.x = 0;
                }
                if (m_source.y >= totalWrong)
                        m_source.y = 0;
        }
}
 

Example of what happens:
It will show this on console
[console]
Guessed Letters: a12
___a____
Enter letter:

[game window]
Still image of the first sprite.

However when I tried
while (game.playGame())
        {
                while (window.isOpen())
                        DrawHangman( skipper, window, clock, deltaTime, game.get_CurrentWrongLetters() );
        }
 

It does the complete opposite. The game window will have the sprite animated, but won't allow inputs for the console.

I understand why they both don't work but I just can't figure how animate in the game window while the console is active too.
« Last Edit: October 20, 2020, 06:18:37 pm by JohnSnow007 »

JohnSnow007

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: Use console and the game window at the same time
« Reply #1 on: October 20, 2020, 06:02:11 pm »
Ok I looked into threads and this the change I made
//in main()
        bool threadRunning{ true };
        sf::Thread thread([&game, &threadRunning]() {
                while (threadRunning)
                        threadRunning = game.playGame();
        }
        );

        thread.launch();


        while (window.isOpen())
        {

                if (!threadRunning)
                {
                        thread.wait();
                        break;
                }

                DrawHangman(skipper, window, clock, deltaTime, game.get_TotalWrongLetters());
        }

        return 0;
 

It works as how I intended it to be. However it feels incredibly messy. What could I improve on it?
« Last Edit: October 21, 2020, 02:16:25 am by JohnSnow007 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Use console and the game window at the same time
« Reply #2 on: October 21, 2020, 02:52:04 pm »
You can't easily use both at once. Console input is a blocking operation, while rendering something needs a continued operation.

Personally, I suggest to just create your own small text input field with SFML. You can get text input with the TextEntered event.

Alternatively,  but this might be even more complex, is to use an existing GUI library, like Imgui-SFML.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/