配置环境:win7+Cocos2d-x.2.0.3+VS2012
目标
实现一个按键效果,按下去之前显示normal.png的图,按下去之后显示selected.png的图。selected.png尺寸大于normal.png。按键按下去之后呈现一种放大的效果,如果你无法想象,下载个AngryBirds观察下吧。
思路
笔者在这个问题上纠结了一天半,尝试了各种方法,一直以为是自己写得不对导致点击菜单不能居中放大,最后查看源码才发现原来菜单类的对象默认锚点并不是中点,而是原点(0,0)。按键前后的图片都是以原点为锚点绘制,无法到达居中放大的效果。
我们先罗列出绘制一个按键所涉及的类,CCMenu、CCMenuItemSprite、CCSprite。它们在结点树上依次是爷爷、父亲、儿子的关系,当然你也可以认为是外婆、母亲、女儿的关系,随便。上述三个类的锚点坐标都是(0,0),不建议更改并且也无法更改。CCMenuItemSprite的大小和CCSprite的大小一致。当你没有抚摸屏幕的时候界面时这样的:
;
在这个图中,只对CCMenuItemSprite的位置进行了设置,其他对象的位置都是默认值。可以看到CCMenu对象的默认位置为(0,0)。CCSprite的位置与CCMenuItemSprite的位置一致,即CCSprite的位置默认也是(0,0)。
那么,如果想在此基础上实现居中放大的功能,该如何设置另一张精灵图像的位置呢?相信你一定能想到通过某种数学运算可以得出精灵selected的位置。看下图:
实现
具体的代码如下,直接在HelloWorld工程中的HelloWorld::init()函数中修改即可查看效果(当然要先把图放进去!)。
//start//////////////////下面这些代码都是通用的/////////////// CCSprite *pNormalSprite = CCSprite::create("normal.png"); CC_BREAK_IF(!pNormalSprite); CCSprite *pSelectedSprite = CCSprite::create("selected.png"); CC_BREAK_IF(!pSelectedSprite); float dW = pNormalSprite->getContentSize().width - pSelectedSprite->getContentSize().width; float dH = pNormalSprite->getContentSize().height - pSelectedSprite->getContentSize().height; pSelectedSprite->setPosition(ccp(dW / 2.0f,dH / 2.0f)); CCMenuItemSprite *pCloseItem = CCMenuItemSprite::create(pNormalSprite,pSelectedSprite,this,menu_selector(HelloWorld::menuCloseCallback)); CC_BREAK_IF(!pCloseItem); //end//////////////////////////////////////////////////////// pCloseItem->setPosition(ccp(100,100));//这里设置菜单项的位置。 CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer. this->addChild(pMenu, 1);
https://www.zybuluo.com/tangyikejun/note/21953
Cocos2d-x 点击菜单按键居中放大