.h file not including if it isn't on the first line

Hi. I have a problem transitioning scenes, if my #include "MainMenuScene.h" isn’t on the first line, the scene won’t be defined in my code. Putting #include "MainMenuScene.h" on the first line completely BREAKS my script where all instances of the scene used in the script give an error. All the errors are Use of undeclared identifier. Can someone please tell me what is wrong?
Code:

#include "GameIntro.h"
#include "MainMenuScene.h"
#include "ui/CocosGUI.h"

USING_NS_CC;

Scene* MainMenuIntro::createScene()
{
    return MainMenuIntro::create();
}

// Print useful error message instead of segfaulting when files are not there.
static void problemLoading(const char* filename)
{
    printf("Error while loading: %s\n", filename);
    printf("Depending on how you compiled you might have to add 'Resources/' in front of filenames in MainMenuScene.cpp\n");
}

// on "init" you need to initialize your instance
bool MainMenuIntro::init()
{
    if ( !Scene::init() )
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    auto spritecache = SpriteFrameCache::getInstance();
    spritecache->addSpriteFramesWithFile("launch_sheet-uhd.plist");
    spritecache->addSpriteFramesWithFile("game_sheet3-uhd.plist");
    
    auto titleLayer = new Layer();
    addChild(titleLayer);
    auto two_point_2 = Sprite::create("update.png");
    auto title = Sprite::createWithSpriteFrameName("logo_001.png");
    auto titleLayerScaleAnim = ScaleTo::create(2,1,1);
    auto titleLayerRotateAnim = RotateTo::create(2,0);
    auto titleLayerMoveAnim = MoveTo::create(2,Vec2(visibleSize.width / 2, visibleSize.height * 0.85f));
    auto titleLayerAnim = Spawn::create(titleLayerScaleAnim, titleLayerRotateAnim, titleLayerMoveAnim, NULL);
    auto wait_half = DelayTime::create(0.5f);
    auto newScene = MainMenu::createScene();
    auto transitionFunc = CallFunc::create([&, newScene](){
        Director::getInstance()->replaceScene(newScene);
    });
    auto titleLayerSequence = Sequence::create(titleLayerAnim, wait_half, transitionFunc, NULL);
    
    title->setScale(0.45f,0.45f);
    titleLayer->addChild(title);
    two_point_2->setPosition(Vec2(title->getContentSize().width / 5, 0 - title->getContentSize().height / 5));
    two_point_2->setScale(0.45f,0.45f);
    titleLayer->addChild(two_point_2);
    titleLayer->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
    titleLayer->setRotation(90);
    titleLayer->setScale(4,4);
    titleLayer->runAction(titleLayerSequence);

    return true;
}

void MainMenuIntro::menuCloseCallback(Ref* pSender)
{
    Director::getInstance()->end();
}

something is wrong, but I am not sure what. It shouldn’t matter the line. I’d suggest posting both the .cpp and .h files so we can see more.

*the scripts have been added to CMakeLists.txt
GameIntro.cpp already shared.
GameIntro.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class MainMenuIntro : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(MainMenuIntro);
};

#endif

MainMenuScene.cpp

#include "MainMenuScene.h"
#include "ui/CocosGUI.h"

USING_NS_CC;

Scene* MainMenu::createScene()
{
    return MainMenu::create();
}

// Print useful error message instead of segfaulting when files are not there.
static void problemLoading(const char* filename)
{
    
    printf("Error while loading: %s\n", filename);
    printf("Depending on how you compiled you might have to add 'Resources/' in front of filenames in MainMenuScene.cpp\n");
}

// on "init" you need to initialize your instance
bool MainMenu::init()
{
    if ( !Scene::init() )
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    
    
    return true;
}

void MainMenu::menuCloseCallback(Ref* pSender)
{
    Director::getInstance()->end();
}

MainMenuScene.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class MainMenu : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(MainMenu);
};

#endif // __HELLOWORLD_SCENE_H__

MainMenuScene.h and GameIntro.h are both using the same header guard:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

...
#endif

Save yourself time (and headaches) from mistakes like this by removing the header guards and just adding this at the top of each header file:

#pragma once

Just a bit of unsolicited advice, try to keep the source file and the class name within it somewhat similar. For instance, GameIntro.h should have a class named “GameIntro” or GameIntroScene etc, or call the file MainMenuIntro instead since that’s the class contained within it. It’ll help you find things quicker.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.