上个博客说道我们象棋程序进入了欢迎界面,在欢迎界面下等待一秒进入主界面
进入主界面的关键代码如下:
CCScene* pScene = CCMainMenu::scene(); 创建scene
...
CCDirector::sharedDirector()->replaceScene(ps); 显示scene
最关键的是CCMainMenu::scene函数,说明后面要显示的scene类型是CCMainMenu类型的
所以接下来我们一起来看CCMainMenu是怎么回事
typedef struct { CCSprite* pSprite; float x; // coordinate float y; }SPRITE_INFO; typedef std::vector<SPRITE_INFO> VEC_SPRITE; typedef VEC_SPRITE::iterator VEC_SPRITE_IT; class CCMainMenu : public CCLayer { public: static CCScene* scene(); virtual bool init(); CREATE_FUNC(CCMainMenu); virtual void ccTouchesEnded(CCSet* pTouches, CCEvent* pEvent); private: void setPos(CCSprite* pSprite, int x, int y); void setPosDigit(CCSprite* pSprite, int x, int y); void menuCallBack(CCObject* pSender); void menuRegret(CCObject* pSender); void menuStart(CCObject* pSender); void menuHardChoose(CCObject* pSender); void menuSoundChoose(CCObject* pSender); void updateTime(float dt); void updateFocus(float dt); void initCoordinate(); void initListImage(); void initTimeShow(); void initChessPosition(); CCSprite* getNumberSprite(int nNum); void setNumberSprite(int nChessTime); CCSprite* getListSprite(CHESS_TYPE nType); CHESS_TYPE getChessType(int i, int j); void dealWithChess(float x, float y); CCSprite* getChessByCoord(float x, float y); bool getChessByCoord(float& x, float& y, short dt); void collectInfo(CCSprite* pSprite); bool judgeAction(int tx, int ty); void freeOne(); void freeAll(); bool judgeContinuous(); void clean(); bool judgeWin(); //void print(); private: CCSprite* m_pFocus; CCSprite* m_pBKG; CCSprite* m_pMinute[2]; CCSprite* m_pSecond[2]; CCSprite* m_pCurChess; CCSprite* m_pTargetChess; CHESS_TYPE m_enCurChessType; CHESS_TYPE m_enTarChessType; CCSprite* m_pChess[2][16]; CCMenuItemImage* m_pOpenVolice; CCMenuItemImage* m_pCloseVolice; //std::ofstream f_output; //std::string str; float m_fPositionX; float m_fPositionY; int m_nChessTime; CCSize s; bool m_bSelect; // has a chess be selected? if true, cannot be change bool m_bVolice; bool m_bCollectCorrect; int ox, oy; // the original coordinate of the current chess int m_nContinuous; // the max numbers to attact opponent's boss int m_nCur; // 0:red; 1:black int m_nWin; // 0:red; 1:black enum GAME_STATUS { GAME_MENU, GAME_RUNNING, GAME_WIN, GAME_OVER, }; GAME_STATUS m_enGameStatus; enum GAME_ROLE { ROLE_RED, ROLE_BLACK, }; GAME_ROLE m_enCurRole; VEC_SPRITE m_vecSprite; };oh,天,这个类太复杂了,对我们初学者来说,但是不要害怕,其他的我们先不管他是咋的,我们先来看基本的函数
一个是scene函数,一个是init函数。scene函数是创建函数,而init函数时初始化调用函数。
CCScene* CCMainMenu::scene() { CCScene* pScene = CCScene::create(); CCMainMenu* pLayer = CCMainMenu::create(); pScene->addChild(pLayer, 3); return pScene; }scene函数和WelCome的scene函数类似,也是先创建一个scene,再创建一个CCMainMenu对象,然后把CCMainMenu对象加入到scene
最后返回scene
bool CCMainMenu::init() { // 调用父类init函数 if (!CCLayer::init()) { return false; } // 获取窗口大小,这个窗口大小将来用来计算控件位置等 s = CCDirector::sharedDirector()->getWinSize(); // 创建背景图片,并设置 m_pBKG = CCSprite::create(RES_PATH"background.png"); CCRect r = m_pBKG->getTextureRect(); m_pBKG->setAnchorPoint(CCPointZero); m_pBKG->setPosition(ccp(0, 0)); m_pBKG->setScaleX(s.width/r.size.width*0.667f); m_pBKG->setScaleY(s.height/r.size.height); this->addChild(m_pBKG, -2); // 创建焦点图片精灵,这个焦点是指棋子被选中 m_pFocus = CCSprite::create(RES_PATH"selected.png"); r = m_pFocus->getTextureRect(); m_pFocus->setScaleX(0.667f); m_pFocus->setScaleY(0.6f); m_pFocus->setVisible(false); this->addChild(m_pFocus, 1); m_fPositionX = s.width - r.size.width*0.667f; m_fPositionY = s.height - r.size.height*0.6f; // 新局按钮 CCMenuItemImage* pItem = CCMenuItemImage::create(RES_PATH"new.jpg", RES_PATH"new.jpg", this, menu_selector(CCMainMenu::menuCallBack)); pItem->setPosition(ccp(m_fPositionX - s.width/6, m_fPositionY - s.height/8)); pItem->setAnchorPoint(CCPointZero); pItem->setScaleX(0.667f); pItem->setScaleY(0.6f); CCMenu* pMenu = CCMenu::create(pItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); // 悔棋按钮 pItem = CCMenuItemImage::create(RES_PATH"regret.jpg", RES_PATH"regret.jpg", this, menu_selector(CCMainMenu::menuRegret)); pItem->setPosition(ccp(m_fPositionX - s.width/6, m_fPositionY - s.height/8*2)); pItem->setAnchorPoint(CCPointZero); pItem->setScaleX(0.667f); pItem->setScaleY(0.6f); pMenu = CCMenu::create(pItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); // 开始按钮 pItem = CCMenuItemImage::create(RES_PATH"start.jpg", RES_PATH"start.jpg", this, menu_selector(CCMainMenu::menuStart)); pItem->setPosition(ccp(m_fPositionX - s.width/6, m_fPositionY - s.height/8*3)); pItem->setAnchorPoint(CCPointZero); pItem->setScaleX(0.667f); pItem->setScaleY(0.6f); // pMenu = CCMenu::create(pItem, NULL); xueguoliang pMenu = CCMenu::create(pItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); // 难度按钮 pItem = CCMenuItemImage::create(RES_PATH"difficulty.jpg", RES_PATH"difficulty.jpg", this, menu_selector(CCMainMenu::menuHardChoose)); pItem->setPosition(ccp(m_fPositionX - s.width/6, m_fPositionY - s.height/8*4)); pItem->setAnchorPoint(CCPointZero); pItem->setScaleX(0.667f); pItem->setScaleY(0.6f); pMenu = CCMenu::create(pItem, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1); // 声音按钮 m_pOpenVolice = CCMenuItemImage::create(RES_PATH"openVolice.png", RES_PATH"openVolice.png", this, menu_selector(CCMainMenu::menuSoundChoose)); CCSize r2 = m_pOpenVolice->getContentSize(); m_pOpenVolice->setPosition(ccp(m_fPositionX - s.width/6 + r.size.width/2 - r2.width/6, m_fPositionY - s.height/8*5)); m_pOpenVolice->setAnchorPoint(CCPointZero); m_pOpenVolice->setScaleX(0.667f); m_pOpenVolice->setScaleY(0.6f); pMenu = CCMenu::create(m_pOpenVolice, NULL); pMenu->setPosition(CCPointZero); this->addChild(pMenu, 1, 100); // 关闭声音按钮 m_pCloseVolice = CCMenuItemImage::create(RES_PATH"closeVolice.png", RES_PATH"closeVolice.png", this, menu_selector(CCMainMenu::menuSoundChoose)); m_pCloseVolice->setPosition(ccp(m_fPositionX - s.width/6 + r.size.width/2 - r2.width/6, m_fPositionY - s.height/8*5)); m_pCloseVolice->setAnchorPoint(CCPointZero); m_pCloseVolice->setScaleX(0.667f); m_pCloseVolice->setScaleY(0.6f); pMenu = CCMenu::create(m_pCloseVolice, NULL); pMenu->setPosition(CCPointZero); m_pCloseVolice->setVisible(false); this->addChild(pMenu, 1, 101); // 坐标信息 this->initCoordinate(); // 初始化时间 this->initTimeShow(); // 初始化图片 this->initListImage(); this->setTouchEnabled(true); this->schedule(schedule_selector(CCMainMenu::updateTime), 1.0f); // 这个相当于做一个双buffer,移动一个buffer,显示一个buffer for (int i = 0; i < 10; ++i) { for (int j = 0; j < 9; ++j) { g_cur_map[i][j] = g_chess_map[i][j]; } } // 一些游戏中用到的状态变量,需要的时候我们再详细描述 m_enGameStatus = GAME_MENU; m_enCurRole = ROLE_RED; m_bVolice = true; m_pCurChess = NULL; m_bSelect = false; m_bCollectCorrect = true; m_pTargetChess = NULL; m_nContinuous = 3; m_nCur = 0; m_enCurChessType = CHESS_NONE; m_enTarChessType = CHESS_NONE; m_nWin = -1; m_vecSprite.reserve(10); return true; }init函数执行完之后,程序就显示出主界面如下:
所以主界面其实含有摆棋子的功能,除了摆棋子之外,还需要准备控制控件和状态量等等,这些工作
都是在init函数中完成,理解了init函数,也就理解了大部分象棋程序的数据结构了。
在init函数主干代码上,大部分代码完成了右边空间创建和状态量初始化,而棋子位置初始化,则调用
如下函数中实现。
// 坐标信息
this->initCoordinate();
// 初始化图片
this->initListImage();