Cocos2d-x MultipleTouch & CCControllButton's confusion
在cocos2dx的程序设计中有时候会遇到需要多点触摸的功能,下面先介绍一下在cocos2dx中多点触摸的一般规则,然后介绍我遇到的一个有关多点触摸的情景的解决方案。
(一)使用多点触摸规则:
关于多点触摸在TestCPP中有一个例子展示,通过这个例子就可以知道多点触摸是如何使用的了。
简单说一下步骤:
①开启多点触摸
在ios文件夹中的AppController.mm文件的
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中:
[__glView setMultipleTouchEnabled:true];
②注册触摸事件( StandardDelegate )
a)可以在onEnter方法中: CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
b)也可以重写: virtual void registerWithTouchDispatcher(void); 在这个方法中:
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
而且注意要在init方法中: setTouchEnabled(true);
为什么呢?因为在init方法中,setTouchEnabled(true); 会自动回调 registerWithTouchDispatcher 方法。
③触摸事件委托方法
virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
virtual void ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
virtual void ccTouchesCancelled(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
在每一个委托方法中,可以用下面的遍历方法,获取每一个触摸点的信息。
CCSetIterator iter = pTouches->begin();
    for (; iter != pTouches->end(); iter++)
    {
        CCTouch* pTouch = (CCTouch*)(*iter);
        CCPoint location = pTouch->getLocation();
    }
(二)一个类似多点触摸情景解决方法
情景介绍:在layer中,需要按住某一个按键,然后在按键保持按下的时候,执行某一个事件(也是要触摸屏幕执行的),如果松开按键,那么执行这个事件结束。
A)那么我的第一个反应就是使用多点触摸,理论上是可以解决的,但是感觉判断起来有点繁琐,所有暂时放弃了这个解决方法。
B)我就想到要CCMenu item 或者 CCControllButton 这类的“按键” 实现,当按键 保持按下 的时候,那么就可以判断它的状态(isSelected),在一个定时器方法中判断按键的状态,根据这个状态值,就可以进行相应处理,恩,这样似乎简单了许多。
注意:在这个情景中其实也是多点触摸的,注意到按键按下是一个触摸点,然后在执行某一个事件,也是要触摸屏幕执行,那么又是一个触摸点。那么我们同样要开启多点触摸,这一点很重要。
然而,如果我们 在按键按下的时候执行的事件,只是需要一个触摸点,那么注册为 TargetedDelegate 就可以了;如果需要多个触摸点,那么注册为 StandardDelegate。
①首先用到 CCMenuItem
在这类按键中 有两个 属性:
bool m_bSelected;
bool m_bEnabled;
确定按键是否选中,和是否可用。
那么在这个情景中,我们使用 它的是否选中 这个属性,通过 virtualbool isSelected(); 方法就可以获取到这个属性的值。
在定时器方法中:
 if (item->isSelected()) {
        CCLOG("selected");
    }
    else
    {
        CCLOG("unselected");
    }
②然后再试一下 CCControllButton
A)首先注意CCControllButton 中的触摸优先级是 1 ,所以 layer 注册的接收触摸事件优先级 就必须 大于等于 1.
下面看看为什么CCControllButton 中的触摸优先级是 1:
CCControllButton 是继承自:CCControl
在 CCControl 中的init 方法中:
bool CCControl::init()
{
if (CCLayer::init())
{
//this->setTouchEnabled(true);
//m_bIsTouchEnabled=true;
// Initialise instance variables
m_eState=CCControlStateNormal;
setEnabled(true);
setSelected(false);
setHighlighted(false); // Set the touch dispatcher priority by default to 1
this->setTouchPriority(1);
// Initialise the tables
m_pDispatchTable = new CCDictionary();
// Initialise the mapHandleOfControlEvents
m_mapHandleOfControlEvent.clear(); return true;
}
else
{
return false;
}
}
注意到了吧:
// Set the touch dispatcher priority by default to 1
this->setTouchPriority(1);
B) CCControllButton 中检测按键是否选中的状态 是使用 isHighlighted 方法,而不是 isSelected() .很奇怪吧!
在CCMenuItem 中是用 isSelected ,那么理论上,在 CCControllButton 也是类似的。
下面分析一下问题:
我们 CCControllButton 继承 CCControl ,而 CCControl 继承 CCLayerRGBA ,那么说到底,其实 CCControllButton 就是继承自
CCLayer。
那么肯定是要在 触摸事件的回调方法中 对CCControllButton的状态进行设置的。
可以发现:
virtual void setEnabled(bool enabled);
virtual void setSelected(bool enabled);
virtual void setHighlighted(bool enabled);
居然,有一个 setHighlighted方法,这个和 setSelected 方法有什么区别呢? 两个方法所对应的属性应该都是在button选中的吧!
带着疑问,继续-----
我们找到触摸事件的回调方法(只显示前两个touch began 和 moved 方法):
bool CCControlButton::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
if (!isTouchInside(pTouch) || !isEnabled() || !isVisible() || !hasVisibleParents() )
{
return false;
} for (CCNode *c = this->m_pParent; c != NULL; c = c->getParent())
{
if (c->isVisible() == false)
{
return false;
}
} m_isPushed = true;
this->setHighlighted(true);
sendActionsForControlEvents(CCControlEventTouchDown);
return true;
} void CCControlButton::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
if (!isEnabled() || !isPushed() || isSelected())
{
if (isHighlighted())
{
setHighlighted(false);
}
return;
} bool isTouchMoveInside = isTouchInside(pTouch);
if (isTouchMoveInside && !isHighlighted())
{
setHighlighted(true);
sendActionsForControlEvents(CCControlEventTouchDragEnter);
}
else if (isTouchMoveInside && isHighlighted())
{
sendActionsForControlEvents(CCControlEventTouchDragInside);
}
else if (!isTouchMoveInside && isHighlighted())
{
setHighlighted(false); sendActionsForControlEvents(CCControlEventTouchDragExit);
}
else if (!isTouchMoveInside && !isHighlighted())
{
sendActionsForControlEvents(CCControlEventTouchDragOutside);
}
}
终于有点发现了,原来,都是只用到了 
 setHighlighted 设置button的是否选中状态,根本就和 setSelected 没有半点关系,难怪,我们只能用 isHighlighted 方法来检测 button 的是否选中状态了。
到这里,似乎问题就结束了。但是我内心有一个深深的好奇:为什么要设多一个这样用处不是很大的 setSelected 方法呢?或者说,setHighlighted 方法抢占了 setSelected 本该有的作用呢?
我在 官方网站论坛上,发了一个帖子,欢迎大神回复指导一下:点击打开链接
其实我为他们找到了两个可能的理由:
① CCMenuItem 和 CCControllButton 这两个类是不同的两个程序员编写的,他们之间缺少交流,所以导致了这个差异。但是这个很明显对我们来说是一个潜在的坑呀!
②CCControllButton 提供 setSelected 是为了给我们提供一个手动设置 按键是否选中状态 的方法。但是这样的方法实际过程中,用处大吗?,大吗?
好咯,大致就是这么些个内容了,关于最后的问题,欢迎大神指导。
Cocos2d-x MultipleTouch & CCControllButton's confusion的更多相关文章
- 小尝试一下 cocos2d
		好奇 cocos2d 到底是怎样一个框架,正好有个项目需要一个游戏框架,所以稍微了解了一下.小结一下了解到的情况. 基本概念 首先呢,因为 cocos2d 是基于 pyglet 做的,你完全可以直接用 ... 
- 采用cocos2d-x lua 制作数字滚动效果样例
		require "Cocos2d"require "Cocos2dConstants"local testscene = class("testsce ... 
- Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板
		很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ... 
- iPhone开发与cocos2d 经验谈
		转CSDN jilongliang : 首先,对于一个完全没有mac开发经验,甚至从没摸过苹果系统的开发人员来说,首先就是要熟悉apple的那一套开发框架(含开发环境IDE.开发框架uikit,还有开 ... 
- Data type confusion: what is an int(11)?
		http://everythingmysql.ning.com/profiles/blogs/data-type-confusion-what-is-an Over and over I see cu ... 
- cocos2d学习记录
		视频 - http://www.manew.com/forum-105-3.html一个论坛帖 - http://www.zhihu.com/question/21114802官网 - http:// ... 
- Android下Cocos2d创建HelloWorld工程
		最近在搭建Cocos2d的环境,结果各种问题,两人弄了一天才能搞好一个环境-! -_-!! 避免大家也可能会遇到我这种情况,所以写一个随笔,让大家也了解下如何搭建吧- 1.环境安装准备 下载 tadp ... 
- 学生信息管理系统(cocos2d引擎)——数据结构课程设计
		老师手把手教了两天半,看了一下模式,加了几个功能就大功告成了!!! 给我的感想就是全都是指针! 添加图片精灵: CCSprite* spBG = CCSprite::create("&qu ... 
- cocos2d触碰例子代码
		// // TestLayer.h // MiniTD // // Created by OnePiece on 12-7-30. // Copyright 2012年 __MyCompanyName ... 
随机推荐
- CSS display 属性详解
			定义display 属性设置是否及如何显示元素. 继承性: No 说明 这个属性用于定义建立布局时元素生成的显示框类型.对于 HTML 等文档类型,如果使用 display 不 谨慎会很危险,因为可能 ... 
- 关于最大流的EdmondsKarp算法详解
			最近大三学生让我去讲课,我就恶补了最大流算法,笔者认为最重要的是让学弟学妹们入门,知道算法怎么来的?为什么是这样?理解的话提出自己的改进,然后再看看Dinic.SAP和ISAP算法….. 一.概念引入 ... 
- 卡牌手游源码《暗黑世界V1.3》数据库表说明文档!!!
			原地址:http://blog.csdn.net/uxqclm/article/details/11970761 欢迎来到9秒:www.9miao.com 由于看到论坛中有人询问需求<暗黑世界V ... 
- linux 性能分析常规逻辑和手段总结
			一. 追查cpu占用较高的进程(线程) 1 . 如何查找出当前系统中占用cpu或者内存最高的进程? ps aux |sort -rn -k 3 |head -n3 查找出当前系统中cpu资源占用前三 ... 
- 安装edX DevStack
			概述 edX Developer Stack 就是通常我们所说的Devstack,是为本地开发所设计的一个Vagrant实例. Devstack: 和产品(edx Product Stack)对系统的 ... 
- javascript小游戏--生命游戏
			昨天参加Code Retreat的活动,"Code Retreat是一个一天的集中练习的活动,专注于软件开发和设计的基础". 要了解更多信息可前往 CodeRetreat官网 通过 ... 
- rc522 ,pn544区别
			请问 我们之前用的刷卡的 是用 rc522 ,,pn544和这个有什么区别? xqhrs232 (10:14:27): 支持的协议更多点吧! 春tian在哪里 (10:14:38): 比如? xq ... 
- hdu4632Palindrome subsequence
			http://acm.hdu.edu.cn/showproblem.php?pid=4632 TLE了N次 原因居然是取模次数太多了..! 这数据卡的好紧 还是我写的太搓..828ms挤过 s[i]= ... 
- epub3 in action: epub3文件格式简介
			epub3文件就是一个符合epub3标准,以epub为扩展名的zip压缩文件.epub3标准则是基于html5.css3.svg等web标准以及mathML等来展示内容.下图就是一个简单epub3文件 ... 
- wpa_supplicant 和 802.11g WPA 认证的配置
			# cd /etc/init.d# ln -s net.lo net.eth0 默认的接口名是 wlan0,让它开机时自动 up:cp /etc/init.d/net.lo /etc/init.d/n ... 
