0

I have a project where I have multiple scenes, each representing a state, such as a splash screen, a main menu, a level, etc. There is a main Game class, and a SceneManager that handles all the scenes. I need to call some of the SceneManager functions from within the individual Scene classes, so I tried to implement passing the SceneManager into the Scene classes via a pointer. However, I keep getting the following error:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

I assume that I haven't initialized something correctly and that I causing the error, but I am having a hard time finding the exact issue and understanding it. I have included the relevant code below:

SceneManager.cpp function that gets the error:

void SceneManager::SetCurrentScene(Scene* scene) {

    currentScene = scene;

}

Game.cpp

Game::GameState Game::GAME_STATE = Playing;
sf::RenderWindow Game::mainWindow;
SceneManager* Game::sceneManager;

void Game::Start(void) {

    mainWindow.create(sf::VideoMode(GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT,32), GAME_WINDOW_TITLE, sf::Style::Close);

    //make a clock
    sf::Clock deltaClock;

    //load the screen manager
    //screenManager = new ScreenManager();
    sceneManager->SetCurrentScene(new SplashScene(sceneManager)); // <---- This line is the first use of SetCurrentScene()



    while(mainWindow.isOpen()) {

        //get the delta time
        sf::Time deltaTime = deltaClock.restart();
        float delta = deltaTime.asMilliseconds();

        GameLoop(delta);
    }

    mainWindow.close();
}

/*
bool Game::IsExiting()
{
    if(gameState == Game::Exiting)
        return true;
    else
        return false;
}
*/

sf::RenderWindow& Game::GetWindow()
{
    return mainWindow;
}


void Game::GameLoop(float delta) {

    sf::Event currentEvent;
    mainWindow.pollEvent(currentEvent);

    // "close requested" event: we close the window
    if (currentEvent.type == sf::Event::Closed) {
        mainWindow.close();
    }

    //graphics and rendering
    mainWindow.clear(GAME_WINDOW_BUFFER_COLOR);

    //update the current screen
    sceneManager->currentScene->Update(currentEvent, delta);
    sceneManager->currentScene->Draw(mainWindow);

    //display the window
    mainWindow.display();

}

Scene.cpp

Scene::Scene() {

    Load();

}


Scene::Scene(SceneManager* sceneManager) {

    this->sceneManager = sceneManager;
    Load();

}


Scene::~Scene() {

}

void Scene::Load() {

}

void Scene::Draw(sf::RenderWindow& renderWindow) {

}

void Scene::Update(sf::Event event, float delta) {

}

Thank you for all of the help!

  • 1
    well... `screenManager = new ScreenManager();` is commented out, so it's not like there is a valid screenManager to operate on. –  May 01 '20 at 07:11
  • I just uncommented it, and now a new line of code throws the same error. It is the line in the SplashScene that calls SetCurrentScene to change to the MainMenuScene – Bill The Biochemist May 01 '20 at 07:22
  • The solution with the pointer should work when you de-comment `screenManager = new ScreenManager();` But I would use a singleton pattern here as there is always just one SceneManager and it will be elegant and easy to use (after implementation); Example: [C++ Singleton design pattern](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern) – Misty May 01 '20 at 07:23
  • As an addition to Jacob Korbas comment, you should probably also read [why singletons are considered bad](https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons). Don't take this as a "don't do it". Just be aware that they introduce some problems and you have to decide which solution is the best for your program. – wychmaster May 01 '20 at 08:44

0 Answers0