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相关方法

时间: 2024-11-01 15:01:20

cocos2dx 开发成长之路 006的相关文章

cocos2dx 开发成长之路 005

cocos2dx 3.0版本TableView拍生自ScrollView,常用来做滚动列表,有几种特殊用法,不知道大家用到过没 要求:1.滚动时不能选中TableCell,非滚动状态才能选中 很简单,在TableView的delegate函数中,通过isTouchMoved()函数来判断 [cpp] view plaincopy void WeaponSelectLayer::tableCellUnhighlight(cocos2d::extension::TableView* table, c

cocos2dx 开发成长之路 004

1.概述 游戏也好,程序也好,只有能与用户交互才有意义.手机上的交互大致可以分为两部分:点击和输入.其中点击更为重要,几乎是游戏中全部的交互.在Cocos2d-x 3.0中,更改了dispatch机制.同时加入了两种新的交互形式:listener 和touchEvent回调.加上先前版本中的点击函数回调,与重写layer层的touch消息响应,构成了一个相对完整的交互模式.先上一张Demo的图: 2.四种点击 1.函数回调 函数回调是最简单的响应形式,一直以来被用于MenuItem中的点击处理.

cocos2dx 开发成长之路 003

SpriteBuilder的使用, 创建SpriteBuilder Project,最好和类名一样,或者相关,一个project里面可以有多个file,每个file即是一个UI,这样可以提高UI的重用率, 1,首先创建Project,命名为DressOnEquip,在file菜单里选project settings,可以把默认缩放改为1X,别的都取消勾选 修改好这些设置,done 2,new a file folder,把你要添加的图片资源文件直接托到folder里面,记住,一定要托噢. 3,n

cocos2dx 开发成长之路 002

在多个layer的情况下,为了避免触摸事件穿透,我们要把触摸事件截取在当前层,具体做法如下 auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(MyLayer::onTouchBegan, this); _eventDispatcher->addEventListenerWithScen

cocos2dx 开发成长之路 001

1.响应按钮事件的创建过程中,如果按钮的响应事件是打开某个页面,也就是说创建一个新的页面,那么先要将此之前创建的同样的页面消除掉,这样避免玩家狂点按钮:如果按钮掉功能是请求服务器点话,请求之后可能会进行某些回调操作,那么有两种方法取设计用户体验,一,强制disable操作界面,直至回调完成之后在解除屏蔽:二,假装屏蔽,设置flag判断是否回调结束,如果回调未结束,则玩家点了按钮也不会产生新的请求.相比之下,第二种方式似乎更人性化,毕竟隐藏了对用户对拒绝警告,更加和谐的一种软屏蔽.当然,还会遇到某

大二女生web开发成长之路——讲述我从软妹子到女汉子的进阶过程

学习和实践前端一年时间,几乎天天在工作室和一群屌丝男程序员一起学习.开发.这种潜移默化的环境下,编码提高了,节操也细碎了. 一年前,娇滴滴的还是工作室里面小师妹一枚,软软的软件工程妹子,做不到人见人爱,但在这个据说男女比例8比1的学校中,仍是比较受欢迎群体——女生中的一员. 然而,    回想过去这一年,跟一帮大老爷们坐在一起讲蛋疼的笑话: 工作室聚餐中满怀“邪”意地企图把师兄们灌醉: 为了赶项目,可以经常和某位苦逼男一起debug到两三点,不亦乐乎: 男生唤我作欣姐,各种玩笑各种开,因为都不拿

2017年Java web开发工程师成长之路

详情请交流  QQ  709639943 00.2017年Java web开发工程师成长之路 00.R语言速成实战 00.R语言数据分析实战 00.Python+Django+Ansible Playbook自动化运维项目实战 00.Java深入微服务原理改造房产销售平台 00.Python3入门机器学习 经典算法与应用 00.老司机学python篇:第一季(基础速过.机器学习入门) 00.Python 从入门到精通 78节.2000多分钟.36小时的高质量.精品.1080P高清视频教程!包括标

从1.5k到18k, 一个程序员的5年成长之路

http://blog.csdn.net/lgg201/article/details/8637763 昨天收到了心仪企业的口头offer, 回首当初什么都不会开始学编程, 到现在恰好五年. 整天在社区晃悠, 看了不少的总结, 在这个时间点, 我也写一份自己的总结吧. 我一直在社区分享, 所以, 这篇总结也是本着一种分享的态度, 希望相比我还年轻的同学们, 可以从中找到一些让自己成长更快的文字. 先介绍下背景:1. 2008年3月开始学习编程, 目前2013年3月;2. 2009年6月计算机专业

菜鸟程序员的成长之路(三)——2014,逝去的半年,奋斗的半年

从3月份到现在,仅仅半年的时间让我扮演了两个完全不同的角色,从在校生一下变成了毕业生,作为毕业生不能再像在校生一样自由自在,无所顾忌,想怎样就怎样,肆无忌惮的生活,浪费时间.如果你想从容的面临未来的生活,就需要彻头彻尾的改变.多一份稳重,多一份责任,多一份担当. 鉴于LZ不太擅长写非技术博文,那就以碎碎念的形式,来回顾一下我的奋斗历程: 技术 3月份开始备战软考,软考准备了两个多月的时间,从看视频做笔记,再到大家一起讲课,复习,做试题巩固,整个过程至今历历在目.软考虽然不难,但是对于基础差的同学