使用Cocos2d-x中的CCMenuItemToggle制作商店

cocos2dx 完整商业版三消类游戏源码 cocos2dx2.2.3环境 完整商业版三消游戏源码 是学习的最佳实例 立即下载

最近一直在和同学用Cocos2d-x做一款手机游戏,期间做过一个商店的功能,在此写一篇关于使用CCMenuItemToggle来实现商店标签功能。

首先把效果发出来,资源是用的《Banana Kong》的图片,上面的字是自己加的:(W == Weapon,H == Hat, I == Inventory, S == Skill)

达到以下几个效果:

1. 进入商店默认“W标签“是选中状态

2. 点击其他的标签后,前一个标签自动还原

3. 点击一个标签,弹出属于这个标签的元素


刚开始做的时候遇到了很多问题,想过用CCMenuItem,但是CCMenuitem的按下和弹起操作时一次性完成的,并且已经封装,网上有继承CCMenuItem重写的方法,感觉比较复杂。之后想过用CCSprite直接写精灵点击事件,结果也是遇到了一些麻烦,最终用CCMenuItemToggle写了出来,如果大家有什么更好的办法写出这个效果,欢迎拍砖!


然后我们来看创建一个CCMenuItemToggle需要的步骤:

CCMenuItemImage* toggleNormal = CCMenuItemImage::create("toggleNormal", "toggleSelect"); // 未点击时的图片
CCMenuItemImage* toggleSelect = CCMenuItemImage::create("toggleSelect", "toggleNormal"); // 点击后的图片
CCMenuItemToggle* myToggle = CCMenuItemToggle::createWithTarget(this,selector,toggleNormal,toggleSelect,NULL);// 使用以上两个图片菜单创建一个开关菜单

这样就创建了一个开关菜单(Toggle == "开关")。当然最后还要传入CCMenu中。


这里又有几点需要讲的:

1. 从这三句代码可以看到如果要创建CCMenuItemToggle的话首先要创建多个CCMenuItemImage,其实也可以是其他菜单项,我们这里只讲用图片创建。想要看其他创建方式以及想要深入研究的可以看源码,这里不赘述。

2. CCMenuItemToggle::createWithTarget(this, selector, imgNormal, imgSelect, NULL); 从这一句最后的参数NULL可以看出还可以继续添加菜单,创建出多选项开关菜单。同样,我们只需要两个图片。

3. 参数selector是回调函数。

如果我们就这样实现标签效果的话,意味着我们将写四遍上述代码,还要控制他们的位置等等,这样我们就理所当然的想到了将其封装成一个函数。我们定义这样一个函数,用来专门创建开关按钮。

CCMenuItemToggle* HShop::createToggle(SEL_MenuHandler selector, char * fileNameNormal, char * fileNameSelect)
{
    CCMenuItemImage* imgNormal = CCMenuItemImage::create(fileNameNormal, fileNameSelect);
    CCMenuItemImage* imgSelect = CCMenuItemImage::create(fileNameSelect, fileNameNormal);
    CCMenuItemToggle* imgToggle = CCMenuItemToggle::createWithTarget(this, selector, imgNormal, imgSelect, NULL);
    return imgToggle;
}

于是我们就可以这样创建标签:

wToggle = HShop::createToggle(menu_selector(HShop::toggleIsPressed), fileNameNormal, fileNameSelect);// HShop是商店类

hToggle = HShop::createToggle(menu_selector(HShop::toggleIsPressed), fileNameNormal, fileNameSelect);

iToggle = HShop::createToggle(menu_selector(HShop::toggleIsPressed), fileNameNormal, fileNameSelect);

sToggle = HShop::createToggle(menu_selector(HShop::toggleIsPressed), fileNameNormal, fileNameSelect);

但是这样依然比较麻烦,这四个标签的位置是有规律的,如果我们将他们使用的图片的文件名改得有规律一点,就可以用一个for循环控制。并且将toggle改为数组形式

于是修改后的代码如下:


// 创建商店里的标签
for(int i = 0; i < AllToggle; i++)
{
    char fileNameNormal[50];	// 未选中图片的文件名
    char fileNameSelect[50];	// 选中图片的文件名
    sprintf(fileNameNormal, "Toggle_Normal%d.png", i);
    sprintf(fileNameSelect, "Toggle_Select%d.png", i);
    toggle[i] = HShop::createToggle(menu_selector(HShop::toggleIsPressed), fileNameNormal, fileNameSelect);
    toggle[i]->setTag(i);	// 为每个标签设置Tag值
    float padding = 4;		// 标签之间的间隔
    toggle[i]->setPosition(ccp(48 + toggle[0]->getContentSize().width/2, (visibleSize.height/2 + 3 * (padding + toggle[0]->getContentSize().height)/2) - (toggle[0]->getContentSize().height + padding) * i));	// 标签位置,这个大家自己调一下,因为visibleSize是为了适应分辨率专写的
    double f = CCDirector::sharedDirector()->getContentScaleFactor();	// 调整一下大小,这个大家看情况
}
toggle[weaponToggle]->setSelectedIndex(1);	// 我们刚进入的时候武器标签是被选中的
toggle[weaponToggle]->setEnabled(false);	// 选中的标签不能再点击
CCMenu *toggleMenu = CCMenu::create(toggle[0], toggle[1], toggle[2], toggle[3], NULL);	// 加入到CCMenu对象中
toggleMenu->setAnchorPoint(ccp(0, 0));
toggleMenu->setPosition(ccp(origin.x, origin.y - 1));
this->addChild(toggleMenu, 0);



1. 这里我把需要的文件都改为Toggle_NormalX.png这种形式的(X代表数字),这样就可以用for循环控制载入相应图片。

2. 使用setSelectedIndex(int n)函数可以把标签设置为需要的状态,n对应的即是函数CCMenuItemToggle* imgToggle = CCMenuItemToggle::createWithTarget(this, selector, imgNormal, imgSelect, NULL);中从第三个参数到之后的各种状态

接下来我们就可以点击各种标签了,并且被点击后的标签不能再被点击(实现选中状态),但是现在呈现的状态确实这样的

这样明显是不对的,应该点击了”I标签“后,”W标签“应该恢复,于是剩下的操作我们就在回调函数toggleIsPressed()中进行操作,先贴代码:

void HShop::toggleIsPressed(CCObject * menuItem)
{
	CCMenuItemToggle* tmp = (CCMenuItemToggle*)menuItem;

	switch(tmp->getTag())
	{
	case weaponToggle:
		toggle[weaponToggle]->setEnabled(false);
		toggle[hatToggle]->setSelectedIndex(0);			toggle[hatToggle]->setEnabled(true);
		toggle[inventoryToggle]->setSelectedIndex(0);	toggle[inventoryToggle]->setEnabled(true);
		toggle[skillToggle]->setSelectedIndex(0);		toggle[skillToggle]->setEnabled(true);
		
		break;
	case hatToggle:
		toggle[hatToggle]->setEnabled(false);
		toggle[weaponToggle]->setSelectedIndex(0);		toggle[weaponToggle]->setEnabled(true);
		toggle[inventoryToggle]->setSelectedIndex(0);	toggle[inventoryToggle]->setEnabled(true);
		toggle[skillToggle]->setSelectedIndex(0);		toggle[skillToggle]->setEnabled(true);
		
		break;
	case inventoryToggle:
		toggle[inventoryToggle]->setEnabled(false);
		toggle[weaponToggle]->setSelectedIndex(0);		toggle[weaponToggle]->setEnabled(true);
		toggle[hatToggle]->setSelectedIndex(0);			toggle[hatToggle]->setEnabled(true);
		toggle[skillToggle]->setSelectedIndex(0);		toggle[skillToggle]->setEnabled(true);
		mc->createInventoryCard();
		CCScrollView* tem= (CCScrollView*)this->getChildByTag(1);
		tem->setContentOffset(ccp(0, -(containLayer->getContentSize().height - MYSCROLLVIEW_HEIGHT)), true);
		break;
	case skillToggle:
		toggle[skillToggle]->setEnabled(false);
		toggle[weaponToggle]->setSelectedIndex(0);		toggle[weaponToggle]->setEnabled(true);
		toggle[hatToggle]->setSelectedIndex(0);			toggle[hatToggle]->setEnabled(true);
		toggle[inventoryToggle]->setSelectedIndex(0);	toggle[inventoryToggle]->setEnabled(true);
		
		break;
	default:
		break;
	}
}


这样,用一个switch语句分别处理这四个标签被按下后的操作,他们的操作都可以总结为:

1. 被点击后不能再进行点击 toggle[XXX]->setEnabled(false);

2. 之前被点击的标签应该复原 toggle[XXX]->setSelectedIndex(0);

其实第二点是可以优化的,我的代码写得非常冗余——点击一个菜单,要复原其他三个菜单。之前我想过用一些方法解决,但是都出了一些莫名其妙的问题,具体我猜是回调函数里这个CCObject * menuItem参数的问题,我使用CCMenuItemToggle* tmp来操作被点击的Toggle总是出问题,如果有哪位大侠解决了的话希望不吝赐教!


这样就实现了我们的标签功能,差不多就这样吧,欢迎拍砖!

相关推荐

ChatGPT高效制作PPT:从内容生成到设计优化全流程

人工智能技术正在改变传统办公文档的创作方式,其中自然语言处理(NLP)与生成式AI的结合为内容创作带来了革命性突破。以ChatGPT为代表的大语言模型(LLM)能够理解复杂指令并生成结构化内容,其核心原理是通过海量数据训练获得的语义理解和文本生成能力。在办公自动化场景中,这种技术特别适合解决PPT制作中的两大痛点:内容创作耗时和逻辑架构困难。通过精心设计的提示词工程,AI可以快速输出包含核心要点、数据支撑的完整内容框架,甚至直接生成Markdown格式的代码以便快速转换为PPT。对于商业计划、项目汇报等高频

weixin_42613018的博客 495

cocos2dx之商店源码

function shopLayer.initShopGoods(iTabelIndex) -- body print("---- Enter shopLayer.initShopGoods ----") --高亮选中项 shopLayer._shopTabel[iTabelIndex]._Selected:setVisible(true) shop

专注,努力,勤奋 1983

软件工程实验报告--用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

m0_73814332的博客 4169

[cocos2d-x]飞机大战 遇到的bug和总结(二)

第一点 声音文件最好不要使用mp3格式,因为我在同时使用背景音乐和playeffect()的时候,出现了bug,两者的音效不能同时出现(应该是格式问题),并且声音在windows上运行的时候加载非常慢(当然也可以通过提前加载实现)。 另外推荐一个免费的在线音频视...

weixin_30402343的博客 165

GhidraMCP:AI驱动的逆向工程革命——让LLM自主操作Ghidra进行自动化分析

(Ghidra Machine Control Protocol)应运而生,它通过将LLM与Ghidra(美国NSA开源逆向工具)结合,实现了AI驱动的自动化逆向工程流程。逆向工程是软件安全、漏洞分析和代码审计的核心环节,但传统方法依赖人工分析,耗时且易出错。未来,随着LLM技术的演进和逆向工程工具的优化,GhidraMCP有望成为安全研究人员和开发者的核心工具,推动逆向工程进入“AI辅助时代”。GhidraMCP通过LLM与Ghidra的深度整合,重新定义了逆向工程的自动化边界。

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 2119

硬件基础知识-电机知识

步进电机存在空载启动频率,所以步进电机可以低速正常运转,但若高于一定速度时就无法启动,并伴有尖锐的啸叫声;在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数。给电机两根线供电,电机就可以旋转,给正电压,电机正转,给相反电压,电机反转;电压越大,电机转得越快,电压越小,转速也变小。是一种直流电机,有刷电机的定子上安装有固定的主磁极和电刷,转子上安装有电枢绕组和换向器。控制器:使用专用的电子控制器来监测和控制电机的转速、电流和方向。线圈电流方向的交替变化是随电机转动的换相器和电刷来完成的。

weixin_46969363的博客 2299

用cocos2dx3.1的MenuItemToggle写一个会跳动音乐开关按钮

第一步: 在.h文件中声明三个全局变量,和一个菜单的回调函数即: MenuItemImage* musicon; MenuItemImage* musicoff; MenuItemToggle* h; void music(Ref* pSender); 第二步: 到.cpp文件中初始化那三个全局变量: musicon = MenuItemImage::create("musicon

cwyzb的博客 848

Android PMS——概述(一)

PMS(Package Manager Service)是 Android 操作系统的一个重要组件,它负责管理应用程序的包信息以及与应用程序的安装、卸载、权限控制等相关功能,确保应用程序的安全性和稳定性。 Android PMS 负责维护一个应用程序包的清单信息,该清单是一个 XML 文件,包含应用程序的各种元数据,例如应用程序的包名、版本号、权限要求、组件信息等。PMS通过访问该清单文件来获取应用程序的信息。 此外,Android PMS 还负责应用程序的安装和卸载。在安装应用

小旭的专栏 1669

cocos2d做开关按钮

这个可以作为CCmenu的一个item,和CCMenuItemSprite一起使用 不同的是,CCMenuItemToggle在点击之后,可以变化图片 CCSprite* pauseNormalSprite1 = [CCSprite spriteWithSpriteFra

bestandroid的专栏 1203

VMware ESXi 直通GPU

虚拟机需要独享GPU资源,那么就需要用到DirectPath I/O (直通),ESXi hypervisor 把 GPU 设备直接映射成虚机中的 GPU 设备,供应用使用。注意,内存注意一定要勾选预留,否则开机后报错如下:无法打开虚拟机 win10 的电源。1.ESXi主机,管理,硬件,PCI设备,勾选GPU卡,切换直通,会提示要求重启主机,重启主机之后,该GPU设备直通一栏显示为“活动”。先确认虚拟机是否EFI引导:编辑虚拟机 - 虚拟机选项 - 引导选项 - 固件 - EFI。

liwension的博客 6296

一种抑制undershoot/overshoot锐化算法介绍

一、USM 当增强图像的边缘、细节信息等高频信息时,图像的锐化视觉效果会得到较大提升。提高图像锐化的一种经典算法为非锐化掩码(UNsharp Masking)技术。该技术首先通过高通滤波并与缩放系数相乘,其结果再与原始图像相加,即可对高频信息进行增强。其主要的原理如下图所示: 其中,对图像进行高通滤波的另一种等效方法为:原始图像减去原始图像的低通滤波图像,其结果被称之为“掩码”。因此,上述的USM方法可以表示为: 原始图像减去原始图像低通滤波之后的图像得到掩码M。 2.掩...

大熊 4242

Cocos studio sample讲解 DemoShop商店界面

cocostuido sample----DemoShop源代码地址   https://github.com/chukong/CocoStudioSamples  大家可以预先下载这个源代码, 本教程所有内容均包含在内    一、目标  本节目标是做一个商店界面,包括商品的展示和购买,用户的交互以及动态改变购买的物品属性。效果如下图:           二、分析界面  本

yejian2011的专栏 1930

基于STM32设计的万能红外遥控器(学习型)

当前介绍了一种基于STM32微控制器设计的红外遥控器,支持接收解码功能和发送功能,可以将接收的码原样发送出去。 红外遥控器作为智能设备控制方式之一,在一定程度上满足了人们对于快速方便控制的需求。 当前设计的红外遥控器支持学习模式和发送模式。通过矩阵键盘上的数字键选择发送对应的控制码。 一共支持学习10个控制码,对应矩阵键盘上的数字。0~9。

6559

从零开始学习cocoStudio(8)--商城

游戏商城:主要提供装备以及道具的购买。 一、本博客主要实现的功能: 1.商品列表显示 2.购买商品(可按数量购买) 二、Cocostudio的UI设计 三、代码 CocosGUIExamplesWeaponScene.h #ifndef __TestCpp__CocosGUIExamp

小枫的专栏 3213

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

1.cocos2dx之Menu(CCMenuItemFont,CCMenuItemImage,CCMenuItemLabel,CCMenuItemSprite,CCMenuItemToggle)

 CCMenu 基本结构 CCMenu继承自CCLayer,本质是一个容器。需要被addChild到父类中去。 CCMenuItem是菜单项,它有如下子类: CCMenuItemFont;CCMenuItemImage;CCMenuItemLabel;CCMenuItemSprite;CCMenuItemToggle; 是真正的需要实例化的菜

涂作权的博客 2421

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

cocos creator下载扩展商店里的源码

首先,随便新建个项目或者打开存在的项目 然后点击菜单栏的扩展-》扩展商店 然后就可以尽情下载源码啦! 注意,mac下载的源码路径在用户的隐藏目录cd ~/.CocosCreator/

小菜希的Blog 5852

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Cocos2d-x开关按钮CCMenuItemToggle的使用

在手机游戏中,一般都会有类似音乐开关这样的按钮,当按钮显示“On”时,按下去音乐会打开,并且按钮显示改变为“Off”。在Cocos2d-x中,用CCMenuItemToggle实现这种开关按钮。接下来我们来学习一下它的使用方法。        首先新建一个项目。命名为“ToggleMenuTest”,然后我们从TestCpp示例项目的Resource目录下将我们需要的background.mp3

路上的点滴 6008

MenuItemToggle的使用

在使用Mneu的时候,我们通常会使用MenuItem来创建Menu,而MenuItem的子类有很多,如下图: 我们经常会使用到的就是MenuItemImage和MenuItemSprite,在这里,就讲讲MenuItemToggle的用处和用法。 MeniItemToggle:它在内部拥有一个MenuItem数组,用来负责展示不同的按钮状态。因为使用了一个菜单按钮的数组,所以此类的

coco小猿的博客 3714

cocos2d-x ——菜单层(CCMenuItemToggle)五

CCMenuItemToggle继承自CCMenuItem 提供可变数组存放CCMenuItem对象,用于实现选中状态切换。 .h void menFun(CCObject* pScene); .cpp bool HelloWorld::init() {     //////////////////////////////

u012220823的专栏 829

cocos2d-x 开关按钮 三态按钮 的实现 CCMenuItemToggle

一.废话少说,先上效果图:       二.实现过程: 1.创建CCMenuItemToggle对象: C++ 12345CCMenuItemImage *btnOn =CCMenuItemImage::create("soundon.png" ,"soundoff.png"); CCMenuIt

houjia159的专栏 3730

cocos2dx学习笔记之菜单Menu和菜单项MenuItem

首先需要明确的是cocos2d-x 3.x版本不推荐使用菜单类Menu了,因为菜单的功能可以用Button,Sprite或者ImageView等经常使用的控件替代. 回想一下个人经历的实际项目,确实没有用过Menu,但是由于目前在学习的教材讲到了Menu,就顺便学习下并记录之.

ellis1970的博客 2858

MenuItemToggle用法

MenuItemImage* playImg = MenuItemImage::create("play.png", "pause.png"); MenuItemImage* pauseImg = MenuItemImage::create("pause.png","play.png"); MenuItemToggle* tog = MenuItemToggle::createWithTarg

w18767104183的专栏 5076

Cocos2d-x MenuItemToggle 实现开关按钮

最近做自己的塔防游戏的时候用到的,作为记录记载下来。MenuItemToggle可以实现按钮的开关两种状态,类似”ON”->”OFF”.void SettingScene::addMenuItems(){ auto size=Director::getInstance()->getWinSize(); /*添加返回按钮*/ auto backMenuItem=MenuItemI

眭 2543

cocos2dx基础篇(7)——菜单按钮CCMenu/CCMenuItem

【唠叨】菜单按钮在游戏中是经常被用到的,比如主菜单界面的菜单选项,暂停游戏时的菜单选项等等。cocos2dx引擎同样为我们提供了CCMenu菜单的功能,并包含了一些简单的菜单项CCMenuItem。且菜单项附带触碰按钮时,自动放大的效果。温馨提示:本节内容比较多,需要大家慢慢分析,不要急于求成。本节组织结构如下:一、介绍CCMenu。...

weixin_34392435的博客 353

CCMenuItemToggle实现选中的效果

最近自己在做的一个小程序想加上一个选择颜色的功能。 大概的设想呢就是一共有七种颜色可以选择,最少选择两种,最多都选。大概就是类似于一个复选框的东西吧。 初步的实现呢就是每种颜色的选择就是一个CCMenuItemToggle,选中状态是一个图片,非选中状态是另一个图片。 大概的代码呢如下: *.h @interface Layer :CCLayer {  }

1506

CCMenuItemToggle

 CCMenuItemToggle 可以切换不同图片   CCMenuItemFont::setFontName("American Typewriter");     CCMenuItemFont::setFontSize(30);      CCMenuItemFont* titleSound = CCMenuItemFont::create("sound");     titleSou...

saydo 229
上一篇: 不能从const char *转换为LPCWSTR 经常碰到
下一篇: cocos2d-x使用TexturePacker打包图片及使用生成的plist文件创建精灵动画
Handz_cpp
博客等级 码龄14年 6粉丝 6原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值