Cocos2dx3.0 Super Mario Development Notes (1) -- Use of loadingbar and pageview

Source: Internet
Author: User

Cocos2dx3.0 Super Mario Development Notes (1) -- Use of loadingbar and pageview

After completing the first project of the cocos2dx course, I chose super Mary. It can be said that you have your own ideas, simple but not simple.

I spent a day upgrading the super Mary source code of Version 2.1 to version 3.0, modifying, modifying, deleting, and referring to the source code. Although I don't know much about it, the upgrade was successful and the game was playing normally.

Based on the idea of not writing code for the game, I listed the knowledge points that can be used by the game. Three methods of Data Persistence: loading page, tmx map resolution, cocosStudio scenario, screen adaptation, how to choose a level, and code structure optimization (various types of abstract inheritance ), after the basic functions are available, you can design your own abnormal checkpoints.


In the past two days, the loading interface and the main interface are implemented for all scenarios and selection scenarios.

The effect is as follows: gif:

Vc/logs + logs/o6zIu7rzo7oKPHByZSBjbGFzcz0 = "brush: java;"> loadProgress = ProgressTimer: create (Sprite: create ("image/loadingbar.png ")); loadProgress-> setBarChangeRate (Point (1, 0); // set the variation rate of the Process BAR loadProgress-> setType (ProgressTimer: Type: BAR ); // set the process Bar type loadProgress-> setMidpoint (Point (0, 1); // set the progress direction loadProgress-> setPosition (visibleSize. width/2, visibleSize. height/2); loadProgress-> setPercentage (progressPercent); this-> addChild (loadProgress );
To adjust the progress bar, you only need to implement it in the callback function for Asynchronously loading resources. Other effects such as loading can also be implemented in the scenario of loading. asynchronous loading does not cause too many lag Effects on the interface, unless the mobile phone is too bad ..
There are three types of cache for asynchronous resource loading: TextureCache, SpriteFrameCache, and AnimationCache. We need to pre-load different resources as needed during loading. Then process the progress bar in the callback function. I use the simplest TextureCache to log on to loading. Add the preloadResource function in init. This function will be executed directly without waiting for any results. Then the resource is loaded in the background.

Void LoadingScene: preloadResource () {// write test separately here. If it is determined that it is a scenario, directly use plist to load std: string resouceMain = "image/mainscene /"; float count = 20; // load a total of 17 everyAdd = 100/count; ctor: getInstance ()-> getTextureCache ()-> addImageAsync (resouceMain + "about_normal.png ", callback (LoadingScene: loadingCallback, this); ctor: getInstance ()-> getTextureCache ()-> addImageAsync (resouceMain + "Callback", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache ()-> addImageAsync (resouceMain + "backA.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director :: getInstance ()-> getTextureCache ()-> addImageAsync (resouceMain + "backB.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "background.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "bg.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "music_off.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "music_on.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "quitgame_normal.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "quitgame_select.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "Set_Music.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "Setting_n.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "setting_s.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "startgame_normal.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "startgame_select.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "wxb.jpg", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); ctor: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "zhy.jpg", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); ctor: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "sound_effect_off.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "sound_effect_on.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this); Director: getInstance ()-> getTextureCache () -> addImageAsync (resouceMain + "switchBg.png", CC_CALLBACK_1 (LoadingScene: loadingCallback, this ));}

In the callback function:
Void LoadingScene: loadingCallback (Texture2D *) {progessAdd ();} void LoadingScene: progessAdd () {progressPercent + = everyAdd; if (100-progressPercent
 
  
ReplaceScene (TransitionFade: create (1, scene);} percentLabel-> setString (StringUtils: format ("% d", int (progressPercent ))); // update the percentLabel value loadProgress-> setPercentage (progressPercent );}
 
Switch the scenario from loading to 100%. Not many progress bars of resources do not move forward with + 1, and there is no technical implementation method here. I hope you can tell me when you have made optimization. Thank you very much for your progress ~
The main game scenario is skipped here, and you can see the source code. It's just a simple background and two menus.
This article focuses on the selection of checkpoints. Super Mary has eight levels. You can select the corresponding level for the game. Here, we implement the function similar to defending the radish level switch. Drag left and right to select the level and click to play the game. There are three ways to achieve this: first, create a Layer and add eight genie horizontally. Implement touch events, and move the left and right touch to move the Layer. After the touch ends, adjust the position of the layer based on the drag position (using the MoveTo animation ). The mechanism of this method is simple, but it is complicated to write. Type 2: I used TableView. I didn't understand the usage of TableView at the beginning. I failed to try it. TableView can create a series of small units horizontally or vertically, and you can set the interval between these units. I thought about it. It is especially suitable for ranking. I don't know how well scroll performs ranking.
The disadvantage of TableView is that when the drag ends, it determines the unit to stop based on the touch inertia, which does not meet our expectations.
Error parsing using TabelView:Import library libExtensions add header file # include "cocos-ext.h" cocos2dx cannot open include file: "extensions/ExtensionMacros. h ": No such file or directory (.. \ Classes \ SelectLevel indicates that $ (EngineRoot) is not introduced to the appended include directory (for how to add the directory, refer to my blog: Click to open the link) usage: Add in init, do not discard the proxy method setDelegate, or you will find no response:
tableView = TableView::create(this, Size(spWidth, spHeight));tableView->setDirection(ScrollView::Direction::HORIZONTAL);tableView->setPosition(Point((winSize.width - spWidth)/2, (winSize.height-spHeight)/2));tableView->setDelegate(this);this->addChild(tableView);tableView->reloadData();
The six callback functions that must be implemented, two of which are scroll's declaration of {} in the. h file.
void SelectLevel::tableCellTouched(TableView* table, TableViewCell* cell){CCLOG("cell touched at index: %ld", cell->getIdx());}Size SelectLevel::tableCellSizeForIndex(TableView *table, ssize_t idx){return Director::getInstance()->getVisibleSize();}TableViewCell* SelectLevel::tableCellAtIndex(TableView *table, ssize_t idx){auto string = String::createWithFormat("%ld", idx+1);TableViewCell *cell = table->dequeueCell();if (!cell) {cell = new TableViewCell();cell->autorelease();auto sprite = Sprite::create(StringUtils::format("image/level/select%d.jpg", idx));sprite->setAnchorPoint(Point::ZERO);sprite->setPosition(Point(0, 0));cell->addChild(sprite);auto label = Label::createWithSystemFont(string->getCString(), "Helvetica", 20.0);label->setPosition(Point::ZERO);label->setAnchorPoint(Point::ZERO);label->setTag(123);cell->addChild(label);}else{auto label = (Label*)cell->getChildByTag(123);label->setString(string->getCString());}return cell;}ssize_t SelectLevel::numberOfCellsInTableView(TableView *table){return Global::getInstance()->getTotalLevels();}



Third: PageView. There are examples in the official Demo. The first thing I can see is that this effect is what I want (at least similar, we can change it ). It is also easy to implement according to the Demo. Note: pageView-> addEventListenerPageView (this, pagevieweventselector (SelectLevel: pageViewEvent ));
The Declaration of the callback function pageViewEvent must be used:
void SelectLevel::pageViewEvent(Ref *pSender, PageViewEventType type){}
Never use:
void SelectLevel::pageViewEvent(Ref *pSender){}
No error is reported for compiling later, but an error is reported during running.
The implementation of PageList is as follows:
    pageView = PageView::create();pageView->setSize(Size(winSize.width, winSize.height));pageView->setPosition(Point(0,0));for (int i = 1; i < Global::getInstance()->getTotalLevels(); i++){Layout* layout = Layout::create();layout->setSize(Size(winSize.width, winSize.height));ImageView* imageView = ImageView::create(StringUtils::format("image/level/select%d.jpg", i));imageView->setScale9Enabled(true);imageView->setSize(Size(spWidth, spHeight));imageView->setPosition(Point(layout->getSize().width / 2.0f, layout->getSize().height / 2.0f));layout->addChild(imageView);Text* label = Text::create(StringUtils::format("page %d", i), "fonts/Marker Felt.ttf", 30);label->setColor(Color3B(192, 192, 192));label->setPosition(Point(layout->getSize().width / 2.0f, layout->getSize().height / 2.0f));layout->addChild(label);pageView->addPage(layout);}pageView->addEventListenerPageView(this, pagevieweventselector(SelectLevel::pageViewEvent));this->addChild(pageView);

In this way, we have implemented drag-and-drop selection. Now we need to click to start the game. There is another problem here. The callback function of PageView calls back every time you touch the end, so we cannot perform scenario Switching Based on its callback function. I want to add a Touch event on the current layer to determine the game to start. The result shows that PageView intercepts the Touch callback event. No way. I added a transparent layer on the PageView to process the touch time and start the game. First, add the transparent layer:
auto layerr = Layer::create();layerr->setContentSize(Size(spWidth, spHeight));layerr->setPosition(size.width/2, size.height/2);layerr->setZOrder(111);this->addChild(layerr);auto listenTouch = EventListenerTouchOneByOne::create();listenTouch->onTouchBegan = CC_CALLBACK_2(SelectLevel::onTouchBegan, this);//listenTouch->onTouchMoved = CC_CALLBACK_2(SelectLevel::onTouchMoved, this);listenTouch->onTouchEnded = CC_CALLBACK_2(SelectLevel::onTouchEnded, this);//listenTouch->onTouchCancelled = CC_CALLBACK_2(SelectLevel::onTouchCancelled, this);Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenTouch, layerr);
It is actually a good touch callback: You need to determine when to switch the scenario. Do not switch when you touch the outside area of PageView, and do not switch when you move PageView more than 5 pixels.
Bool SelectLevel: onTouchBegan (Touch * touch, Event * event) {clickBeginPoint = touch-> getLocation (); return true;} void SelectLevel: onTouchEnded (Touch * touch, event * event) {int dragDistance = abs (touch-> getLocation (). x-clickBeginPoint. x); // if you click more than 5 pixels to switch the scenario if (dragDistance <5) {Rect layerRect = Rect (winSize. width-spWidth)/2, (winSize. height-spHeight)/2, spWidth, spHeight); if (layerRect. containsPoint (touch-> getLocation () {// The int level to be switched over = pageView-> getCurPageIndex () + 1 ;}}}

Here, PageView selects and starts the corresponding level game.

Tomorrow's TMX map resolution, there is a need for source code can be sent to me wct511@126.com or add QQ179261480. After the code is completed, the entire code is shared.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.