• Advertisement
Sign in to follow this  

Confused with classes

This topic is 1896 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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. Edited by thefollower

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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. Edited by ultramailman

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement