[Cocos2dx Study Notes] Use cocos2dx3.x to complete the battle for defending the gaming kingdom-map (2), mfccocos2dx3.0

Source: Internet
Author: User

[Cocos2dx Study Notes] Use cocos2dx3.x to complete the battle for defending the gaming kingdom-map (2), mfccocos2dx3.0

Add the map directly at the map layer. I set the AnchorPoint to (0, 0) to facilitate coordinate calculation.

mapSprite = Sprite::createWithSpriteFrameName(String::createWithFormat("Stage_%d.png",level+1)->getCString());mapSprite->setAnchorPoint(Point(0,0));mapSprite->setPosition(Point(0,0));addChild(mapSprite);

This topic describes how to implement fixed skills and store skills.


The first is two fixed skills. Take meteorite as an example.

First, add the button image genie

StoneSprite = Sprite: createWithSpriteFrameName ("Courier"); stoneSprite-> setAnchorPoint (Point (); stoneSprite-> setPosition (Point (10,-20 )); stoneSprite-> setName ("inactive"); // judge whether the countdown is complete completeStone = false; addChild (stoneSprite, 1 );

Then there is the countdown cover layer, which is implemented by ProgressTimer and placed on the button image genie.

StoneTimer = progresstmer: create (Sprite: createWithSpriteFrameName ("power_loading.png"); stoneTimer-> setAnchorPoint (Point (0, 0 )); // rotate stoneTimer clockwise-> setReverseDirection (true); stoneTimer-> setPosition (Point (10,-20); stoneTimer-> setPercentage (100 ); // display the percentage of the original shape. this-> addChild (stoneTimer, 1 );


Add a timer to update the ProgressTimer status

Void PlayerStateMenu: updateStoneProgress (float Dt) {stoneTimer-> setPercentage (stoneTimer-> getPercentage ()-Dt * 2); // Update Progress 2if (stoneTimer-> getPercentage () = 0) {this-> unschedule (schedule_selector (PlayerStateMenu: updateStoneProgress); // cancel the timer completeStone = true;} return ;}

Schedule at the beginning, for example, after the first wave of enemies appeared.


Add touch response

Auto stoneListener = EventListenerTouchOneByOne: create (); stoneListener-> onTouchBegan = [&] (Touch * touch, Event * event) {auto target = static_cast <Sprite *> (event-> getCurrentTarget (); Point locationInNode = target-> convertTouchToNodeSpace (touch); Size size Size = target-> getContentSize (); rect rect = Rect (0, 0, size. width, size. height); // if you click if (rect. containsPoint (locationInNode) {// if cool-down ends if (completeStone = true) {// touch listening mTouchLayer-> removeAllListener (); if (stoneSprite-> getName () = "inactive") {// set it to the click status stoneSprite-> setSpriteFrame (SpriteFrameCache: getInstance () -> getSpriteFrameByName ("power_portrait_fireball_0002.png"); // Changes the status of TAGstoneSprite-> setName ("active "); // change the status of the other two buttons/******** // set the meteorite skill listening mTouchLayer-> setFireBallTouchShield () in the touch layer; // click the button for the second time, cancel} else {mTouchLayer-> removeFireBallTouchShield (); stoneSprite-> setSpriteFrame (SpriteFrameCache: getInstance ()-> getSpriteFrameByName ("worker ")); stoneSprite-> setName ("inactive"); <span style = "white-space: pre"> </span >}< span style = "white-space: pre "> </span >}return true;} return false ;}; stoneListener-> onTouchEnded = [&] (Touch * touch, Event * event ){}; // touch stoneListener-> setSwallowTouches (true); _ eventDispatcher-> addEventListenerWithSceneGraphPriority (stoneListener, stoneSprite );

When the countdown ends, set completeStone to true, which is triggered only when you click the button.

Click "skill" to add an EventListenerTouchOneByOne In the touch layer to overwrite the entire touch layer. When you click the map, this touch event is executed.

Next let's take a look at the touch Layer


class TouchLayer :public Layer{public:virtual bool init();    CREATE_FUNC(TouchLayer);EventListenerTouchOneByOne* touchlistener;EventListenerTouchOneByOne* FiereBalllistener;void setFireBallTouchShield();void removeFireBallTouchShield();bool onFireBallTouchBegan(Touch* touch, Event* event);void onFireBallTouchEnded(Touch* touch, Event* event);bool isFlag;bool onTouchBegan(Touch* touch, Event* event);void onTouchEnded(Touch* touch, Event* event);void onTouchMoved(Touch* touch, Event* event);Size winSize;bool isMoved;void removeAllListener();};
Here, I only captured the part related to the meteorite and the moving map.


Add the touch listening layer in BaseMap

void BaseMap::initTouchLayer(){mTouchLayer = TouchLayer::create();mTouchLayer->setContentSize(mapSprite->getContentSize());mTouchLayer->setAnchorPoint(Point(0,0));mTouchLayer->setPosition(Point(0,0));addChild(mTouchLayer,99);}

Add map movement time touch

touchlistener = EventListenerTouchOneByOne::create();touchlistener->onTouchBegan = CC_CALLBACK_2(TouchLayer::onTouchBegan, this);touchlistener->onTouchEnded = CC_CALLBACK_2(TouchLayer::onTouchEnded, this);touchlistener->onTouchMoved = CC_CALLBACK_2(TouchLayer::onTouchMoved, this);touchlistener->setSwallowTouches(true);_eventDispatcher->addEventListenerWithFixedPriority(touchlistener,-1);_eventDispatcher->addEventListenerWithSceneGraphPriority(touchlistener,this);


Set FiexPriority to-1 here to ensure that the touch event is triggered first with other touch times such as skill

Void TouchLayer: onTouchEnded (Touch * touch, Event * event) {<span style = "white-space: pre"> </span> touchlistener-> setSwallowTouches (isMoved ); isMoved = false;} void TouchLayer: onTouchMoved (Touch * touch, Event * event) {// calculates the sliding increment auto diff = touch-> getDelta (); // finger movement correction, because the finger touch is not as fixed as the mouse touch if (abs (diff. x)> 5 | abs (diff. y)> 5) {isMoved = true;} // obtain the current bgSprite position auto currentPos = this-> getParent ()-> getPosition (); // get the position where bgSprite should be located after sliding: auto pos = currentPos + diff; // The Boundary Control restricts the position pos of pos. x = MIN (pos. x, 0); pos. x = MAX (pos. x,-1200 + winSize. width); pos. y = MIN (pos. y, 0); pos. y = MAX (pos. y,-1000 + winSize. height); // reset the location of the map layer this-> getParent ()-> setPosition (pos );}

When the finger moves on the touch layer, isMoved is set to true. This is because setSwallowTouches (isMoved) will swallow other touch events.
This is to ensure that when moving, or when moving ends, it happens to be at a touch point and will not trigger other touch events (for example, moving the finger exactly on a defense tower, in this way, the Defense tower upgrade layer will not pop up)
In addition, the skill event listening will not be triggered when you move it. You can move it and then select the skill release location.


Void TouchLayer: setFireBallTouchShield () {// call this method to create a meteorite skill touch time FiereBalllistener = listener: create (); FiereBalllistener-> onTouchBegan = CC_CALLBACK_2 (TouchLayer: Listener, this); FiereBalllistener-> onTouchEnded = CC_CALLBACK_2 (TouchLayer: onFireBallTouchEnded, this); FiereBalllistener-> setSwallowTouches (true ); // set it to a higher value than the mobile touch event. _ eventDispatcher-> addEventListenerWithFixedPriority (FiereBalllistener, 1); _ eventDispatcher-> listener (FiereBalllistener, this);} void TouchLayer: removeFireBallTouchShield () {// if (FiereBalllistener! = NULL) _ eventDispatcher-> removeEventListener (FiereBalllistener);} bool TouchLayer: onFireBallTouchBegan (Touch * touch, Event * event) {// return TRUE directly, return true to intercept other time;} void TouchLayer: onFireBallTouchEnded (Touch * touch, Event * event) {// play sound SoundManager: playFireballUnleash (); // create 3 meteorite auto fireBall1 = FireBall: create (); addChild (fireBall1); fireBall1-> shoot (static_cast <TouchLayer *> (event-> getCurrentTarget ()) -> convertTouchToNodeSpace (touch) + Point (-30,300); auto fireBall2 = FireBall: create (); addChild (fireBall2 ); fireBall2-> shoot (static_cast <TouchLayer *> (event-> getCurrentTarget ()-> convertTouchToNodeSpace (touch) + Point (0,350); auto fireBall3 = FireBall :: create (); addChild (fireBall3); fireBall3-> shoot (static_cast <TouchLayer *> (event-> getCurrentTarget ()-> convertTouchToNodeSpace (touch) + Point (30,280 )); // obtain the player status layer of the parent category after the meteorite falls. Call startStone to start timing again and reset ProgressTimer to cover layer static_cast <BaseMap *> (this-> getParent ()) -> playerState-> startStone (); // remove this listener event removeFireBallTouchShield ();}

This is almost the case when I implement the whole skill listening and touch mobile.

Store skills, summon soldiers, and other skills are the same, but different skills are used ~ Other information, such as freezing enemies and summoning soldiers, will be described in the corresponding modules.


This is what I wrote for the moment today. There are also hard-pressed internships waiting for me to find.






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.