d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Sfml Game Issue
Add Reply New Topic New Poll
Member
Posts: 25,430
Joined: Apr 3 2008
Gold: 10.27
May 31 2016 02:33pm
My wife and I are making a game. We are stuck on another issue. The program works fine except how do we make it so if someone is asked what is your name?
They can't hit the letter Y or N to skip to the next question? Like I want when a question is asked, for only the keyboard presses to work while that slide is up. Any ideas?
Kind hard to explain my question. Here's our code:

Edited to more cleaned up version:

Code

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

using namespace std;

int main()
{
sf::Event event;
sf::Font font;
if (!font.loadFromFile("arialbd.ttf"))
{
cout << "Could not load the font";
}
sf::RenderWindow Window(sf::VideoMode(1200, 800), "Getting Text On The Screen");
sf::String sentence;
sf::Text text(sentence, font, 40);
text.setColor(sf::Color::Blue);
text.setFont(font);
text.setString("What is your name?");
while(Window.isOpen())
{
sf::Event Event;
while(Window.pollEvent(Event))
{
switch(Event.type)
{
case sf::Event::Closed:
Window.close();
break;
case sf::Event::TextEntered:
if(Event.text.unicode >= 32 &&Event.text.unicode <= 126)
sentence += (char)Event.text.unicode;
else if(Event.text.unicode == 8 && sentence.getSize() > 0)
sentence.erase(sentence.getSize() - 1, sentence.getSize());
text.setString(sentence);
break;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Return)){
text.setFont(font);
text.setString("It's nice to meet you Chris!\n Would you like to go on an adventure with me?\n\n Type 'Y' for yes or 'N' for no");
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Y)){
text.setFont(font);
text.setString("That's great news! Let's get started!");
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::N)){
text.setFont(font);
text.setString("Well that's no fun! I'll see you later.");
}
Window.clear(sf::Color::Black);
Window.draw(text);
Window.display();
}
}



This post was edited by EBAZ on May 31 2016 02:47pm
Member
Posts: 23,518
Joined: Aug 3 2011
Gold: 3,575.00
Jun 3 2016 12:50pm
Create a variable:

char character name;

cout << "Please enter character name" << endl;
cin << character name; << endl;

Something like this? If you want someone to enter a character name....
Member
Posts: 25,430
Joined: Apr 3 2008
Gold: 10.27
Jun 3 2016 02:17pm
Quote (Cocoo @ Jun 3 2016 12:50pm)
Create a variable:

char character name;

cout << "Please enter character name" << endl;
cin << character name; << endl;

Something like this? If you want someone to enter a character name....


I got the input output to work. Issue I'm having is how do I stop the program from skipping ahead? Say question one is a yes or no question and question 3 is a yes or no question. How do I make it so they can't put in yes and automatically have it jump to question 3 instead of going in sequence?

Here's new code I've tried using bools with partial successs:

Code

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

using namespace std;

bool phase1 = true;
bool phase2 = false;

int main()
{
sf::Event event;
sf::Font font;
if (!font.loadFromFile("arialbd.ttf"))
{
cout << "Could not load the font";
}
sf::RenderWindow Window(sf::VideoMode(900, 700), "Getting Text On The Screen");
sf::String sentence;
sf::Text text(sentence, font, 40);
text.setColor(sf::Color::Blue);
text.setFont(font);
text.setString("It's nice to meet you!\nWould you like to go on an adventure with me?\n\n Type 'Y' for yes or 'N' for no");
while(Window.isOpen())
{
sf::Event Event;
while(Window.pollEvent(Event))
{
switch(Event.type)
{
case sf::Event::Closed:
Window.close();
break;
case sf::Event::TextEntered:
if(Event.text.unicode >= 32 &&Event.text.unicode <= 126)
sentence += (char)Event.text.unicode;
else if(Event.text.unicode == 8 && sentence.getSize() > 0)
sentence.erase(sentence.getSize() - 1, sentence.getSize());
text.setString(sentence);
break;
}
}
if (phase1){
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Y)){
text.setFont(font);
text.setString("That's great news! Let's get started!");
phase1 = false;
phase2 = true;
}

if (sf::Keyboard::isKeyPressed(sf::Keyboard::N)){
text.setFont(font);
text.setString("Well that's no fun! I'll see you later.");
}

}

if (phase2){

text.setString("When do you want to start the trip?");


}




Window.clear(sf::Color::Black);
Window.draw(text);
Window.display();
}
}

Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jun 3 2016 02:31pm
The direction you're heading is a tricky one and will likely be a giant mess when you hit more than a few phases. I would research data structures and create a structure(s) that will help you create your game.

If I were to do this I would create a linked list of structures where each struct holds the required data to render a complete scene (Ex: images, text, etc). Then I would create a binary tree of the struct so that you can transverse scenes easily. This will also allow you to precache N scenes, although if you are just displaying text it won't be needed.

Here is a copy paste of what I said to another user on another forum. They were thinking of ways of creating to create an animated visual novel in which each scene has 1-4 responses you can select and depending on the selected response it will lead you to a new scene. This is vaguely similar to what you are attempting to do, in which you ask a question and then change to a different "phase" depending on the response.

Quote
If you were wondering how a binary tree could be used for precaching of levels (although probably not needed as you can simply read your music/text/images as you need to without little impact) then I have provided a commented rough draft. I have not included deallocation methods or tree population methods other than node insertion.

The theory is that when you transverse the left side nodes that you are going through the options for the current scene. Then when you transverse a right sided node for an option you go to the next scene that option points to.

In this example I use the preface of "You wake up from a dream only to realize you are late for school!\n\n" for the first scene with the options (left side nodes) of "1) Ugh, I should just fall back asleep.\n", "2) Looks like I won't be having breakfast this morning... again.\n", "3) I wonder if binary-tree-senpai will notice me today?\n". Then when we select an option, for instance 2, we will go down 2 left side nodes from where we started, and then 1 right side node to go to our new scene in which we update our currentScene pointer to remember where we are.

Because this setup is a simple binary tree all allocation methods, insertion methods, sorting methods, and the like are well documented all over the internet.

Using this code you can setup large scenes that can be preloaded. Say maybe you're at a school, you could load each school related scene so no matter your option everything is precached. Then when you leave the school you deallocate that tree and load a new one for the general area you are in.

You may likely need to use a tree within a tree structure. Where the outer container tree holds all your levels and where they transition too, then the inner tree holds all the data for the text, music, and images for that level. Or not if the story is purely linear, Then this will be an extremely easy method to pull off. It will also get extremely complex if you have to start doing some kind of character relations and dynamic text based on previous interactions of a scene. Then again that might be more along the lines of a simulator than a VN I suppose.

Or you can just load things as you need them via a config file pointing to resources and which resource pack leads into the next.


Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jun 3 2016 02:32pm
Continuation, the previous post was too long:

Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//The nodes structure for the binary tree. A left node is another option, a right node is the scene that option could lead to
/*
O0
|
O1 - S1O0 - S2O0
| | |
O2 S1O1 S2O1 - S4O0
| | |
O3 S1O2 - S3O0 S4O1
|
S3O1
|
S3O2
*/

struct sceneNode {
char output[256];
struct sceneNode *nextScene;
struct sceneNode *nextOption;
};

//insertOption and insertScene do the exact same thing and can be merged. The only exist as a duplicate for ease of code reading
//What they do is if the current node that you are passing is null (non existant, not allocated) it will allocate memory and set it up.
//This might be where you would want to also pass your images and music buffers so they can be added to the structure.
void insertOption(char *output, struct sceneNode **nodeOption) {
if(*nodeOption == NULL) {
*nodeOption = (struct sceneNode*)malloc(sizeof(struct sceneNode));
strncpy((*nodeOption)->output, output, 256);
(*nodeOption)->nextScene = NULL;
(*nodeOption)->nextOption = NULL;
}
}

void insertScene(char *output, struct sceneNode **nodeScene) {
if(*nodeScene == NULL) {
*nodeScene = (struct sceneNode*)malloc(sizeof(struct sceneNode));
strncpy((*nodeScene)->output, output, 256);
(*nodeScene)->nextScene = NULL;
(*nodeScene)->nextOption = NULL;
}
}

//This function recursivly iterates the left nodes (options) printing their output text
void printOptions(struct sceneNode *scene) {
if(scene != NULL) {
printf("%s", scene->output);
printOptions(scene->nextOption);
}
}

//This function changes to a specific scene N options away from the route recursivly
//For example if you are at O0 and want to go to the scene pointed to at O1, it would travel 1 left node, then 1 right node and return that node.
struct sceneNode *changeScene(int option, struct sceneNode *scene) {
if(scene != NULL) {
if(option == 0)
return scene->nextScene;

scene = scene->nextOption;
option -= 1;
return changeScene(option, scene);
}

return NULL;
}

int main() {
//Initialize the root of the scene
//You can use O0 as a pretext for the scene, or as an option itself
struct sceneNode *rootScene = malloc(sizeof(struct sceneNode));
strncpy(rootScene->output, "You wake up from a dream only to realize you are late for school!\n\n", 256);
rootScene->nextScene = NULL; printf("\n-------------------------------------------------------\n");
rootScene->nextOption = NULL;

//Setup a character buffer so we can dynamically create strings via snprintf if we need to, we can simply use char * strings if we wanted
char output[256] = {0};

//Create some placeholders, there is bound to be a better way I was tired
struct sceneNode *currentOption = rootScene;
struct sceneNode *currentScene = rootScene;
struct sceneNode *temp = NULL;

//The next bulk of code down to where it starts printing options should be in its own method
//The method should read a file for inputs/scenes, probably tab delimited or something
//All the options will be on the same level, then a new scene and its options would be indented once, and the next twice and so forth.
snprintf(output, 256, "%s\n", "1) Ugh, I should just fall back asleep.\n");
insertOption(output, &currentOption->nextOption);

temp = currentOption;
snprintf(output, 256, "%s\n", "You awake 4 hours later.");
insertScene(output, &currentOption->nextScene);
currentOption = currentOption->nextScene;

snprintf(output, 256, "%s\n", "1) I wonder who is online on animebytes...\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "2) I should probably check on my guild on my mmo...\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "3) I wonder what is in the fridge for lunch.\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

currentOption = temp->nextOption;
snprintf(output, 256, "%s\n", "2) Looks like I won't be having breakfast this morning... again.\n");
insertOption(output, &currentOption->nextOption);

temp = currentOption;
snprintf(output, 256, "%s\n", "You arrive at school on time in a frantic rush.");
insertScene(output, &currentOption->nextScene);
currentOption = currentOption->nextScene;

snprintf(output, 256, "%s\n", "1) I should go check the message board for updates on my school clubs.\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "2) If I don't hurry up I will be late for first period.\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

currentOption = temp->nextOption;
snprintf(output, 256, "%s\n", "3) I wonder if binary-tree-senpai will notice me today?\n");
insertOption(output, &currentOption->nextOption);

temp = currentOption;
snprintf(output, 256, "%s\n", "You leave the bathroom grin with a blushed grin on your face.");
insertScene(output, &currentOption->nextScene);
currentOption = currentOption->nextScene;

snprintf(output, 256, "%s\n", "1) I feel so guilty, but that felt too good.\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "2) If binary-tree-senpai found out I could never face her again.\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "3) If I go to school now I will be late, but at least binary-tree-senpai will be there!\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;

snprintf(output, 256, "%s\n", "4) ...\n");
insertOption(output, &currentOption->nextOption);
currentOption = currentOption->nextOption;


//Start at the beginning of our tree
currentScene = rootScene;

//Print our options and then look for user input
printOptions(currentScene);
printf("\n-------------------------------------------------------\n");
scanf("%d", &i);

//Change to that user inputted next scene and print the options
currentScene = changeScene(i-1, currentScene);
printOptions(currentScene);
printf("\n-------------------------------------------------------\n");


return 0;
}
Go Back To Programming & Development Topic List
Add Reply New Topic New Poll