【笨木头Cocos2d-x 042】一个函供应多个菜单回调——UserObject自定义数据

笨木头  2013-05-27 19:19   Cocos2d-x,Cocos2d-x2.0   阅读(9,904)   11条评论

笨木头花心贡献,啥?花心?不呢,是用心~

转载请注明,原文地址:http://www.benmutou.com/archives/596

正文:

 

1.Java的菜单点击事件实现方式

我是个Java中毒比较深的人,所以,一般菜单或按钮的点击事件我都是传一个匿名内部类进去,而且还能支持参数,类似这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
exitBtn1.setOnClickListener(new ExitEvent(0) );

exitBtn2.setOnClickListener(new ExitEvent(1) );

exitBtn3.setOnClickListener(new ExitEvent(2) );

Class ExitEvent {

ExitEvent(int iCode) {

}

}

我有三个按钮,分别对应不同的回调事件,但是我只需要使用同一个类去做处理。

 

2.一个简单的需求

所以,在Cocos2d-x里我也想类似这么用,假设我有这样一个需求:有五个菜单和一个标签,点击不同的菜单,标签就显示不同的内容。

效果如下图所示:

 

3.一般的做法

正常情况下,我们会这么做,先声明几个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class HelloWorld : public cocos2d::CCLayer

{

public:

virtual bool init();

static cocos2d::CCScene* scene();

CREATE_FUNC(HelloWorld);

private:

CCLabelTTF* m_numLab;

void numClick1(CCObject* pSender);

void numClick2(CCObject* pSender);

void numClick3(CCObject* pSender);

void numClick4(CCObject* pSender);

void numClick5(CCObject* pSender);

};

一个m_numLab标签,五个回调函数。

实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
bool HelloWorld::init()

{

bool bRet = false;

do

{

CC_BREAK_IF(! CCLayer::init());

/* 数字标括签 */

m_numLab = CCLabelTTF::create("""Arial"85);

m_numLab->setColor(ccGREEN);

m_numLab->setPosition(ccp(250200));

this->addChild(m_numLab);

CCMenuItemLabel* item1 = CCMenuItemLabel::create(CCLabelTTF::create("one""Arial"35)this, menu_selector(HelloWorld::numClick1));

CCMenuItemLabel* item2 = CCMenuItemLabel::create(CCLabelTTF::create("two""Arial"35)this, menu_selector(HelloWorld::numClick2));

CCMenuItemLabel* item3 = CCMenuItemLabel::create(CCLabelTTF::create("three""Arial"35)this, menu_selector(HelloWorld::numClick3));

CCMenuItemLabel* item4 = CCMenuItemLabel::create(CCLabelTTF::create("four""Arial"35)this, menu_selector(HelloWorld::numClick4));

CCMenuItemLabel* item5 = CCMenuItemLabel::create(CCLabelTTF::create("five""Arial"35)this, menu_selector(HelloWorld::numClick5));

CCMenu* numMenu = CCMenu::create(item1, item2, item3, item4, item5, NULL);

numMenu->setPosition(ccp(25080));

numMenu->alignItemsHorizontallyWithPadding(10);

this->addChild(numMenu);

bRet = true;

} while (0);

return bRet;

}

void HelloWorld::numClick1( CCObject* pSender )

{

m_numLab->setString("1");

}

void HelloWorld::numClick2( CCObject* pSender )

{

m_numLab->setString("2");

}

void HelloWorld::numClick3( CCObject* pSender )

{

m_numLab->setString("3");

}

void HelloWorld::numClick4( CCObject* pSender )

{

m_numLab->setString("4");

}

void HelloWorld::numClick5( CCObject* pSender )

{

m_numLab->setString("5");

}

很简单,创建了五个CCMenuItemLabel菜单对象,每个菜单对象对应一个回调函数,每个回调函数都对m_numLab标签进行赋值操作,不同的回调函数赋不同的值。

 

4.一个看起来更舒服的实现方式

~!但是,我不喜欢要那么多函数,明明就是类似的功能,非得要我搞这么多函数,我才不要。(小若:这些函数明明就是你自己写的O O!)

没关系,Cocos2d-x有一个很好用的东西,叫做userObject,它是CCNode的一个特别的地方,CCNode允许我们绑定一个CCObject类型或其子类型的对象到其身上,只要这个CCNode没有被释放,我们就可以随时取出绑定的userObject对象(小若:就是绑定自定义数据嘛~Box2D也有~)

于是,木头投机取巧的编码方式又诞生了,完整的新实现方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#include "SimpleAudioEngine.h"

USING_NS_CC;

class HelloWorld : public cocos2d::CCLayer

{

public:

virtual bool init();

static cocos2d::CCScene* scene();

CREATE_FUNC(HelloWorld);

private:

CCLabelTTF* m_numLab;

void numClick(CCObject* pSender);

};

#endif  // __HELLOWORLD_SCENE_H__

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "HelloWorldScene.h"

using namespace cocos2d;

CCScene* HelloWorld::scene()

{

CCScene * scene = NULL;

do

{

scene = CCScene::create();

CC_BREAK_IF(! scene);

HelloWorld *layer = HelloWorld::create();

CC_BREAK_IF(! layer);

scene->addChild(layer);

} while (0);

return scene;

}

bool HelloWorld::init()

{

bool bRet = false;

do

{

CC_BREAK_IF(! CCLayer::init());

/* 数字标括签 */

m_numLab = CCLabelTTF::create("""Arial"85);

m_numLab->setColor(ccGREEN);

m_numLab->setPosition(ccp(250200));

this->addChild(m_numLab);

CCMenuItemLabel* item1 = CCMenuItemLabel::create(CCLabelTTF::create("one""Arial"35)this, menu_selector(HelloWorld::numClick));

item1->setUserObject(CCString::create("1"));

CCMenuItemLabel* item2 = CCMenuItemLabel::create(CCLabelTTF::create("two""Arial"35)this, menu_selector(HelloWorld::numClick));

item2->setUserObject(CCString::create("2"));

CCMenuItemLabel* item3 = CCMenuItemLabel::create(CCLabelTTF::create("three""Arial"35)this, menu_selector(HelloWorld::numClick));

item3->setUserObject(CCString::create("3"));

CCMenuItemLabel* item4 = CCMenuItemLabel::create(CCLabelTTF::create("four""Arial"35)this, menu_selector(HelloWorld::numClick));

item4->setUserObject(CCString::create("4"));

CCMenuItemLabel* item5 = CCMenuItemLabel::create(CCLabelTTF::create("five""Arial"35)this, menu_selector(HelloWorld::numClick));

item5->setUserObject(CCString::create("5"));

CCMenu* numMenu = CCMenu::create(item1, item2, item3, item4, item5, NULL);

numMenu->setPosition(ccp(25080));

numMenu->alignItemsHorizontallyWithPadding(10);

this->addChild(numMenu);

bRet = true;

} while (0);

return bRet;

}

void HelloWorld::numClick( CCObject* pSender )

{

CCMenuItemLabel* item = (CCMenuItemLabel*)pSender;

CCString* text = (CCString*)item->getUserObject();

 

m_numLab->setString(text->getCString());

}

我们调用每一个CCMenuItemLabel菜单对象的setUserObject函数,绑定一个CCString对象到菜单身上。

然后,我们把五个回调函数缩减成一个,回调函数有一个pSender参数,这个参数代表触发这个回调函数的对象,也就是我们的CCMenuItemLabel菜单对象。

于是,重点来了,我们的CCMenuItemLabel菜单对象是绑定了一个CCString的,我们只需要调用它的getUserObject函数取出这个CCString即可。然后用这个CCStringm_numLab标签赋值。

呼,这样的实现方式才能让我心情愉悦~~

 

最后的最后,源代码下载地址:

下载地址1:http://www.bego.cc/file/21735596

下载地址2:http://filemarkets.com/file/musicvs/ad2177c7/

 

.