Cocos2dx 3.2如何实现两个节点间的通信
在实际开发中,我们时常会碰到这种情况:一个按钮点击后会弹出一个对话框,对话框中的一个按钮点击后会将本对话框关掉。这种情况要求我们能在一个node节点里对另一个node节点进行操作。一般情况下我们能用三种方法来解决这个问题。
第一种:通过代理类完成两个节点间的通信。
我们把包含触发对话框的按钮的层称为layer1,把包含触发的对话框的层称为layer2。首先我们需要创建一个代理类,这个代理类Delegate除了一个public的纯虚函数外什么都没有,之后我们让layer1继承Delegate,并且在layer1中重写这个虚函数。接着我们在layer2中加入一个新成员变量layer1* test。最后在layer1中按钮的回调函数里,在讲layer1加入渲染树之前,把layer1的指针赋值给layer2->test。并在layer2的按钮的回调函数里调用test的虚函数。好吧这样说有些复杂,我们还是看代码吧。
layer1头文件:
1 #ifndef __LAYER1_H__ 2 #define __LAYER1_H__ 3 4 #include "cocos2d.h" 5 USING_NS_CC; 6 class Delegate 7 { 8 public: 9 virtual void stop() = 0;//作为代理的虚函数 10 }; 11 class layer1 :public Scene,public Delegate 12 { 13 public: 14 static Scene* scene(); 15 CREATE_FUNC(layer1); 16 bool init(); 17 void stop();//重写的虚函数 18 void loadMenuItem();//加入按钮 19 void func(); 20 Layer* lay; 21 }; 22 23 #endif
layer1的cpp文件:
1 #include "layer1.h" 2 #include "layer2.h" 3 Scene* layer1::scene() 4 { 5 Scene* scene1 = Scene::create(); 6 Layer* layer = Layer::create(); 7 scene1->addChild(layer); 8 return scene1; 9 } 10 bool layer1::init() 11 { 12 Scene::init(); 13 loadMenuItem(); 14 Size size = Director::getInstance()->getWinSize(); 15 Sprite* sprite = Sprite::create("HelloWorld.png"); 16 sprite->setPosition(size.width / 2, size.height / 2); 17 addChild(sprite); 18 return true; 19 } 20 void layer1::loadMenuItem() 21 { 22 MenuItem* item = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(layer1::func, this)); 23 item->setZOrder(100); 24 Menu* menu = Menu::create(); 25 item->setPositionX(item->getPositionX() + 300); 26 menu->addChild(item); 27 addChild(menu,1); 28 } 29 void layer1::func() 30 { 31 layer2* layer = layer2::create(); 32 layer->example = this; 33 lay = layer; 34 addChild(lay); 35 } 36 void layer1::stop() 37 { 38 lay->removeFromParent(); 39 }
layer2的头文件:
1 #ifndef __LAYER2_H__ 2 #define __LAYER2_H__ 3 #include "cocos2d.h" 4 #include "layer1.h" 5 USING_NS_CC; 6 class layer2:public Layer 7 { 8 public: 9 CREATE_FUNC(layer2); 10 bool init(); 11 void loadMenuItem(); 12 Delegate* example;//等会将layer1传进来 13 void func(); 14 }; 15 #endif
layer2的cpp文件:
1 #include "layer2.h" 2 3 bool layer2::init() 4 { 5 Sprite* sprite = Sprite::create("background.png"); 6 Size size = Director::getInstance()->getWinSize(); 7 sprite->setPosition(size.width / 2, size.height / 2); 8 addChild(sprite); 9 loadMenuItem(); 10 return true; 11 } 12 void layer2::loadMenuItem() 13 { 14 MenuItem* item = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(layer2::func, this)); 15 item->setZOrder(100); 16 item->setPositionY(item->getPositionY() + 20); 17 Menu* menu = Menu::create(); 18 menu->addChild(item); 19 addChild(menu, 1); 20 } 21 void layer2::func() 22 { 23 example->stop(); 24 }