I guess I wasn't being very helpful earlier. Sorry. I just get frustrated.
Since it seems like everybody is introduced to the console first, they all think "I should make a game in the console". And I find myself perpetually attempting (often in vain) to dissuade people from doing this, as it is a horrible, horrible path to go down. Almost to the point where you're actually doing yourself a disservice by wasting your time and energy.
If you're really interested in making game, I'd say you shouldn't bother learning all this crap you're messing with now. Playing midi this way, changing the console text color, etc (where did you even learn how to
do that?). All of that malarchy is useless and wasted knowledge. You're better off just getting a lib designed for gaming (I often recommend SFML
http://www.sfml-dev.org/ ) and making games with that. It's really not as difficult as it's perceived to be.
That said... here's some actual advise as to how you can improve:
How can you say that my code is riddled |
several reasons (many related)
1) You have tangles of gotos
2) Your names are indescriptive
3) Your functions are doing to much / they're too large
3) You're hardcoding everything.
Gotos destroy rational program flow. When your program is hoping all around it makes the logic very hard to follow. Hard to follow logic means more bugs, harder to maintain code, messier code, and makes it extremely difficult for anyone else to figure out what is going on.
Sure the code might makes sense
to you. But that's because you're the one who wrote it. And you wrote it recently. Try sitting on the project for a couple months, then come back to it after you've forgotten how the inner workings work. You'll find it's a lot harder to follow than you originally thought.
Your labels and names of things are not descriptive, only adding to the confusion. "ERR001", "OPT001", etc. As a general rule of thumb, if you're naming things with numbers like that, you're doing something wrong. (Of course this isn't always the case, but it usually is).
Your functions are too long. This is because they're doing too much. A function should do 1 task. If that task consists of several parts, then you should break down those parts into other functions. This makes the overall flow of logic
much easier to follow... especially if you give the functions descriptive names. Plus if the function does a small, simple task, it's much easier to write and bugs are less likely.
You're hard-coding everything. Basically that means you're doing this:
1 2 3 4 5 6 7 8
|
if( player_is_in_the_forest )
{
// do forest stuff here
}
else if( player_is_in_the_mountains )
{
// do mountain stuff here
}
|
This seems like a logical way to go to newbies, but really it's creeping death.
Games (and really all programs) should strive to have everything treated the same way,
with the same logic. Since the logic is all the same, all that changes is the data. So instead of hard-coding different areas, you can use the same code for every area and just change the data that's used.
In this instance, your data consists of 2 general parts:
1) the text you print to describe the scene
2) the options available to the player
You should store these parts seperately from the code, and just have your code access the appropriate data at the appropriate time.
For a very simplistic example (and you'll have to excuse the crudity here, as I only put about a minute of thought into this).
This is also really sloppy. You could clean this up by putting the classes in different headers and stuff:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
enum Action
{
act_none, // not a valid action
act_move, // move to a different location
act_text // print some new text on the screen
};
struct Option
{
Option() : action(act_none) { } // the default option has no action
string display;
Action action;
// different data used depending on the type of action
int act_int;
string act_string;
static Option Move(const string& display,int moveto)
{
Option r;
r.display = display;
r.action = act_move;
r.act_int = moveto;
return r;
}
static Option Text(const string& display,const string& text)
{
Option r;
r.display = display;
r.action = act_text;
r.act_string = text;
return r;
}
};
struct Area
{
string description;
Option[4] options;
Area(const string& desc,const Option& o0,const Option& o1 = Option(),const Option& o2 = Option(),const Option& o3 = Option())
{
description = desc;
options[0] = o0;
options[1] = o1;
options[2] = o2;
options[3] = o3;
}
};
//=================================
// The areas. Probably you should put these in a .txt file or something and load them.
// You generally don't want to store the game data in the program.
// But whatever, this is an example
enum
{
area_beach = 0,
area_forest
};
Areas theareas[] = {
// beach
Area("You are on the beach. Check out the waves!",
Option::Move("Go to the forest", area_forest)
);
// forest
Area("You are in a forest. So many trees!",
Option::Move("Go to the beach", area_beach),
Option::Text("Punch a tree","Ouch! I think you broke your hand!")
);
|
Your code would then all just keep track of which area you're in, present the options for that area, and perform the appropriate action based on the option the player selected.
All the code would be the same for every area.
Of course this all isn't very "simple". Choose-your-own-adventure games are actually one of the harder games for beginners to make. A simple vertical shooter / space invaders clone would be easier.
</my 4 cents>