基于cocos2dx的英雄联盟皮肤选择菜单

基于cocos2dx的英雄联盟皮肤选择菜单,第1张

概述最终效果图 英雄联盟皮肤选择 设计说明 实现目标所需要的动作 移动(MoveTo),伸缩(ScaleTo),倾斜(OrbitCamera) 实现目标所需要函数(这是一个数学函数) x/(x+a) 其中a为常量,用来计算上面三个动作的值 大小 与原版Menu不同,大小不是全屏的,默认是屏幕的(2/3),可以通过setContentSize()函数设置 _index变量 将所有的菜单项平铺构成一个长方 最终效果图 英雄联盟皮肤选择


设计说明 实现目标所需要的动作

移动(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

voIDaddMenuItem(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);	//更新位置	voID updateposition();	//更新位置,有动画	voID updatepositionWithAnimation();	//位置矫正  修改位置forward为移动方向  当超过1/3,进1	//true 为正向  false 负	voID rectify(bool forward);	//初始化	virtual bool init();	//重置  显示所引号设置为0	voID reset();private:	//设置当前显示索引	voID setIndex(int index);	//设置当前显示菜单项的索引号	float getIndex();	//返回被选中的item	cocos2d::MenuItem * getCurrentItem();	//数学计算式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,calcFunction(i - _lastIndex,MENU_ASLOPE),MENU_ASLOPE) - calcFunction(i - _index,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,calcFunction(i - _index,MENU_ASLOPE) - calcFunction(i - _lastIndex,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,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.h
#ifndef __LolMenu_SCENE_H__#define __LolMenu_SCENE_H__#include "cocos2d.h"class LolMenuDemo : public cocos2d::Layer{public:	// there's no 'ID' in cpp,so we recommend returning the class instance pointer	static cocos2d::Scene* createScene();	// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'ID' in cocos2d-iphone	virtual bool init();	// a selector callback	voID menuCloseCallback(cocos2d::Ref* pSender);	voID menuItem1Callback(cocos2d::Ref* pSender);	voID menuItem2Callback(cocos2d::Ref* pSender);	voID menuItem3Callback(cocos2d::Ref* pSender);	voID menuItem4Callback(cocos2d::Ref* pSender);	voID menuItem5Callback(cocos2d::Ref* pSender);	voID hIDeAllSprite();	cocos2d::Sprite *sprite[5];	// implement the "static create()" method manually	CREATE_FUNC(LolMenuDemo);};#endif // __HELLOWORLD_SCENE_H__

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 instancebool 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);	for (int i = 0; i < 5; i++){		char str[100];		sprintf(str,"4_Lol_MENU/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();	return true;}voID LolMenuDemo::menuCloseCallback(Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)	MessageBox("You pressed the close button. windows Store Apps do not implement a close button.","Alert");	return;#endif	Director::getInstance()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)	exit(0);#endif}voID LolMenuDemo::menuItem1Callback(cocos2d::Ref* pSender){	hIDeAllSprite();	sprite[0]->setVisible(true);}voID LolMenuDemo::menuItem2Callback(cocos2d::Ref* pSender){	hIDeAllSprite();	sprite[1]->setVisible(true);}voID LolMenuDemo::menuItem3Callback(cocos2d::Ref* pSender){	hIDeAllSprite();	sprite[2]->setVisible(true);}voID LolMenuDemo::menuItem4Callback(cocos2d::Ref* pSender){	hIDeAllSprite();	sprite[3]->setVisible(true);}voID LolMenuDemo::menuItem5Callback(cocos2d::Ref* pSender){	hIDeAllSprite();	sprite[4]->setVisible(true);}voID LolMenuDemo::hIDeAllSprite(){	for (auto p : sprite){		if (p->isVisible())			p->setVisible(false);	}}


可运行的程序(需要安装vs2013或相关dll文件)

所有源代码


有任何问题可以发邮件给我 810278677@qq.com
PS 这种类型的菜单在网页里会常见一些,比如优酷的动漫专题或者App Store都可以看到类似的影子,由于是平面的,菜单项的切换不是很自然,我通过倾斜来变得自然。 总结

以上是内存溢出为你收集整理的基于cocos2dx的英雄联盟皮肤选择菜单全部内容,希望文章能够帮你解决基于cocos2dx的英雄联盟皮肤选择菜单所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1043622.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存