cocos2dx 开发成长之路 006

 场景单例,

  做一个场景是公用的,可以在同一个scene上面更换layer
    

class GameScene
{
public:
    static GameScene* getInstance();
    
    virtual ~GameScene();
    
    void loadPlayerAndStart();
    
    void loadStageOpeningAnimation(int mapId, int areaId = 0);

    void setupPlayScreen(int mapId, bool isNormalStage, int areaId = 0);
    
    void loadData();
    void loadStageMap(int mapId, bool isNormalStage = true, int areaId = 0);
    void loadMainStage();
//    void exitStageMap();
    
    int getCurrentMap() { return m_mapId; }
    void gotoStage(int stageId, int areaId = 0);
    
    void showMessageOnStageOpeningScene(const char* pMessage);
    void clearStage();
    
    Scene* sharedScene;//共享的场景
    GameStage* sharedGameStage;//共享的角色表现层,一般用layer
    
    MainUI* sharedMainUI;//共享的玩家操作层
    

    CC_SYNTHESIZE(bool, m_DataLoaded, DataLoaded);
    
    CC_SYNTHESIZE(bool, m_IsStageOpeningScene, IsStageOpeningScene);
    
private:
    GameScene();
    int m_mapId;
};

 实现:

GameScene* GameScene::getInstance()
{
    static GameScene* gameScene;
    
    if (!gameScene)
    {
        if (gameScene)
        {
            delete gameScene;
        }
        
        gameScene = new GameScene();
    }
    
    return gameScene;
}

GameScene::GameScene()
{
    sharedScene = CCScene::create();
    sharedScene->retain();
    
    sharedMainUI = MainUI::create();
    sharedScene->addChild(sharedMainUI, 1);
    
    sharedGameStage = NULL;
    
    m_IsStageOpeningScene = false;
    
    m_DataLoaded = false;
}

GameScene::~GameScene()
{
    if (sharedScene)
    {
        sharedScene->release();
        sharedScene = nullptr;
    }
    
    if (sharedMainUI)
    {
        sharedMainUI->release();
    }
    
}

 MainUI 的实现:

class MainUI : public Node
{
public:
    virtual bool init();
    
    CREATE_FUNC(MainUI);
    
    StageUI* getStageUI();
    
    void initStageUI();
    void showLoadingMessage(const char* pMessage);
};

 

bool MainUI::init()
{
    if (!Node::init())
    {
        return false;
    }
    
    return true;
}


StageUI* MainUI::getStageUI()
{
    Node* node = getChildByTag(STAGE_UI_TAG);
    if (node)
    {
        return static_cast<StageUI*>(node);
    }
    
    return NULL;
}



void MainUI::initStageUI()
{
    if (getChildByTag(STAGE_UI_TAG))
    {
        // exists
        return;
    }
    
    removeAllChildrenWithCleanup(true);
    
    addChild(StageUI::create(), 0, STAGE_UI_TAG);
}

void MainUI::showLoadingMessage(const char *pMessage)
{

    
    removeAllChildrenWithCleanup(true);

    Label* pLabel = Label::createWithSystemFont(pMessage, REGULAR_FONT_NAME, 36);
    
    Size winSize = Director::getInstance()->getWinSize();
    
    pLabel->setPosition(Vec2(winSize.width/2, winSize.height/2));
    
    pLabel->setScaleX(winSize.width/DESIGN_SCREEN_WIDTH);
    pLabel->setScaleY(winSize.height/DESIGN_SCREEN_HEIGHT);
    
    addChild(pLabel, 0, TAG_MESSAGE);
    
}

 StageUI的实现

class StageUI : public Node
{
public:
    virtual bool init();
    virtual void update(float dt);
    
    CREATE_FUNC(StageUI);
    
    
    virtual void addChild(Node * child);
    
    virtual void addChild(Node * child, int localZOrder);
    
    virtual void addChild(Node* child, int localZOrder, int tag);
    virtual void addChildWithoutScale(Node *child, int localZOrder, int tag);
    
    void reset();
    
//    void createSystemMenu(ENUM_HEROSYSTEM_MENU_TYPE menuType);
    
//    void showGameSettingMenu();
    void resetActionMenu();
    
    /*
    void createBattleUnitSelection();
    void updateBattleUnitSelection();
    */
    /*
    void updateSelectedUnitIcons(const vector<AttackObject*>& selectedUnits);
    */
    void updateDotaStageProgressBar(int buildingRemains);
    
    void updatePlayerMoveMenu();
    
    void showWinningMenu();
    cocos2d::Node* getWinningMenu();
    
    void showNpcStatusMenu(int npcId);
    void removeNpcStatusMenu();
    
    void onUserTapOnMap(const cocos2d::Point& touchPos);
//    void showBuildingUpgradeMenu(Building* pBuilding);
    void removeBuildingMenu();
    
    bool isInBuildingMenu();

    void showTutorialInstruction(ENUM_PROGRESS_FLAG progressFlag);
    
    void removeInstructions();
    void removeArrow();
    void showPressDownArrow(const cocos2d::Point& pos);


    void showHint(const char* message, bool autoRemove = false, float delayTime = 2.0);
    void removeHint();
    bool isShowingHint();
    
    void showInstructionForSkillTree();
    
    void showMessage(const char* pMessage, bool pauseGame);
    void hideMessageBox();
    void hideNpcMessage();
    bool hasMessageBox();
    
    /*
    inline PlayerMoveMenu* getPlayerMoveMenu()
    {
        return m_pPlayerMoveMenu;
    }
    */
    inline GameMessageBox* getMessageBox()
    {
        return m_MessageBox;
    }
    
    void showNpcMessage(int npcId, const char* message);
    void showBattleMessage(const char *message);
    void showBattleMessage2(const char *message);
    NpcMessageBox* getNpcMessageBox();
    BattleMessageBox* getBattleMessageBox();
    
    
    void showWarningMessage(const char* pMessage);
    
    void showAwardView(ENUM_AWARD_TYPE type, int cnt, int id = 0);
    
    void showRotateMinerNpc(const char* message);
    void hideRotateMinerNpc();
    
    void showIapBonus(int id);
private:
    
    void updateChildScale(Node* pChild);
    
    void showUnplaceable(const cocos2d::Point& tilePos);
    
    void resumeGame();
    
    void removeUnnamedNode(cocos2d::Node* pNode);
    
    
    
    cocos2d::Node* m_PrevInstructionArrow;
    cocos2d::Node* m_pInstruction;
    
    cocos2d::Node* m_PrevInstructionMessageBox;
    
//    PlayerMoveMenu* m_pPlayerMoveMenu;
    
    
    GameMessageBox* m_MessageBox;
    NpcMessageBox* m_NpcMessageBox;
    BattleMessageBox *m_BattleMessageBox;
    
    bool m_ArrowIsForSettingMenu;
    


    
};

 实现文件:

bool StageUI::init()
{
    if (!Node::init())
    {
        return false;
    }
    
    return true;
}


void StageUI::reset()
{
    unscheduleUpdate();
    
    Size winSize = CCDirector::getInstance()->getWinSize();
    
    this->setContentSize(Size(DESIGN_SCREEN_WIDTH, DESIGN_SCREEN_HEIGHT));
    ignoreAnchorPointForPosition(false);
//    setPosition(Vec2(winSize.width/2, winSize.height/2));
//    setAnchorPoint(Vec2(0.5, 0.5));
    setPosition(Vec2(0,0));
    setAnchorPoint(Vec2(0,0));
    
    m_PrevInstructionArrow = NULL;
    m_PrevInstructionMessageBox = NULL;
    m_pInstruction = NULL;
    
    m_ArrowIsForSettingMenu = false;
    
    removeAllChildrenWithCleanup(true);
    
    /*
    if (Function::getStageType(GameScene::getInstance()->sharedGameStage->getMapId()) == ENUM_STAGE_HOME)
    {
        createSystemMenu(ENUM_HEROSYSTEM_MENU_HOME);
    }
    */
    
//    m_MessageBox = GameMessageBox::create();
//    
//    addChild(m_MessageBox, 128, MESSAGEBOX_TAG); // messagebox has the highest z-order
    
    
    m_BattleMessageBox = BattleMessageBox::create();
    addChild(m_BattleMessageBox,128,BATTLE_MESSAGE_BOX_TAG);
    
    setScaleX(winSize.width/DESIGN_SCREEN_WIDTH);
    setScaleY(winSize.height/DESIGN_SCREEN_HEIGHT);
    
    
    m_NpcMessageBox = NpcMessageBox::create();
    addChild(m_NpcMessageBox, 128, NPC_MESSAGE_BOX_TAG);
    
    scheduleUpdate();
}


void StageUI::updateChildScale(Node* pChild)//最小自适应
{
    float scale = MIN(getScaleX(), getScaleY());
    pChild->setScaleX(pChild->getScaleX()*scale/getScaleX());
    pChild->setScaleY(pChild->getScaleY()*scale/getScaleY());
}

void StageUI::addChild(Node * child)
{
    
    updateChildScale(child);
    Node::addChild(child);
    
}

void StageUI::addChild(Node * child, int localZOrder)
{
    
    updateChildScale(child);
    Node::addChild(child, localZOrder);
    
}

void StageUI::addChild(Node* child, int localZOrder, int tag)
{
    updateChildScale(child);
    Node::addChild(child, localZOrder, tag);
}

void StageUI::addChildWithoutScale(Node *child, int localZOrder, int tag)
{
    Node::addChild(child,localZOrder,tag);
}

 上面实现了对屏幕的自适应缩放,使得子节点在放大的过程中高度优先缩放而不变形。即重载了addchild相关方法

 

posted @ 2015-01-23 14:57  Mareon  阅读(166)  评论(0编辑  收藏  举报