SFML community forums
Help => Graphics => Topic started by: TrampolineGames 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()
#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. ^_^
-
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:
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.
-
I have this now, but whenever I run it the game crashes.
#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;
}
-
Your main loop should have the following structure
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
while (App.GetEvent(Dialogue1))
you will empty the event queue leaving no events left for when you call
while (App.GetEvent(GameClose))
The event loop you can write something like this
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
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.
-
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.