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

Author Topic: Text not being drawn to screen  (Read 2183 times)

0 Members and 1 Guest are viewing this topic.

xx_Dan_xx

  • Newbie
  • *
  • Posts: 4
    • View Profile
Text not being drawn to screen
« on: December 03, 2014, 07:38:46 pm »
Hi, I started my first year of C++ at university and I have been messing around with the SFML library. I am trying to create a Tic Tac Toe game but my text isn't being drawn to screen but the board is. The text has been set and the position is correct but no text appears. Well the text appears for a fraction of a second then disappears

Please bare in mind I only started to learn C++ in October so forgive me if I am not doing things the best way.

Here's my code:

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

using namespace std;
using namespace sf;

RectangleShape GameTile[3][3];
Text GameText[12];

void createTextProperties(string sPlayer1, string sPlayer2)
{
        int X = 300; // Start X,Y of the Text
        int Y = 10;

        // Loops through the Text array setting properties
        for(int i = 0; i < 12; i++)
        {
                GameText[i].setCharacterSize(24);
                GameText[i].setColor(Color::Red);
        }

        // Set position of all text except the Tile counter text
        for(int i = 0; i < 3; i++)
        {
                GameText[i].setPosition(Vector2f(X,Y));
                // Seperate position of Player's Name and Turn Name
                if(i == 1)
                {
                        Y = Y + 100;
                }
                else
                {
                        Y = Y + 25;
                }
        }

        // Set String values
        GameText[0].setString("X Player 1: " + sPlayer1); // Player's name and their counter
        GameText[1].setString("O Player 2: " + sPlayer2);
        GameText[2].setString(sPlayer1 + "'s turn"); // Always Player 1's turn first
}

void createTileProperties()
{
        // Start Tile Position from Window Start
        int X = 10;
        int Y = 10;

        // Loop through each tile and set properties
        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 3; j++)
                {
                        GameTile[i][j].setSize(Vector2f(50,50));
                        GameTile[i][j].setPosition(Vector2f(X,Y));
                        GameTile[i][j].setOutlineThickness(1);
                        GameTile[i][j].setOutlineColor(Color::Black);
                        X = X + 50;
                }
                        Y = Y + 50;
                        X = 10;
        }
}

void loadFont(Font &font)
{
        if (!font.loadFromFile("arial.ttf"))
        {
                cout << "Error loading the font. Make sure the font files are in the project directory." << endl;
        }
}

void drawGameObjects(RenderWindow &GameWindow, string sPlayer1, string sPlayer2)
{
        Font font;
        createTextProperties(sPlayer1, sPlayer2);
       
        GameWindow.clear(Color::White);
        // Draw Game Tiles -- Make sure this code is below the Draw Game Text for the z-order
        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 3; j++)
                {
                        GameWindow.draw(GameTile[i][j]);
                }
        }
       
        // Draw Game Text
        for(int i = 0; i < 12; i++)
        {
                loadFont(font);
                GameText[i].setFont(font);
                GameWindow.draw(GameText[i]);
        }
}

void createGame(string sPlayer1, string sPlayer2)
{
        RenderWindow GameWindow(VideoMode(600,400), "Tic Tac Toe");
        bool isGameRunning = true; // The Game Loop condition - Is a game in session?
        Font font;

        // Functions to happen once
        // Set Text & Tile Properties
        createTileProperties();
        createTextProperties(sPlayer1, sPlayer2);

        while(isGameRunning == true)
        {
                // Loop through events

#pragma region Window Events
        Event event;
        while (GameWindow.pollEvent(event))
        {
                if (event.type == Event::Closed)
                {
                        GameWindow.setVisible(false);
                }
        }  
#pragma endregion

                drawGameObjects(GameWindow, sPlayer1, sPlayer2);
               
                string s = GameText[0].getString();
                cout << s << " " << GameText[0].getPosition().x << " " << GameText[0].getPosition().y << endl;

                GameWindow.display(); // Draw everything to screen
       
               


               
        }
}

#pragma region Main Function
int main() {
        string sPlayer1; // Variable for holding Player 1's name
        string sPlayer2; // Variable for holding Player 2's name
        // Welcome Message -- Get their names via User input
        cout << "Welcome to Tic Tac Toe!" << endl << endl << "Please enter Player 1's (X) name: ";
        cin >> sPlayer1;
        cout << "Please enter Player 2's (O) name: ";
        cin >> sPlayer2;

        // Start the Game
        createGame(sPlayer1, sPlayer2);
        system("pause");
        return 0;
}  
#pragma endregion
 

Note: the string s in the game loop was just me troubleshooting the problem.
« Last Edit: December 03, 2014, 07:47:39 pm by xx_Dan_xx »

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Text not being drawn to screen
« Reply #1 on: December 03, 2014, 07:48:43 pm »
This
 loadFont(font);
 GameText[i].setFont(font);
must be out of any loop, in "createTextProperties". But GameText must be drawed in every render loop: GameWindow.draw(GameText[ i ]);

xx_Dan_xx

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Text not being drawn to screen
« Reply #2 on: December 03, 2014, 07:51:09 pm »
This
 loadFont(font);
 GameText[i].setFont(font);
must be out of any loop, in "createTextProperties". But GameText must be drawed in every render loop: GameWindow.draw(GameText[ i ]);

Hm ok but dont I need the setFont inside a loop so every text element has its font set to Arial?

Edit: Ok I seem have to fixed the problem by merging the loadFont function into the drawGameObjects function? Which I don't understand as the code only throws an error if it doesnt load it right?
« Last Edit: December 03, 2014, 08:00:17 pm by xx_Dan_xx »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Text not being drawn to screen
« Reply #3 on: December 03, 2014, 09:26:17 pm »
Basically, you should only create one sf::Font object for each font you want to use, and only create it once (not recreate it every single frame).  If multiple sf::Text objects should use the same font, just make them use the same font, don't try to load a new one every time (which isn't what your code does, but it seems to be what you think it's doing).

To be more concrete, in your initialization code, ie the code that runs exactly once at the beginning, you need to declare your sf::Font object (or a class with an sf::Font member or something like that), and call .loadFromFile() on it.  Then, in your game loop, ie the code that runs every single frame, which processes events and does clear/draw/delete, you must call draw() on every sf::Text object (and other drawables) that you want to see on the screen.

Whether the sf::Text objects should be created and positioned during initialization or in the game loop depends on whether they're going to change from frame to frame.  From what I saw skimming through your code, they don't change at all right now, but if you expect them to be changing in the future it's reasonable to have them in the game loop.