当前位置: 首页>C语言>正文

基于Cocos2d-x的英雄聯盟皮膚選擇菜單

基于Cocos2d-x的英雄聯盟皮膚選擇菜單

最終效果圖


英雄聯盟皮膚選擇


設計說明

實現目標所需要的動作

移動(MoveTo),伸縮(ScaleTo),傾斜(OrbitCamera)


實現目標所需要函數(這是一個數學函數)

x/(x+a)

其中a為常量,用來計算上面三個動作的值


大小

與原版Menu不同,大小不是全屏的,默認是屏幕的(2/3),可以通過setContentSize()函數設置


_index變量

將所有的菜單項平鋪構成一個長方形,_index表示目前在中間位置的點,如下圖


顯示方式

將菜單項距中心的距離(i-_indxe)作為函數變量x,具體內容查看LOLMenu::updatePosition();


操作說明

滑動四分之一菜單寬的距離為一個單位的_index,距離大于0.6小于1.0的部分進1


使用

使用這個菜單只要知道兩個函數:

1.構造函數:LOLMenu::create()(由CREATE_FUNC創建)

2.添加MenuItem:void addMenuItem(cocos2d::MenuItem *item);


其它函數可以看代碼


菜單代碼

LOLMenu.h

#ifndef?__LOL__TE_MENU_H__??
#define?__LOL__TE_MENU_H__??
#include?"cocos2d.h"??
/*?
*模仿英雄聯盟的皮膚選擇菜單?
*不同點在于,英雄聯盟當皮膚過多時,部分皮膚會移出邊緣,不顯示?
*我會顯示所以菜單項,向邊緣移動會不斷減緩?
*/??
class?LOLMenu?:public?cocos2d::Layer{??
????public:??
????????//構造方法??
????????CREATE_FUNC(LOLMenu);??
????????//添加菜單項??
????????void?addMenuItem(cocos2d::MenuItem?*item);?
????????//位置矯正??修改位置forward為移動方向??當超過1/3,進1??
????????//true?為正向??false?負??
????????void?rectify(bool?forward);??
????????//初始化??
????????virtual?bool?init();??
????????//重置??顯示所引號設置為0??
????????void?reset();??
? //設置當前顯示索引??
??????void?setIndex(int?index);??
??????//設置當前顯示菜單項的索引號??
??????float?getIndex();??
??????//返回被選中的item??
????????cocos2d::MenuItem?*?getCurrentItem();?
????private:??
? //更新位置??
??????void?updatePosition();??
??????//更新位置,有動畫??
??????void?updatePositionWithAnimation();??
????????//數學計算式width*index/(abs(index)+CALC_A)?,其中CALC_A為常數??
????????float?calcFunction(float?index,?float?width);??
????private:??
????????//菜單菜單項的索引號??
????????float?_index;??
????????//上一次菜單項的索引號??
????????float?_lastIndex;??
????????//菜單項集合,_children順序會變化,新建數組保存順序??
????????cocos2d::Vector<cocos2d::MenuItem?*>?_items;??
????????//監聽函數??
????????virtual?bool?onTouchBegan(cocos2d::Touch*?touch,?cocos2d::Event*?event);??
????????virtual?void?onTouchEnded(cocos2d::Touch*?touch,?cocos2d::Event*?event);??
????????virtual?void?onTouchMoved(cocos2d::Touch*?touch,?cocos2d::Event*?event);??
????????//動畫完結調用函數,這個主要是確定哪一個菜單項在前面??
????????void?actionEndCallBack(float?dx);??
????????//當前被選擇的item??
????????cocos2d::MenuItem?*_selectedItem;??
};??
#endif

LOLMenu.cpp

#include?"LOLMenu.h"??
#include?<math.h>??
#define?PI?acos(-1)??
//菜單的縮小比例?最小的比例是1-MENU_SCALE??
#define?MENU_SCALE?0.3??
//菜單的傾斜度?最多為45度??
#define?MENU_ASLOPE?60.0??
//calcFunction(x)?為?x/(x+a),其中a為常數??
#define?CALC_A?1??
//動畫運行時間??
#define?ANIMATION_DURATION??0.3f???
//菜單項的大小與屏幕的比例,當然可以通過setContentSize設置??
#define?CONTENT_SIZE_SCALE?(2.0/3)??
//菜單項長度與菜單長度的比例?滑動一個菜單項長度,菜單項變化一個??
#define?ITEM_SIZE_SCALE?(1.0/4)??
/*?
????代碼里面還有可以設置的參數,這里沒有一一例出或給出函數?
????*/??
USING_NS_CC;??
bool?LOLMenu::init(){??
????if?(!Layer::init())??
????????return?false;??
????_index=0;??
????_lastIndex?=?0;??
????this->ignoreAnchorPointForPosition(false);??
????_selectedItem?=?nullptr;??
????auto?size?=?Director::getInstance()->getWinSize();??
????this->setContentSize(size*CONTENT_SIZE_SCALE);??
????this->setAnchorPoint(Vec2(0.5f,?0.5f));??
????auto?listener?=?EventListenerTouchOneByOne::create();??
????listener->onTouchBegan?=?CC_CALLBACK_2(LOLMenu::onTouchBegan,?this);??
????listener->onTouchMoved?=?CC_CALLBACK_2(LOLMenu::onTouchMoved,?this);??
????listener->onTouchEnded?=?CC_CALLBACK_2(LOLMenu::onTouchEnded,?this);??
????getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,?this);??
????return?true;??
};??
???
void?LOLMenu::addMenuItem(cocos2d::MenuItem?*item){??
????item->setPosition(this->getContentSize()?/?2);??
????this->addChild(item);??
????_items.pushBack(item);??
????reset();??
????//如果希望開始沒有移動效果,改成updatePosition函數即可??
????updatePositionWithAnimation();??
????return;??
}??
void?LOLMenu::updatePosition(){??
????auto?menuSize?=?getContentSize();??
????for?(int?i?=?0;?i?<?_items.size();?i++){??
????????//設置位置??
????????float?x?=?calcFunction(i?-?_index,?menuSize.width?/?2);??
????????_items.at(i)->setPosition(Vec2(menuSize.width/2+x,?menuSize.height/2));??
????????//設置zOrder,即繪制順序??
????????_items.at(i)->setZOrder(-abs((i?-?_index)?*?100));??
????????//設置伸縮比例??
????????_items.at(i)->setScale(1.0-abs(calcFunction(i?-?_index,?MENU_SCALE)));??
????????//設置傾斜,Node沒有setCamera函數,將OrbitCamera的運行時間設為0來達到效果??
????????auto?orbit1?=?OrbitCamera::create(0,?1,?0,?calcFunction(i?-?_lastIndex,?MENU_ASLOPE),?calcFunction(i?-?_lastIndex,?MENU_ASLOPE)?-?calcFunction(i?-?_index,?MENU_ASLOPE),?0,?0);??
????????_items.at(i)->runAction(orbit1);??
????}??
????return;??
}??
void?LOLMenu::updatePositionWithAnimation(){??
????//先停止所有可能存在的動作??
????for?(int?i?=?0;?i?<?_items.size();?i++)??
????????_items.at(i)->stopAllActions();??
????auto?menuSize?=?getContentSize();??
????for?(int?i?=?0;?i?<?_items.size();?i++){??
????????_items.at(i)->setZOrder(-abs((i?-?_index)*100));??
????????float?x?=?calcFunction(i?-?_index,?menuSize.width?/?2);??
????????auto?moveTo?=?MoveTo::create(ANIMATION_DURATION,?Vec2(menuSize.width?/?2?+?x,?menuSize.height?/?2));??
????????_items.at(i)->runAction(moveTo);??
????????auto?scaleTo?=?ScaleTo::create(ANIMATION_DURATION,?(1?-?abs(calcFunction(i?-?_index,?MENU_SCALE))));??
????????_items.at(i)->runAction(scaleTo);??
????????auto?orbit1?=?OrbitCamera::create(ANIMATION_DURATION,?1,?0,?calcFunction(i?-?_lastIndex,?MENU_ASLOPE),?calcFunction(i?-?_index,?MENU_ASLOPE)?-?calcFunction(i?-?_lastIndex,?MENU_ASLOPE),?0,?0);??
????????_items.at(i)->runAction(orbit1);??
????}??
????scheduleOnce(schedule_selector(LOLMenu::actionEndCallBack),?ANIMATION_DURATION);??
????return;??
}??
void?LOLMenu::reset(){??
????_lastIndex?=?0;??
????_index?=?0;??
}??
void?LOLMenu::setIndex(int?index){??
????_lastIndex?=?_index;??
????this->_index?=?index;??
}??
float?LOLMenu::getIndex(){??
????return?_index;??
}??
???
???
???
MenuItem?*?LOLMenu::getCurrentItem(){??
????if?(_items.size()?==?0)??
????????return?nullptr;??
????return?_items.at(_index);??
}??
???
???
bool?LOLMenu::onTouchBegan(Touch*?touch,?Event*?event){??
????//先停止所有可能存在的動作??
????for?(int?i?=?0;?i?<?_items.size();?i++)??
????????_items.at(i)->stopAllActions();??
????if?(_selectedItem)??
????????_selectedItem->unselected();??
????auto?position?=?this->convertToNodeSpace(touch->getLocation());??
????auto?size?=?this->getContentSize();??
????auto?rect?=?Rect(0,?0,?size.width,?size.height);??
????if?(rect.containsPoint(position)){??
????????return?true;??
????}??
????return?false;??
}??
void?LOLMenu::onTouchEnded(Touch*?touch,?Event*?event){??
????auto?size?=?getContentSize();??
????auto?xDelta?=?touch->getLocation().x?-?touch->getStartLocation().x;??
????rectify(xDelta>0);??
????if?(abs(xDelta)<size.width?/?24?&&?_selectedItem)??
????????_selectedItem->activate();??
????updatePositionWithAnimation();??
????return;??
}??
void?LOLMenu::onTouchMoved(Touch*?touch,?Event*?event){??
????auto?xDelta?=?touch->getDelta().x;??
????auto?size?=?getContentSize();??
????_lastIndex?=?_index;??
????_index?-=?xDelta?/?(size.width?*ITEM_SIZE_SCALE);??
????updatePosition();??
????return;??
}??
???
void?LOLMenu::rectify(bool?forward){??
????auto?index?=?getIndex();??
????if?(index?<?0)??
????????index?=?0;??
????if?(index>_items.size()?-?1)??
????????index?=?_items.size()?-?1;??
????if?(forward){??
????????index?=?(int)(index?+?0.4);??
????}??
????else??
????????index?=?(int)(index?+?0.6);??
????setIndex((int)index);??
}??
???
void?LOLMenu::actionEndCallBack(float?dx){??
????_selectedItem?=?getCurrentItem();??
????if?(_selectedItem)??
????????_selectedItem->selected();??
}??
???
float?LOLMenu::calcFunction(float?index,?float?width){??
????return?width*index?/?(abs(index)?+?CALC_A);??
}
LOLMenuDemo.cpp

#include?"LOLMenuDemo.h"??
#include?"LOLMenu.h"??
???
???
USING_NS_CC;??
???
Scene*?LOLMenuDemo::createScene()??
{??
????//?'scene'?is?an?autorelease?object??
????auto?scene?=?Scene::create();??
???
????//?'layer'?is?an?autorelease?object??
????auto?layer?=?LOLMenuDemo::create();??
???
????//?add?layer?as?a?child?to?scene??
????scene->addChild(layer);??
???
????//?return?the?scene??
????return?scene;??
}??
???
//?on?"init"?you?need?to?initialize?your?instance??
bool?LOLMenuDemo::init()??
{??
????//??
????//?1.?super?init?first??
????if?(!Layer::init())??
????{??
????????return?false;??
????}??
???
????Size?visibleSize?=?Director::getInstance()->getVisibleSize();??
????Vec2?origin?=?Director::getInstance()->getVisibleOrigin();??
???
????auto?item1?=?MenuItemImage::create("4_LOL_MENU/item1_0.png",?"4_LOL_MENU/item1_0.png",?CC_CALLBACK_1(LOLMenuDemo::menuItem1Callback,?this));??
????auto?item2?=?MenuItemImage::create("4_LOL_MENU/item2_0.png",?"4_LOL_MENU/item2_0.png",?CC_CALLBACK_1(LOLMenuDemo::menuItem2Callback,?this));??
????auto?item3?=?MenuItemImage::create("4_LOL_MENU/item3_0.png",?"4_LOL_MENU/item3_0.png",?CC_CALLBACK_1(LOLMenuDemo::menuItem3Callback,?this));??
????auto?item4?=?MenuItemImage::create("4_LOL_MENU/item4_0.png",?"4_LOL_MENU/item4_0.png",?CC_CALLBACK_1(LOLMenuDemo::menuItem4Callback,?this));??
????auto?item5?=?MenuItemImage::create("4_LOL_MENU/item5_0.png",?"4_LOL_MENU/item5_0.png",?CC_CALLBACK_1(LOLMenuDemo::menuItem5Callback,?this));??
???
????LOLMenu?*menu?=?LOLMenu::create();??
???
????menu->addMenuItem(item1);??
????menu->addMenuItem(item2);??
????menu->addMenuItem(item3);??
????menu->addMenuItem(item4);??
????menu->addMenuItem(item5);??
???
????menu->setPosition(visibleSize?/?2);??
????this->addChild(menu,?2);??
???
????return?true;??
}??
void?LOLMenuDemo::menuItem1Callback(cocos2d::Ref*?pSender){????
????sprite[0]->setVisible(true);??
}??
void?LOLMenuDemo::menuItem2Callback(cocos2d::Ref*?pSender){??
????sprite[1]->setVisible(true);??
}??
void?LOLMenuDemo::menuItem3Callback(cocos2d::Ref*?pSender){??
????sprite[2]->setVisible(true);??
}??
void?LOLMenuDemo::menuItem4Callback(cocos2d::Ref*?pSender){??
????sprite[3]->setVisible(true);??
}??
void?LOLMenuDemo::menuItem5Callback(cocos2d::Ref*?pSender){????
????sprite[4]->setVisible(true);??
}??
可以通過 getIndex()函數獲取到當前正在顯示的是那個頁面,最左端頁面的index為0,次著index為1,以此類推疊加。

PS.這種類型的菜單在網頁里會常見一些,比如優酷的動漫專題或者App Store都可以看到類似的影子,由于是平面的,菜單項的切換不是很自然,我通過傾斜來變得自然。

https://www.zydui.com/afaa4UG8CDQ9VAF4E.html
>

相关文章:

  • 詳解PyTorch中的contiguous
  • PyTorch中的contiguous解讀
  • Pytorch中contiguous()函數理解
  • ios自定義UITabBar-仿寫掌上英雄聯盟的UITabBar
  • 基于Cocos2d-x的英雄聯盟皮膚選擇菜單
  • lol-登陸英雄聯盟出錯
  • JS中雙層for循環執行順序
  • 關于for循環執行順序
  • 上古卷軸5boss計算機丟失,上古卷軸5常見BUG解決辦法
  • 上古世紀服務器維護真情禮,4月9日例行維護懷舊服合服公告
  • 塔羅牌張數
  • 工程管理中的工程技術
  • 銳派出品:LOL新年特輯S4各類細節之下路篇
  • 藍城兄弟Q4業績背后,垂直社區具備多少想象力?
  • Mac OS啟動服務優化高級篇(launchd tuning)
  • #Geek Point# 為什么現在要去印度看一看?
  • vm 流程運行mac os_什么是“商務”流程,為什么在我的Mac上運行?
  • # 陌生人社交產品:需求、困境與破局之道
  • mac 不受信任在哪里更改_什么是受信任的,為什么它可以在Mac上運行?
  • 車行軌跡分類實踐
  • 智慧車行預約小程序 v9.1
  • i12藍牙耳機充電倉怎么看充滿電_車行藍牙耳機價格高性價比的選擇
  • 車行平安
  • 論文閱讀——《基于卷積神經網絡的車行環境多類障礙物檢測與識別》
  • 飛槳開發者創意薈:PaddleHub一鍵部署,AI創意實現原來如此簡單
  • eclipse左側欄目即包資源管理器怎么打開
  • 卷毛機器人符文_卷毛S6娜美輔助天賦 娜美輔助符文天賦S6最新
  • 天賦介紹
  • 蘋果怎么沒有4g信號還無服務器,不顯示4g信號怎么回事?蘋果手機不顯示4g信號的解決方法...
  • c4D體積生成和Quad Remesher重新拓撲減面插件