
下面这个引用自乱斗西游
设计说明
1.菜单项(MenuItem)平均分布在椭圆(类似)上
2.椭圆长轴为2/3wIDth,短轴为2/8height
3.最前面的菜单项Scale=1,opacity=255,最后面Scale=0.5,opacity=129.其它位置根据三角函数变换(updateposition中实现)
4.默认最前面菜单被选中(selected)
5.单位角度(unitAngle)是2*PI/菜单项的数量
6.滑动一个wIDth,菜单旋转两个单位角度
7.touch结束会自动调整位置,保证最前面位置有菜单项
8.滑动超过1/3单位角度会向前舍入
9.移动小于1/6单位角度会判定点击菜单
10.默认菜单大小不是全屏,而是屏幕的2/3,通过Node::setContentSize()设置
使用使用这个菜单只要知道两个函数
1.构造函数
RotateMenu::create()(由CREATE_FUNC创建)
2.添加MenuItem
voIDaddMenuItem(cocos2d::MenuItem*item);
其它函数可以看代码
相关参数的函数设置还未添加
代码声明
[cpp] view plain copy #ifndef__ROTA__TE_MENU_H__ #define__ROTA__TE_MENU_H__ #include"cocos2d.h" /* *模仿乱斗西游主界面的旋转菜单 */ classRotateMenu:publiccocos2d::Layer{ public: //构造方法 CREATE_FUNC(RotateMenu); //添加菜单项 voIDaddMenuItem(cocos2d::MenuItem*item); //更新位置 voIDupdateposition(); //更新位置,有动画 voIDupdatepositionWithAnimation(); //位置矫正修改角度forward为移动方向当超过1/3,进1 //true为正向false负 voIDrectify(boolforward); //初始化 virtualboolinit(); //重置 *** 作有旋转角度设为0 voIDreset(); private: //设置角度弧度 voIDsetAngle(floatangle); floatgetAngle(); //设置单位角度弧度 voIDsetUnitAngle(floatangle); floatgetUnitAngle(); //滑动距离转换角度,转换策略为移动半个Menu.wIDth等于_unitAngle floatdisToAngle(floatdis); //返回被选中的item cocos2d::MenuItem*getCurrentItem(); private: //菜单已经旋转角度弧度 float_angle; //菜单项集合,_children顺序会变化,新建数组保存顺序 cocos2d::Vector<cocos2d::MenuItem*>_items; //单位角度弧度 float_unitAngle; //监听函数 boolontouchBegan(cocos2d::touch*touch,cocos2d::Event*event); virtualvoIDontouchended(cocos2d::touch*touch,cocos2d::Event*event); voIDontouchmoved(cocos2d::touch*touch,0); background-color:inherit">//动画完结调用函数 voIDactionEndCallBack(floatdx); //当前被选择的item cocos2d::MenuItem*_selectedItem; //动画运行时间 floatanimationDuration=0.3f; }; #endif
实现
@H_233_502@copy #include"RotateMenu.h" #include<math.h> #definePIacos(-1) USING_NS_CC; boolRotateMenu::init(){ if(!Layer::init()) returnfalse; _angle=0.0; this->ignoreAnchorPointForposition(false); _selectedItem=nullptr; Sizes=Director::getInstance()->getWinSize(); this->setContentSize(s/3*2); this->setAnchorPoint(Vec2(0.5f,0.5f)); autoListener=EventListenertouchOneByOne::create(); Listener->ontouchBegan=CC_CALLBACK_2(RotateMenu::ontouchBegan,this); Listener->ontouchmoved=CC_CALLBACK_2(RotateMenu::ontouchmoved,153); Font-weight:bold; background-color:inherit">this); Listener->ontouchended=CC_CALLBACK_2(RotateMenu::ontouchended,248)"> getEventdispatcher()->addEventListenerWithSceneGraPHPriority(Listener,153); Font-weight:bold; background-color:inherit">true; voIDRotateMenu::addMenuItem(cocos2d::MenuItem*item){ item->setposition(this->getContentSize()/2); this->addChild(item); _items.pushBack(item); setUnitAngle(2*PI/_items.size()); reset(); updatepositionWithAnimation(); return; } voIDRotateMenu::updateposition(){ automenuSize=getContentSize(); autodisY=menuSize.height/8; autodisX=menuSize.wIDth/3; for(inti=0;i<_items.size();i++){ floatx=menuSize.wIDth/2+disX*sin(i*_unitAngle+getAngle()); floaty=menuSize.height/2-disY*cos(i*_unitAngle+getAngle()); _items.at(i)->setposition(Vec2(x,y)); _items.at(i)->setZOrder(-(int)y); //Opacity129~255 _items.at(i)->setopacity(192+63*cos(i*_unitAngle+getAngle())); _items.at(i)->setScale(0.75+0.25*cos(i*_unitAngle+getAngle())); } return; voIDRotateMenu::updatepositionWithAnimation(){ //先停止所有可能存在的动作 inti=0;i<_items.size();i++) _items.at(i)->stopAllActions(); automoveto=Moveto::create(animationDuration,Vec2(x,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _items.at(i)->runAction(moveto); autofadeto=Fadeto::create(animationDuration,(192+63*cos(i*_unitAngle+getAngle()))); _items.at(i)->runAction(fadeto); //缩放比例0.5~1 autoscaleto=Scaleto::create(animationDuration,0.75+0.25*cos(i*_unitAngle+getAngle())); _items.at(i)->runAction(scaleto); _items.at(i)->setZOrder(-(int)y); scheduleOnce(schedule_selector(RotateMenu::actionEndCallBack),animationDuration); voIDRotateMenu::reset(){ _angle=0; voIDRotateMenu::setAngle(floatangle){ this->_angle=angle; floatRotateMenu::getAngle(){ return_angle; voIDRotateMenu::setUnitAngle( _unitAngle=angle; floatRotateMenu::getUnitAngle(){ return_unitAngle; floatRotateMenu::disToAngle(floatdis){ floatwIDth=this->getContentSize().wIDth/2; returndis/wIDth*getUnitAngle(); MenuItem*RotateMenu::getCurrentItem(){ if(_items.size()==0) returnnullptr; //这里实际加上了0.1getAngle(),用来防止精度丢失 intindex=(int)((2*PI-getAngle())/getUnitAngle()+0.1*getUnitAngle()); index%=_items.size(); return_items.at(index); boolRotateMenu::ontouchBegan(touch*touch,Event*event){ if(_selectedItem) _selectedItem->unselected(); autoposition=this->convertToNodeSpace(touch->getLocation()); autosize=this->getContentSize(); autorect=Rect(0,size.wIDth,size.height); if(rect.containsPoint(position)){ true; false; voIDRotateMenu::ontouchended(touch*touch,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autoxDelta=touch->getLocation().x-touch->getStartLocation().x; rectify(xDelta>0); if(disToAngle(fabs(xDelta))<getUnitAngle()/6&&_selectedItem) _selectedItem->activate(); updatepositionWithAnimation(); voIDRotateMenu::ontouchmoved(touch*touch,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autoangle=disToAngle(touch->getDelta().x); setAngle(getAngle()+angle); updateposition(); voIDRotateMenu::rectify(boolforward){ autoangle=getAngle(); while(angle<0) angle+=PI*2; while(angle>PI*2) angle-=PI*2; if(forward>0) angle=((int)((angle+getUnitAngle()/3*2)/getUnitAngle()))*getUnitAngle(); else int)((angle+getUnitAngle()/3)/getUnitAngle()))*getUnitAngle(); setAngle(angle); voIDRotateMenu::actionEndCallBack(floatdx){ _selectedItem=getCurrentItem(); _selectedItem->selected(); }
一个糟糕的Demo
声明
@H_233_502@copy #ifndef__HELLOWORLD_SCENE_H__ #define__HELLOWORLD_SCENE_H__ classHelloWorld:publiccocos2d::Layer { //there'sno'ID'incpp,sowerecommendreturningtheclassinstancepointer staticcocos2d::Scene*createScene(); //Here'sadifference.Method'init'incocos2d-xreturnsbool,insteadofreturning'ID'incocos2d-iphone boolinit(); //aselectorcallback voIDmenuCloseCallback(cocos2d::Ref*pSender); voIDmenuItem1Callback(cocos2d::Ref*pSender); voIDmenuItem2Callback(cocos2d::Ref*pSender); voIDmenuItem3Callback(cocos2d::Ref*pSender); voIDmenuItem4Callback(cocos2d::Ref*pSender); voIDmenuItem5Callback(cocos2d::Ref*pSender); voIDhIDeAllSprite(); cocos2d::Sprite*sprite[5]; //implementthe"staticcreate()"methodmanually CREATE_FUNC(HelloWorld); #endif//__HELLOWORLD_SCENE_H__
声明
@H_233_502@copy #include"HelloWorldScene.h" #include"RotateMenu.h" USING_NS_CC; typedefstructSceneList{ constchar*name; std::function<cocos2d::Scene*()>callback; }SceneList; SceneListsceneList[]={ {"Demo1",[](){returnHelloWorld::createScene();}} constunsignedintsceneCount=sizeof(sceneList)/sizeof(SceneList); #defineliNE_SPACE40 Scene*HelloWorld::createScene() //'scene'isanautoreleaSEObject autoscene=Scene::create(); //'layer'isanautoreleaSEObject autolayer=HelloWorld::create(); //addlayerasachildtoscene scene->addChild(layer); //returnthescene returnscene; //on"init"youneedtoinitializeyourinstance boolHelloWorld::init() ////////////////////////////// //1.superinitfirst SizevisibleSize=Director::getInstance()->getVisibleSize(); Vec2origin=Director::getInstance()->getVisibleOrigin(); ///////////////////////////// //2.addamenuitemwith"X"image,whichisclickedtoquittheprogram //youmaymodifyit. //adda"close"icontoexittheprogress.it'sanautoreleaSEObject autocloseItem=MenuItemImage::create( "Closenormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback,153); Font-weight:bold; background-color:inherit">this)); closeItem->setposition(Vec2(origin.x+visibleSize.wIDth-closeItem->getContentSize().wIDth/2, origin.y+closeItem->getContentSize().height/2)); //createmenu,it'sanautoreleaSEObject /*automenu=Menu::create(closeItem,NulL); menu->setposition(Vec2::ZERO); this->addChild(menu,1);*/ autoitem1=MenuItemImage::create("Demo1/item1_1.png","Demo1/item1_0.png",CC_CALLBACK_1(HelloWorld::menuItem1Callback,this)); autoitem2=MenuItemImage::create("Demo1/item2_1.png","Demo1/item2_0.png",CC_CALLBACK_1(HelloWorld::menuItem2Callback,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autoitem3=MenuItemImage::create("Demo1/item3_1.png","Demo1/item3_0.png",CC_CALLBACK_1(HelloWorld::menuItem3Callback,248)"> autoitem4=MenuItemImage::create("Demo1/item4_1.png","Demo1/item4_0.png",CC_CALLBACK_1(HelloWorld::menuItem4Callback,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autoitem5=MenuItemImage::create("Demo1/item5_1.png","Demo1/item5_0.png",CC_CALLBACK_1(HelloWorld::menuItem5Callback,108); List-style:decimal-leading-zero outsIDe; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> RotateMenu*menu=RotateMenu::create(); menu->addMenuItem(item1); menu->addMenuItem(item2); menu->addMenuItem(item3); menu->addMenuItem(item4); menu->addMenuItem(item5); menu->setposition(visibleSize/2); this->addChild(menu,2); inti=0;i<5;i++){ charstr[20]; sprintf(str,"Demo1/item%d.jpg",i+1); sprite[i]=Sprite::create(str); sprite[i]->setAnchorPoint(Vec2(0.5f,0.5f)); sprite[i]->setposition(visibleSize/2); this->addChild(sprite[i]); hIDeAllSprite(); ///////////////////////////// //3.addyourcodesbelow... //addalabelshows"HelloWorld" //createandinitializealabel autolabel=LabelTTF::create("HelloWorld","Arial",24); //positionthelabelonthecenterofthescreen label->setposition(Vec2(origin.x+visibleSize.wIDth/2, origin.y+visibleSize.height-label->getContentSize().height)); //addthelabelasachildtothislayer this->addChild(label,1); voIDHelloWorld::menuCloseCallback(Ref*pSender) #if(CC_TARGET_PLATFORM==CC_PLATFORM_WP8)||(CC_TARGET_PLATFORM==CC_PLATFORM_WINRT) MessageBox("Youpressedtheclosebutton.windowsStoreAppsdonotimplementaclosebutton.","Alert"); #endif Director::getInstance()->end(); #if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS) exit(0); voIDHelloWorld::menuItem1Callback(cocos2d::Ref*pSender){ sprite[0]->setVisible(true); voIDHelloWorld::menuItem2Callback(cocos2d::Ref*pSender){ sprite[1]->setVisible(voIDHelloWorld::menuItem3Callback(cocos2d::Ref*pSender){ sprite[2]->setVisible(voIDHelloWorld::menuItem4Callback(cocos2d::Ref*pSender){ sprite[3]->setVisible(voIDHelloWorld::menuItem5Callback(cocos2d::Ref*pSender){ sprite[4]->setVisible(voIDHelloWorld::hIDeAllSprite(){ for(autop:sprite){ if(p->isVisible()) p->setVisible(false); }
@L_502_7@ 总结
以上是内存溢出为你收集整理的基于cocos2dx的伪立体菜单全部内容,希望文章能够帮你解决基于cocos2dx的伪立体菜单所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)