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

Author Topic: Two questions.  (Read 2423 times)

0 Members and 1 Guest are viewing this topic.

TrampolineGames

  • Newbie
  • *
  • Posts: 4
    • View Profile
Two questions.
« on: September 05, 2011, 08:21:51 pm »
I'm trying to make a game in C++ similar to a visual novel, but I seem to be having a lot of trouble (this is my first game). I'm trying to make it so that whenever you hit enter a new sentence pops up. But whenever I hit enter, both pieces of text just flicker in front of each other. I also have a blue box that loads at the bottom of the screen. I've changed the text multiple times, and deleted the other string, but now the text won't load at all.

My other problem is that I think that if I keep developing the way I am, the whole game might just in the main.cpp file. I can't figure out a way to have the same objects over multiple files and because of that, all the text has to be written in the main file, so it can be displayed with App.Draw()

Code: [Select]
#include <SFML/Graphics.hpp>

int main(){
    sf::RenderWindow App(sf::VideoMode(1024, 768), "Game");

    //Loads the game font and images
    sf::Font GameFont;
    if (!GameFont.LoadFromFile("calist.ttf")) {
        return EXIT_FAILURE;
    }
    sf::Image TextBoxImage;
    sf::Sprite TextBox;
    if (!TextBoxImage.LoadFromFile("Blue.png")) {
        return EXIT_FAILURE;
    }
    TextBox.SetImage(TextBoxImage);
    TextBox.SetColor(sf::Color(0, 0, 255, 155));
    TextBox.SetPosition(0, 490.f);
    TextBox.Scale(1.6f, 1.6f);
   
    //Loads the game Text
    sf::String dia1a ("That piece of trash over there is Joey.", GameFont);
   
    //Game Loop
    while (App.IsOpened())
    {
        App.Clear();
        App.Draw(TextBox);
        App.Display();
    //Dialogue for level 1
        sf::Event Dialogue1;
        while (App.GetEvent(Dialogue1)) {
            if ((Dialogue1.Type == sf::Event::KeyPressed) && (Dialogue1.Key.Code == sf::Key::Escape)) {
                App.Draw(dia1a);
            }
        }
       
    //Close Game    
        sf::Event GameClose;
        while (App.GetEvent(GameClose)) {
            if (GameClose.Type == sf::Event::Closed)
                App.Close();
            }
        }
    return EXIT_SUCCESS;
}


If anyone knows any solutions to displaying new text when the enter key is pressed, or using objects over multiple header files, please let me know. ^_^

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Two questions.
« Reply #1 on: September 05, 2011, 08:33:13 pm »
You call "App.Draw(diala)" but you aren't displaying it (with App.Display).
I would use a bool (e.g. DrawText) and do something like this:
Code: [Select]
App.Clear();
App.Draw(Textbox);

if (DrawText)
    App.Draw(diala);

App.Display();

The only thing you have to do when the user presses enter is to make DrawText true.

If you use objects over multiple files then you will have to put everything in a class and put the class in a header.
TGUI: C++ SFML GUI

TrampolineGames

  • Newbie
  • *
  • Posts: 4
    • View Profile
Two questions.
« Reply #2 on: September 05, 2011, 09:00:44 pm »
I have this now, but whenever I run it the game crashes.

Code: [Select]
#include <SFML/Graphics.hpp>

int main(){
    sf::RenderWindow App(sf::VideoMode(1024, 768), "Game");

    //Loads the game font and images
    sf::Font GameFont;
    if (!GameFont.LoadFromFile("calist.ttf")) {
        return EXIT_FAILURE;
    }
    sf::Image TextBoxImage;
    sf::Sprite TextBox;
    if (!TextBoxImage.LoadFromFile("Blue.png")) {
        return EXIT_FAILURE;
    }
    TextBox.SetImage(TextBoxImage);
    TextBox.SetColor(sf::Color(0, 0, 255, 155));
    TextBox.SetPosition(0, 490.f);
    TextBox.Scale(1.6f, 1.6f);
   
    //Loads the game Text
    sf::String dia1a ("That piece of trash over there is Joey.", GameFont);
   
    //Game Loop
    while (App.IsOpened())
    {
        App.Clear();
        App.Draw(TextBox);
bool DrawText;
    //Dialogue for level 1
        if (DrawText) {
            App.Draw(dia1a);
App.Display();
}
        sf::Event Dialogue1;
        while (App.GetEvent(Dialogue1)) {
            if ((Dialogue1.Type == sf::Event::KeyPressed) && (Dialogue1.Key.Code == sf::Key::Escape)) {
                DrawText = true;
            }
        }
    //Close Game    
        sf::Event GameClose;
        while (App.GetEvent(GameClose)) {
            if (GameClose.Type == sf::Event::Closed)
                App.Close();
            }
        }
    return EXIT_SUCCESS;
}

sbroadfoot90

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Two questions.
« Reply #3 on: September 25, 2011, 01:56:30 am »
Your main loop should have the following structure


Code: [Select]

while(App.IsOpened()) {

   Loop through events
      Close if you need to
      display text if escape is pressed

   clear screen
   draw objects
   display screen
}


Currently you have two event loops.

By writing

Code: [Select]
while (App.GetEvent(Dialogue1))

you will empty the event queue leaving no events left for when you call

Code: [Select]
while (App.GetEvent(GameClose))

The event loop you can write something like this

Code: [Select]
while(App.GetEvent(event)) {
   if (event.Type == sf::Event::Closed) {
      App.Close();
   } else if ((event.Type == sf::Event::KeyPressed) && (event.Key.Code == sf::Key::Escape)) {
      drawText = true;
   }
}


After your event handling loop, you can write something like this


Code: [Select]

App.Clear();
App.Draw(TextBox);
if (drawText) App.Draw(diala);
App.Display();


To reiterate, your game loop should go something like this.

Handle events

Update all physics etc

Clear screen

Draw all relevant objects

Display screen

and you should only have one loop going through all the events, not a separate loop for each behaviour you are interested in. Think of the event stack like a stack of pancakes. When you call sf::RenderWindow.GetEvent(event), it returns the pancake on the top, and when you're done with it, you throw it in the bin. If you run two separate loops, all your pancakes will be in the bin when it comes around to you looping through the second time.

It seems you probably need to review your knowledge of C++ before you try to start making graphical games. Try making some simple command line games.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Two questions.
« Reply #4 on: September 25, 2011, 09:06:45 am »
Quote
Don't declare variables inside loops. Instead, you want to declare a single sf::Event object outside the main loop, and reuse it

The general rule is rather to construct a variable only when you need it, so as late as possible in the code. Declaring objects early and reusing them should only be done when it shows a significant performance improvement. With sf::Event it makes no difference at all: it's a POD type and thus it has no constructor.
Laurent Gomila - SFML developer