Cocos2d-x3.6 continuous view touch event Transfer
In the previous article, the entire game has basically been connected.
This article adds a countdown and a Game Over interface. When the Game ends, a Game Over dialog box is displayed. You can also Play again.
The countdown is a time progress bar.
// Time bar background frame auto progressFrame = Sprite: createWithTexture (textureCache-> getTextureForKey (s_time_slot); // The anchorpoint (Vec2 (0, 0); progressFrame-> setPosition (120, wSize. height-50); addChild (progressFrame); // time bar genie auto pSprite = Sprite: createWithTexture (textureCache-> getTextureForKey (s_time_bars); progress = ProgressTimer :: create (pSprite); // anchpoint, progress-> setAnchorPoint (Vec2 (0, 0) in the lower left corner; // Type, bar progress-> setType (ProgressTimer :: BAR); progress-> setPosition (120, wSize. height-50); // horizontal change progress-> setMidpoint (Vec2 (0, 0); // one unit at a time progress-> setBarChangeRate (Vec2 (1, 0 )); // initial 100 progress-> setPercentage (100); addChild (progress); // time number numberTime = Label: createWithSystemFont (100, Thonburi, 24 ); numberTime-> setAnchorPoint (Vec2 (0, 0); numberTime-> setPosition (400, wSize. height-50); numberTime-> setColor (Color3B: BLACK); addChild (numberTime );
Then the countdown reduces one cell per second and calls the update () function once per second. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHByZSBjbGFzcz0 = "brush: java;"> schedule(SEL_SCHEDULE(&GameScene::update), 1.0);
Let's look at the update function:
Void GameScene: update (float dt) {// current progress int current = progress-> getPercentage (); // if it is zero, gameover if (current = 0) {// game over gameOver ();} else {// subtract one current --; progress-> setPercentage (current); char time [] = {25}; sprintf (time, % d, current); numberTime-> setString (time );}}
It is very easy to get the value of the current time bar, minus one. If it is 0, it calls game Over.
Let's look at the gameOver function:
Void GameScene: gameOver () {// stop the update function scheduling. Unschedule (SEL_SCHEDULE (& GameScene: update); // create a color layer auto layer = LayerColor: create (Color4B (100,100,100,100 )); // The default value of the anchor is layer-> setPosition (1000) in the lower left corner. addChild (layer,); // dialog box Background: auto sprite = Sprite: createWithTexture (Director: getInstance () -> getTextureCache ()-> getTextureForKey (s_game_dialog); sprite-> setPosition (wSize. width/2, wSize. height/2); layer-> addChild (sprite); // Game Over prompts auto title = Label: createWithSystemFont (Game Over, Thonburi, 35 ); title-> setPosition (layer-> getContentSize (). width/2, sprite-> getContentSize (). height-100); title-> setColor (Color3B: RED); layer-> addChild (title); // Font Item MenuItemFont: setFontName (fonts/Marker Felt. ttf); // Play Again button auto item1 = MenuItemFont: create (Play Again, CC_CALLBACK_0 (GameScene: playAgain, this); auto color_action = TintBy: create (0.5f, 0,-255,-255); auto color_back = color_action-> reverse (); auto seq = Sequence: create (color_action, color_back, nullptr ); item1-> runAction (RepeatForever: create (seq); auto menu = Menu: create (item1, nullptr); menu-> setPosition (layer-> getContentSize (). width/2, sprite-> getContentSize (). height/2); layer-> addChild (menu); // Add the touch event auto dispatcher = Director: getInstance ()-> getEventDispatcher () at the Game Over layer (); auto listener = EventListenerTouchOneByOne: create (); // swallow the touch event, that is, the following layer does not respond to the touch listener-> setSwallowTouches (true); // The Lambda expression implements the touch function, null, because you do not need to Touch to implement listener-> onTouchBegan = [] (touch * Touch, Event * event) {return true ;}; listener-> onTouchMoved = [] (Touch * touch, Event * event) {}; listener-> onTouchEnded = [] (Touch * touch, Event * event ){}; listener-> onTouchCancelled = [] (Touch * touch, Event * event) {}; // added to the GameOver layer dispatcher-> addEventListenerWithSceneGraphPriority (listener, layer );}
Note that GameScene itself is a Layer, and the GameOver page in it is a Layer. There are two layers in a scenario.
The previously added touch events in init () cannot solve the problem here. After the GameOver layer pops up, click the screen and even the small icons in it can be clicked. Check the touch events in init:
auto dispatcher = Director::getInstance()->getEventDispatcher(); auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameScene::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameScene::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameScene::onTouchCancelled, this); dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
This is the touch in init (). You can see that the touch event is swallowed up. listener-> setSwallowTouches (true), but it is not. Why:
In a scenario, if there are multiple layers, all layers must register a touch event for control. We can see that the current layer is registered here. Therefore, only the touch function settings in initi () cannot meet the requirements. When the GameOver layer pops up, the following layers cannot be clicked.
Therefore, we also need to register the touch event for our GameOver:
// Add the touch event auto dispatcher = Director: getInstance ()-> getEventDispatcher (); auto listener = EventListenerTouchOneByOne: create (); // swallow the touch event at the Game Over layer, that is, the following layer does not respond to the current touch listener-> setSwallowTouches (true); // Lambda expressions implement the touch function, empty, because the listener-> onTouchBegan = [] (Touch * touch, Event * event) {return true ;}; listener-> onTouchMoved = [] (Touch * touch, event * event) {}; listener-> onTouchEnded = [] (Touch * touch, Event * event) {}; listener-> onTouchCancelled = [] (Touch * touch, event * event) {}; // added to the GameOver layer dispatcher-> addEventListenerWithSceneGraphPriority (listener, layer );
Last line:dispatcher->addEventListenerWithSceneGraphPriority(listener, layer);
This is to register a touch event for the layer.
Since the GameOver layer does not need to do any touch logic, it just swallowed up the event and no longer passed down. I used a few empty Lambda expressions directly.
Then we can see that the effect has been achieved.