Hi, I am making a game using SFML. I have implemented a state handling system and am just filling in the bare bones e.g. closing the game and changing states. However I have discovered an issue. When I close the window within the intro/splash state everything is fine. However when I close it from the menu state I get an access violation. The following is the layout of the classes:
The state class is mainly virtual and the intro and menu classes are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class cIntro: public cStates{
public:
void Initialise(bool *r);
void Draw(sf::Window *window);
void Input(sf::Window *window);
void Clean();
private:
};
class cMenu: public cStates{
public:
void Initialise(bool *r);
void Draw(sf::Window *window);
void Input(sf::Window *window);
void Clean();
private:
};
The input function is the only function within the states that actually does anything at the moment and for intro and menu it looks like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void cIntro::Input(sf::Window *window){
sf::Event event;
while (window->pollEvent(event)){
if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Space){
*cState = 1;
}
if (event.type == sf::Event::Closed){
window->close();
*run = false;
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void cMenu::Input(sf::Window *window){
sf::Event event;
while (window->pollEvent(event)){
if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Space){
*cState = 0;
}
if (event.type == sf::Event::Closed){
window->close();
*run = false;
}
}
}
As mentioned this only occurs when closing the window, which encompass and only on the menu state:
1 2 3 4
if (event.type == sf::Event::Closed){
window->close();
*run = false;
}
This leads me to believe that it has something to do with one of the pointers but that's as far as my debugging skills can go.
Thanks for the replies. I have moved the variables out of protected and into their respective classes as private. Also kbw I think they should be pointers as they change the data for variables that are part of the engine class to determine what state the program is in as well as to close the program down. The program now closes properly without any errors, without deleting the pointers. I then add delete ptr and this causes debug assertion failed to appear and when debugging it is the delete pointer that is causing it.
> they change the data for variables that are part of the engine class
¿Shouldn't the ownership be in the `engine' class then?
¿why is `state' managing their lifetime?
Also, you may consider sending a message to the object, instead of messing around with its organs
I see so if I have understood this correctly I need to do something like
object.ChangeState() rather than passing the address of the variable I wish to change? If this is correct then withint the structure of my program I don't see how to do it as the structure is like this:
main: create engine object
engine.cpp set up the environment, such as current state, state list, create the window and handle the main game loop.
states (e.g. intro, menu, credits etc) contain virtual functions that are called by from within engine object.
The system I have in place for changing state and ending the program has me passing the address of these two variables to the current state.
Engine main loop as well as the initialising function (called only once) looks like:
> Do you only delete variables that are created with the new prefix?
Exactly (except that new is not a prefix), and everything that you new must be deleted (otherwise is a leak)
So you must delete each state.
> I need to do something like object.ChangeState() rather than passing the address of the variable I wish to change?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//void cEngine::Loop()
//states[curState]->Initialise(&run, &curState);
states[curState]->Initialise(this); //consider using the constructor instead
class cStates{
// int *cState;
// bool *run;
cEngine *engine;
};
//void cIntro::Input(sf::Window *window)
//*cState = 1;
engine->next_state();
//*run = false;
engine->stop();