`
810364804
  • 浏览: 819941 次
文章分类
社区版块
存档分类
最新评论

【Cocos2d-X开发学习笔记】第22期:事件处理机制之触屏事件

 
阅读更多

本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010


游戏主要是玩家和程序的交流。无论你的动画做得多么生动,特效做得如何炫,游戏还是要和玩家进行互动和交

流。在智能手机中,主要的输入操作是通过触摸屏幕、重力感应等方式实现的,而输入文字主要通过虚拟键盘等实现

的。下面就让我们一起来学习触屏事件的使用。

一、触屏事件

在Cocos2D-X中,继承自触屏代理协议CCTouchDelegate的布景层类CCLayer可以检测触屏事件并调用回调函

数。首先来看CCTouchDelegate类的继承关系,如下图所示。

CCTouchDelegate的子类中,CCStandardTouchDelegate协议是标准的获得多点触摸点的范例,

CCTargetedTouchDelegate不用处理触摸点的集合,它是返回单点的。

但是需要注意的是,CCTargetedTouchDelegate并没有屏蔽多点触摸,而是将多点离散成了单点,同时传递过来

了。可以在开始触摸的函数中返回true来实现之后获得的触摸点肯定是自己的。此外,我们常用的类是布景层类

CCLayer,也就是说,在布景层类中可以重写ccTouchesBegan等函数获得触屏的信息。

二、触屏事件监听函数

1、在CCDirector类中有如下函数。

<1> addTargetedDelegate(CCTouchDelegate * pDelegate,int nPriority,bool bSwallowsTouches)

作用:在Dispatcher的列表中注册一个触屏事件的委托,用以监听用户的触屏事件。

参数1:触屏事件委托CCTouchDelegate目标。

参数2:优先级(其值越小优先级越高,优先级越高越早被响应)。

参数3:是否拦截触屏事件。

当第3个参数为true时,表示对本次触屏事件进行拦截,也就是说当触屏事件响应了本次触屏委托后,不会再继续

将此触屏事件分发响应到Dispatcher列表中的其他委托中。

如果CCNode使用了CCTouchDelegate接口,并且注册了触屏委托,那么当用户触摸手机屏幕后,Cocos2D-X会

从当前设备拦截到此事件,并开始遍历Dispatcher的列表,逐一对注册过的CCNode进行响应对应的触屏事件。

2、一般触屏事件分为三种。

<1> bool virtual bool ccTouchBegan(CCTouch * touch,CCEvent * event)

作用:当用户手指第一次触碰到手机屏幕时响应的回调函数。

返回值:bool类型。当返回true时,表示继续响应ccTouchMoved、ccTouchEnded事件;当返回false时,则不再继

响应这两个事件。

<2> virtual bool ccTouchMoved(CCTouch * touch,CCEvent * event)

作用:当用户手指在手机屏幕上进行移动(拖动)时响应的回调函数。

<3> virtual bool ccTouchEnded(CCTouch * touch,CCEvent * event)

作用:当用户手指在手机屏幕上离开、抬起响应的回调函数。

参数1:CCTouch包含用户触屏点坐标。

注意:由于CCLayer默认使用了CCTouchDelegate触屏委托,所以继承CCLayer的子类无须再次使用此接口。

三、单点触摸实例

1、接下来,让我们以项目实例来实现一个精灵自动移动到用户触屏位置的功能。

<1> 首先新建Cocos2D-X项目,取名为“MyCCTouch”,然后在HelloWorldScene.h文件中声明成员函数。

//重写触屏回调函数
    virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    
    //重写生命周期函数
    virtual void onEnter();
    virtual void onExit();

<2> 在HelloWorldScene.cpp文件中的init函数中添加如下所示代码。

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        CC_BREAK_IF(! CCLayer::init());

        CCSprite * spr = CCSprite::create("Icon.png");
		spr->setPosition(ccp(150,150));
		addChild(spr,0,922);

        bRet = true;
    } while (0);

    return bRet;
}

<3> 最后在HelloWorldScene.cpp文件中添加如下所示函数。

void HelloWorld::onEnter(){
    
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,false);
    CCLayer::onEnter();
}

void HelloWorld::onExit(){
    
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
    CCLayer::onExit();
}

bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
	CCLOG("ccTouchBegan");
    return true;
}

void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event){
    CCLOG("ccTouchMoved");
}

void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
	CCLOG("ccTouchEnded");
    //获取离开屏幕时对应的坐标
    CCPoint point = touch->getLocation();
    
    //获取到精tag=922的精灵
    CCSprite* sp = (CCSprite*)this->getChildByTag(922);
    //暂停所有动作
    sp->stopAllActions();
    //执行move动作到用户离开时的位置
    sp->runAction(CCMoveTo::create(1, point));
}


对于以上代码需要着重讲解的有4点:

<1> 重写了生命周期函数onEnter与onExit,主要用于注册和移除委托。

因为委托一般都是成对出现的,有注册就要对应有移除。如果你想对一个CCNode进行委托监听,那么创建本类时

就可以进行监听了,而当本类退出时也可以对应删除其监听。

所以一般情况下,推荐大家将触屏事件的注册与移除代码都写在onEnter与onExit中。如果注册的委托不及时移除

掉,就有可能造成程序的异常退出

<2> 以上代码中,我们将精灵move逻辑写在触屏监听用户手指离开的函数ccTouchEnded中进行处理,其原因是考虑

用户体验。

很多用户在手指第一次触摸屏幕时并不是有目的性的、或者说是尝试性地去触碰屏幕,那么如果系统很快响应了

这些用户的错误操作逻辑,用户就会比较反感,所以一般情况下,例如按钮等我们只在用户离开屏幕时进行响应。当

然,这些细微的用户体验也会根据不同类型的游戏进行改进。

<3> 由于Cocos2D-X是基于OpenGL ES实现的,所以在CCTouch中保存用户触屏坐标,位置是3D坐标系中的坐标,

所以需要将其转换成2D坐标。当然,Cocos2D-X也在CCTouch中为开发者提供了转换坐标的函数getLocation进行2D

坐标点的转换。

<4> 在上面的示例项目中,在精灵进行runAction之前,我先调用了这个精灵的stopAllActions()函数,将停止此精灵的

所有动作。很多时候游戏中的精灵会有很多不同的动作需要执行,为了防止在运行新的动作时上一个动作可能还没暂

停的情况,所以这里先对所有动作进行一个停止的操作。主要原因是当精灵同时runAction两个不同的动作时,会出现

乱掉的情况。

2、示例效果图

精灵会随着屏幕的点击到达指定的位置。

四、多触点事件

我们学习了触屏的监听,其监听委托类为CCTargetedTouchDelegate,此接口属于单点触屏的监听委托;对于多

触点,其委托类为CCStandardTouchDelegate。

不论是CCTargetedTouchDelegate,还是CCStandardTouchDelegate,都是CCTouchDelegate的子类,而

CCLayer默认继承了CCTouchDelegate接口,所以CCLayer的子类无须再重新使用这些接口。

多触点委托中的回调函数如下所示:

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);


其中分别对应为用户按下、移动(拖动)、抬起(离开屏幕)3种事件。在这个回调函数中,第一个参数不再是

CCTouch,而是CCTouch的集合。


遍历所有触点位置的方式如下所示:

CCSetIterator iter = pTouches->begin();
    for (; iter != pTouches->end(); iter++)
    {
        CCTouch* pTouch = (CCTouch*)(*iter);
        CCPoint location = pTouch->getLocation();
	}


CCTouch 有如下所示函数:

<1> int getID()

作用 :得到当前触点的下标(从0开始计数)。


在多触点委托监听时,需要注意以下3点问题:

<1> setTouchEnabled(true),开启多触点监听务必调用此函数。

<2> 在CCDirector类中添加多触点委托事件代码:

 CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(CCTouchDelegate* pDelegate,int nPriority)


注意:多触点的委托注册放在onEnter的生命函数中会造成程序异常退出。默认都重写如下函数:

virtual void registerWithTouchDispatcher(void);

将多触点委托注册放在此函数中进行注册,用以指明此委托类型为多触点委托监听。


<3> 开启IOS多触点支持功能。

在IOS设备中,默认多触点是关闭的,如果我们想要在IOS设备中使用多触点,就需要开启多触点的支持。



五、多触点触摸实例


1、首先新建Cocos2D-X项目,取名为“MyMutiTouch”,然后在HelloWorldScene.h文件中声明成员函数。

//重写多触点回调函数
	virtual void registerWithTouchDispatcher(void);
	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 onExit();

2、在HelloWorldScene.cpp文件中的init函数中添加如下所示代码。

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        CC_BREAK_IF(! CCLayer::init());

        //开启多触点监听务必调用此函数
		setTouchEnabled(true);
    
		CCSprite * sp1 = CCSprite::create("Icon.png");
		sp1->setColor(ccc3(255, 255, 0));//便于区分
		CCSprite * sp2 = CCSprite::create("Icon.png"); 
		sp1->setPosition(ccp(150,100));
		sp2->setPosition(ccp(150,200)); 
		addChild(sp1,0,91);
		addChild(sp2,0,92);

        bRet = true;
    } while (0);

    return bRet;
}

3、最后在HelloWorldScene.cpp文件中添加如下所示函数。

//注册多触点的委托监听
void HelloWorld::registerWithTouchDispatcher(void){
    CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
}

//用户手指第一次触碰
void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){
    CCSetIterator iter = pTouches->begin();
    for (; iter != pTouches->end(); iter++)
    {
        CCTouch* pTouch = (CCTouch*)(*iter);
        CCPoint location = pTouch->getLocation();
        if(pTouch->getID()==0){//第一个触点
            CCSprite * sp1 = (CCSprite*)this->getChildByTag(91);
            sp1->setPosition(location);            
        }else if(pTouch->getID()==1){//第二个触点
            CCSprite * sp2= (CCSprite*)this->getChildByTag(92);
            sp2->setPosition(location);
        }
    }
}

//用户手指进行移动或者拖拽
void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){
    CCSetIterator iter = pTouches->begin();
    for (; iter != pTouches->end(); iter++)
    {
        CCTouch* pTouch = (CCTouch*)(*iter);
        CCPoint location = pTouch->getLocation();
        if(pTouch->getID()==0){//第一个触点
            CCSprite * sp1 = (CCSprite*)this->getChildByTag(91);
            sp1->setPosition(location);
        }else if(pTouch->getID()==1){//第二个触点
            CCSprite * sp2= (CCSprite*)this->getChildByTag(92);
            sp2->setPosition(location);
        }
    }
}

//用户手指抬起
void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){
    CCSetIterator iter = pTouches->begin();
    for (; iter != pTouches->end(); iter++)
    {
        CCTouch* pTouch = (CCTouch*)(*iter);
        CCPoint location = pTouch->getLocation();
        CCLOG("pTouch  触摸点 %i 的坐标: x:%f,y:%f",pTouch->getID(),location.x,location.y);
    }
}

//删除多触点的委托监听
void HelloWorld::onExit(){
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
    CCLayer::onExit();
}

4、示例效果图


以上示例代码主要实现随着不同用户多个触摸点位置的移动,其各精灵位置也不断移动。





源码下载地址

分享到:
评论

相关推荐

    Cocos2d-x实战:JS卷——Cocos2d-JS开发

    资源名称:Cocos2d-x实战:JS卷——Cocos2d-JS开发内容简介:本书是介绍Cocos2d-x游戏编程和开发技术书籍,介绍了使用Cocos2d-JS中核心类、瓦片地图、物理引擎、音乐音效、数据持久化、网络通信、性能优化、多平台...

    Cocos2D-X开发学习笔记-触屏事件使用示例

    首先,我们要了解Cocos2D-X中的触摸事件处理机制。在Cocos2D-X中,触屏事件主要通过`Touch`类和`TouchEvent`类来实现。`Touch`代表一次触摸行为,而`TouchEvent`则包含了多个`Touch`对象,表示一次多点触摸事件。...

    Cocos2d-x学习笔记

    Cocos2d-x框架除了Windows平台外,还支持iOS、Android、Mac OS X、Web等平台,初学者在掌握了Windows平台的开发后,可以进一步学习如何使用Cocos2d-x跨平台开发,实现一个游戏在多个平台上运行。 在学习过程中,...

    Cocos2d-x 3.x游戏开发实战pdf含目录

    《Cocos2d-x 3.x游戏开发实战》是一本深度探讨Cocos2d-x 3.x框架的游戏开发书籍,适合对游戏编程有兴趣的开发者学习。Cocos2d-x 是一个开源的、跨平台的2D游戏开发框架,广泛应用于iOS、Android、Windows等多平台的...

    Cocos2D-X开发学习笔记-游戏数据存储项目实例(上)

    Cocos2D-X没有内置的序列化机制,但开发者可以利用`cocos2d::Value`和`cocos2d::ValueMap`进行自定义实现。 6. **云存储服务**:对于网络游戏,考虑使用云存储服务如Apple的Game Center、Google Play Games ...

    Cocos2D-X开发学习笔记-按键事件使用示例

    总之,Cocos2D-X的按键事件处理是通过`EventListenerKeyboard`类和对应的回调函数实现的,这使得开发者能够轻松响应用户的键盘输入,为游戏或应用增加丰富的交互功能。通过学习和实践,你可以进一步掌握这一关键机制...

    Cocos2d-x实战++JS卷++Cocos2d-JS开发+PDF电子书下载+带书签目录+完整

    标题中提到了"Cocos2d-x实战++JS卷++Cocos2d-JS开发+PDF电子书下载+带书签目录+完整",这里面包含了几个关键知识点: 1. Cocos2d-x:是一个开源的游戏开发框架,它主要用于开发跨平台的游戏和应用程序,支持iOS、...

    Cocos2d-x实战 JS卷 Cocos2d-JS开发

    《Cocos2d-x实战 JS卷 Cocos2d-JS开发》是一本深入探讨Cocos2d-x游戏引擎JavaScript版本使用的专业书籍。Cocos2d-x是全球范围内广泛采用的游戏开发框架,尤其适用于2D游戏的制作,而Cocos2d-JS则是其JavaScript接口...

    Cocos2d-x实战:C++卷(2版)源代码

    5. **事件处理**:Cocos2d-x提供了事件处理机制,包括触摸事件、键盘事件、网络事件等,使得游戏能够响应用户的输入。 6. **声音与音乐**:Cocos2d-x支持音频播放,包括背景音乐和音效,可以实现音效的同步和控制。...

    cocos2d-x学习笔记

    《cocos2d-x学习笔记》 在学习cocos2d-x时,了解其核心组件和工作流程至关重要。AppDelegate是cocos2d-x框架中的一个关键类,它扮演着应用程序入口点的角色,处理应用程序的生命周期事件。让我们深入探讨...

    Cocos2d-x实战 JS卷

    5. **事件处理**:掌握事件监听和响应机制,包括触摸事件、键盘事件以及自定义事件的处理,实现用户交互。 6. **游戏逻辑**:学习如何组织游戏逻辑,包括状态管理、游戏循环、时间管理和AI设计。 7. **资源管理**...

    cocos2d-x事件类

    在使用cocos2d-x开发游戏的过程中,为了实现逻辑和显示相分离。 在下通宵了一个晚上,写出了该事件类。 谨记,该事件只能用于cocos2d-x中。 事件发送者需要继承EventDispatcher类 事件接收者需要继承EventHandle类...

    cocos2d-x-3.1.zip

    总的来说,Cocos2d-x 3.1是游戏开发者学习2D游戏开发的一个重要参考点,虽然它已经不是最新的版本,但其核心概念和机制在后续版本中仍然保持一致,是理解整个Cocos2d-x框架的基础。解压并研究“cocos2d-x-3.1”中的...

    Cocos2D-X游戏开发技术精解

    资源名称:Cocos2D-X游戏开发技术精解内容简介:Cocos2D-X是一款支持多平台的 2D手机游戏引擎,支持iOS、Android、BlackBerry等众多平台。当前,很多移动平台流行的游戏,都是基于Cocos2D-X开发的。 《Cocos2D-X...

    经典版本 方便下载 源码 旧版本 3.8 官网找不到了 cocos2d-x-3.8.zip

    6. **事件处理**:提供触摸、键盘、摇杆等多种输入事件的处理机制,使开发者能快速响应用户操作。 7. **物理引擎**:集成Box2D物理引擎,可以轻松实现物理模拟,如碰撞检测和刚体动力学。 8. **Audio支持**:支持...

    cocos2d-x 3.0

    《cocos2d-x 3.0:游戏开发中的角色移动技术详解》 在游戏开发领域,cocos2d-x是一款广泛使用的开源2D游戏引擎,尤其在移动平台上的应用非常广泛。cocos2d-x 3.0版本带来了许多性能优化和新特性,使得开发者能够更...

    Cocos2d-x实战C++卷关东升著完整版pdf

    接着,书中会讲解Cocos2d-x的事件处理机制,包括触摸事件、键盘事件等,这些都是游戏交互必不可少的部分。同时,还会涉及动画和物理引擎的使用,如动作(Action)、序列(Sequence)、组(Group)以及Box2D物理引擎...

    Cocos2D-X开发学习笔记-动作类之基础动作的使用示例(下)

    Cocos2D-X是一款流行的开源游戏开发框架,尤其在2D游戏领域有着广泛的应用。它提供了丰富的API和功能,使得开发者能够轻松创建出各种复杂的2D游戏。在Cocos2D-X中,动作(Actions)是游戏对象行为的核心组成部分,...

    Cocos2D-X开发学习笔记-渲染框架之图形的绘制

    Cocos2D-X是一款强大的跨平台2D游戏开发框架,基于C++,并提供了Lua和JavaScript等脚本语言接口。本教程将深入讲解Cocos2D-X中的渲染框架,特别是如何进行图形的绘制,这对于创建游戏场景、角色动画以及用户界面至关...

Global site tag (gtag.js) - Google Analytics