Confused with classes

Started by
5 comments, last by rip-off 11 years, 5 months ago
Hey

In my class i have a private function which has this:


[source lang="cpp"] void Application::init(){

CreateSprite Background(theme["Background"]);
CreateSprite Logo(theme["Logo"]);
CreateSprite Button(theme["Button"]);
CreateSprite ButtonOn(theme["ButtonOn"]);

run(1);

}

void Application::run(int gameBool){

while(gameBool){
//game loop

}[/source]

The problem is - i cannot access my sprites (due to scopes).

So how do game makers do this ?

The way i thought was something like using a setting like so:

[source]std::string Setting = "MainMenu";[/source]

Then in run i would have:
[source lang="cpp"] void Application::run(int gameBool,std::string &Setting){

while(gameBool){
switch(Setting){
case "MainMenu": loadMainMenu result(); //this would be a class that sets sprites instead of doing so in "init()"
}
window.clear();
result.updateTo(window); //this will have window.draw() for all the sprites in the class
window.display();
}

[/source]

Am i on the right lines to how games are best programmed? Or is there some neat trick I'm missing.
Advertisement
Hello

This looks confusing, there is no way to tell what or where your "sprite" is. Can you post more code? At least the class definition.
Which class? Application or CreateSprite?
Application, because thats the class the private function belongs to. By the way, why is CreateSprite a class? most of the time, classes should be nouns, not verbs.
Firstly, put the locals as members of the class. That would be inside the class declaration in the header file.

Secondly, don’t use switch cases to manage such a large web of possible states. There are many patterns for this, one of which I have documented here: General Game/Engine Structure.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

maybe you use static clas for game management
my map aplications http://haritaaraci.com

maybe you use static clas for game management
[/quote]
No, there is no reason to do this.


Secondly, don’t use switch cases to manage such a large web of possible states. There are many patterns for this, one of which I have documented here: General Game/Engine Structure.
[/quote]
A simple switch over a game state enumeration is the easiest ways of implementing a simple game. Your state system, while a better fit for larger projects, is probably unnecessary here. The OP is still working out how to get simpler classes to work, let alone a more complex polymorphic solution.

@OP Your Application class should look more like this:

class Application {
public:
Application(const std::map<std::string, std::string> &theme);

void run();
private:
Sprite background;
Sprite buttonOn;
Sprite buttonOff;
Sprite logo;
};

The sprites should be initialised in a constructor. One way to do this is to use an initialiser list:

Application::Application(const std::map<std::string, std::string> &theme)
:
background(theme["Background"]),
buttonOn(theme["ButtonOn"]),
buttonOff(theme["ButtonOff"]),
logo(theme["Logo"])
{
}


Your initialisation code should not be invoking a "run" method, this is quite surprising. Also, passing an integer and treating it as a boolean, even if you include this hint in the name, is confusing. A better approach:

void Application::run() {
bool running = true;
while(running) {
// ...
}
}


As for separating the code to deal with different states, you don't need a polymorphic solution (though it would save you a little typing):

typedef std::map<std::string, std::string> Settings;


enum GameState {
STATE_INTRO,
STATE_MENU,
STATE_INGAME
}

class Intro {
static const int INTRO_TIME_MS = 5 * 1000;
public:
Intro(const Settings &settings)
:
logo(settings["logo"]),
timer(INTRO_TIME_MS),
finished(false)
{
}

void reset() {
timer.set(INTO_TIME_MS);
finished = false;
}


GameState nextState() {
if(finished) {
return STATE_MENU;
}
return STATE_INTRO;
}

void onEvent(const InputEvent &event) {
// Skip intro if the player hammers an input device!
finished = true;
}

void update(const TimeSpan &time) {
timer.update(time);
if(timer.elapsed()) {
finished = true;
}
}

void render(Screen &screen) {
screen.apply(logo);
}

private:
Timer timer;
Sprite logo;
bool finished;
};

// MainMenu and Game classes in a similar vein

class Application {
public:
Application(const Settings &settings)
void run();

private:
GameState currentState;
Intro intro;
MainMenu mainMenu;
Game game;
Screen screen;
};

Application::Application(const Settings &settings)
:
currentState(STATE_INTRO),
intro(settings),
mainMenu(settings),
game(settings),
screen(settings)
{
}


void Application::run() {
bool running = true;
TimeSpan time;
while(running) {
time.update();

InputEvent event;
GameState nextState;
switch(currentState) {
case STATE_INTRO:
while(pollEvent(event)) {
intro.onEvent(event);
}
intro.update(time);
intro.render(screen);
nextState = intro.nextState();
break;

case STATE_MENU:
while(pollEvent(event)) {
menu.onEvent(event);
}
menu.update(time);
menu.render(screen);
nextState = menu.nextState();
break;

case STATE_INGAME:
while(pollEvent(event)) {
game.onEvent(event);
}
game.update(time);
game.render(screen);
nextState = game.nextState();
break;

default:
assert(false, "Not implemented!");
break;
}

if(nextState != currentState) {
switch(currentState) {
case STATE_INTRO: intro.reset(); break;
case STATE_MENU: menu.reset(); break;
case STATE_INGAME: game.reset(); break;

default: assert(false, "Not implemented!"); break;
}
currentState = nextState;
}
}
}

Just a simple, untested example.

This topic is closed to new replies.

Advertisement