上篇文章写了Paddle类来处理精灵的点击、触摸事件,现在我们在Paddle的基础上
写一个MyPaddle类,来处理上一关、下一关、开始游戏按钮的点击事件。
1.类声明如下:
class MyPaddle :
public Paddle
{
CC_SYNTHESIZE(enum_evt, m_evttyp, evttyp);
CC_SYNTHESIZE(ChoiceScene*, m_pSence, pSence);
public:
MyPaddle();
~MyPaddle();
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
private:
bool bFlag;
};
2.其中bFlag用于标记是否被点击,我们处理ccTouchBegan和ccTouchEnded来处理点击事件:
bool MyPaddle::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (Paddle::ccTouchBegan(touch, event))
{
bFlag = true;
return true;
}
return false;
}
void MyPaddle::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
Paddle::ccTouchEnded(touch, event);
if (bFlag)
{
bFlag = false;
m_pSence->touchDownAction(this, m_evttyp);
}
}
3.可以看到ccTouchEnded中确认精灵被点击后会调用场景中的touchDownAction,
其中第二个参数是点击的事件类型,我们在ChoiceScene中实现touchDownAction这个函数:
在实现之前用一个头文件存放一些游戏中的常量,先定义一个常量和一些枚举类型,
#define ROUNDS 20
enum enum_evt {
evt_start,
evt_pressA,
evt_pressB,
evt_text
};
ROUNDS是关卡总数,enum_evt是事件类型
然后再ChoiceScene中定义如下内容
public:
void touchDownAction(CCObject* sender , unsigned int controlEvent);
private:
void update();
int m_nRound;
m_nRound初始化为1,其中update根据m_nRound的值更新显示的关卡数,下面我们写他们的实现代码如下:
void ChoiceScene::touchDownAction(CCObject* sender, unsigned int controlEvent)
{
if (controlEvent == evt_pressA)
{
m_nRound = 1 + (m_nRound - 1 + ROUNDS - 1) % ROUNDS;
update();
}
else if (controlEvent == evt_pressB)
{
m_nRound = 1 + (m_nRound + 1 + ROUNDS - 1) % ROUNDS;
update();
}
else if (controlEvent == evt_start)
{
//开始对应关卡的场景,稍后添加
}
}
void ChoiceScene::update()
{
char szTemp[260];
CCLabelAtlas* label1 = (CCLabelAtlas*)getChildByTag(evt_text);
sprintf(szTemp, "%d", m_nRound);
label1->setString(szTemp);
}
可以看到update中,getChildByTag来根据Tag来获取子节点的指针,还记得我们在ChoiceScene中的代码吗?
//5.对现实关卡的数字进行操作,设置显示数字为1,
//设置锚点,设置缩放,设置位置已经颜色,
int i = 3;
ccColor3B color = { 0, 0, 0 };
float* fSetting = fSettings[i];
CCLabelAtlas* label1 = CCLabelAtlas::create("1", szImgs[i], 16, 32, '.');
CCSize sz = label1->getContentSize();
label1->setAnchorPoint(ccp(0.5f, 0.5f));
label1->setScaleX(szWin.width / sz.width * fSetting[0]);
label1->setScaleY(szWin.height / sz.height * fSetting[1]);
label1->setPosition(ccp(szWin.width * fSetting[2], szWin.height * fSetting[3]));
label1->setColor(color);
addChild(label1, 0);
可以看到我们在ChoiceScene中第五步最后addChild,我们现在改为
addChild(label1, 0, evt_text);
这样,我们在update中可以获取到这个精灵对象,并修改它显示的内容。
4.最后我们在MyPaddle中添加一个通过纹理创建精灵的函数,注意在类中声明是静态函数:
MyPaddle* MyPaddle::paddleWithTexture(CCTexture2D* pTexture)
{
MyPaddle* pPaddle = new MyPaddle();
pPaddle->initWithTexture(pTexture);
pPaddle->autorelease();
return pPaddle;
}
5.万事具备了,只需要把ChoiceScene中创建的 上一关、下一关、开始游戏按钮的精灵
换成我们的MyPaddle精灵:
//4.分别对开始游戏,上一关,下一关按钮的图片加载上来显示到合适位置
enum_evt evts[4] = {evt_start, evt_pressA, evt_pressB, evt_text};
for (int i = 0; i < 3; ++i)
{
float* fSetting = fSettings[i];
CCTexture2D* paddleTexture = CCTextureCache::sharedTextureCache()->addImage(szImgs[i]);
//CCSprite* pPaddle = CCSprite::createWithTexture(paddleTexture);
MyPaddle* pPaddle = MyPaddle::paddleWithTexture(paddleTexture);
CCSize szBtn = pPaddle->getContentSize();
pPaddle->setScaleX(szWin.width / szBtn.width * fSetting[0]);
pPaddle->setScaleY(szWin.height / szBtn.height * fSetting[1]);
pPaddle->setPosition(ccp(szWin.width * fSetting[2], szWin.height * fSetting[3]));
addChild(pPaddle);
//设置当前场景到MyPaddle中,然后设置事件类型到MyPaddle中
pPaddle->setpSence(this);
pPaddle->setevttyp(evts[i]);
}
可以看到注释的位置替换成了额我们的MyPaddle精灵:
MyPaddle* pPaddle = MyPaddle::paddleWithTexture(paddleTexture);
然后再最后在pPaddle中设置了我们的场景和相应的事件类型。
pPaddle->setpSence(this);
pPaddle->setevttyp(evts[i]);
好了,现在我们编译运行程序,可以看到可以自由选择关卡和显示关卡了,如下图:
好了,下一篇我们写游戏关卡内容场景的设计,以及相应关卡开始按钮切换到关卡内容场景的事件。