在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的更多相关文章

  1. 小尝试一下 cocos2d

    好奇 cocos2d 到底是怎样一个框架,正好有个项目需要一个游戏框架,所以稍微了解了一下.小结一下了解到的情况. 基本概念 首先呢,因为 cocos2d 是基于 pyglet 做的,你完全可以直接用 ...

  2. 采用cocos2d-x lua 制作数字滚动效果样例

    require "Cocos2d"require "Cocos2dConstants"local testscene = class("testsce ...

  3. Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板

    很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ...

  4. iPhone开发与cocos2d 经验谈

    转CSDN jilongliang : 首先,对于一个完全没有mac开发经验,甚至从没摸过苹果系统的开发人员来说,首先就是要熟悉apple的那一套开发框架(含开发环境IDE.开发框架uikit,还有开 ...

  5. 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 ...

  6. cocos2d学习记录

    视频 - http://www.manew.com/forum-105-3.html一个论坛帖 - http://www.zhihu.com/question/21114802官网 - http:// ...

  7. Android下Cocos2d创建HelloWorld工程

    最近在搭建Cocos2d的环境,结果各种问题,两人弄了一天才能搞好一个环境-! -_-!! 避免大家也可能会遇到我这种情况,所以写一个随笔,让大家也了解下如何搭建吧- 1.环境安装准备 下载 tadp ...

  8. 学生信息管理系统(cocos2d引擎)——数据结构课程设计

    老师手把手教了两天半,看了一下模式,加了几个功能就大功告成了!!! 给我的感想就是全都是指针! 添加图片精灵: CCSprite*  spBG = CCSprite::create("&qu ...

  9. cocos2d触碰例子代码

    // // TestLayer.h // MiniTD // // Created by OnePiece on 12-7-30. // Copyright 2012年 __MyCompanyName ...

随机推荐

  1. Seven Python Tools All Data Scientists Should Know How to Use

    Seven Python Tools All Data Scientists Should Know How to Use If you’re an aspiring data scientist, ...

  2. HTTP错误代码详细介绍

    HTTP 400 - 请求无效 HTTP 401.1 - 未授权:登录失败 HTTP 401.2 - 未授权:服务器配置问题导致登录失败 HTTP 401.3 - ACL 禁止访问资源 HTTP 40 ...

  3. HDU4523+简单

    题意很简单. 一次最多多切出一条边! 其余的就没什么好说的了 import java.util.*; import java.math.*; public class Main{ public sta ...

  4. jsp空页面导致的jvm heap溢出

    为了性能测试需要,写一个了简单的jsp页面: <%@ page contentType="text/html;charset=UTF-8" language="ja ...

  5. ANDROID_MARS学习笔记_S01原始版_009_下载文件

    一.代码1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...

  6. 协议(porotocol)

    fly.h: #import <Foundation/Foundation.h> @protocol Fly -(void) go; -(void) stop; @optional -(v ...

  7. 同一客户代码下一个CPN对应多个FG会出现CPN描述一样的问题

    Q&A : D2E01客户下已经存在CPN: TP1062/A 对应FG: P5M2812512AFHHF0 直接在客户代码下无法新建,只能在交叉信息新建CPN: TP1062/A, 但无法修 ...

  8. -_-#【网站优化】AJAX

    如何让搜索引擎抓取AJAX内容? Ajax 缓存: 两个重要的事实 使用 AJAX 事件触发 AJAX 请求.不要产生多次请求. 对 AJAX 请求使用 GET 方法 Use GET for AJAX ...

  9. codeigniter实现ajax分页

    <?php /** *417 add 主要是实现ajax分页 **/ class MY_Pagination extends CI_Pagination{ public function __c ...

  10. 【转】Ubuntu更改语言环境设置

    原文网址:http://studiogang.blog.51cto.com/505887/385199 上午装了下Ubuntu 10.4,默认安装时选择的语言是english的,结果由于英语水平太次, ...