zoukankan      html  css  js  c++  java
  • Cocos2d-x 3.0 屏幕触摸及消息分发机制

    ***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************



    题外话:

    唉。

    开学了!    好烦。

    这就已经大三了,

    两年前的这时候,我还是懵懂的大一小学弟,

    两年后。就要奔上社会就业了。

    光阴似箭。日月如梭呀~



    正文:

    好久没做cocos2d-x了,这次练习一下。屏幕触摸及消息分发机制。

    这里,我用的是cocos2d-x 3.0版本号来进行练习的,环境是 VS2012+WIN7


    首先。新建一个项目,并向场景增加一个精灵。

    新建项目: cocos  new -p xxx(包名)  -l xxx(语言)  -d xxx(保存路径)

    选择一个精灵,放到resource文件夹下,并在VS2012中增加资源项。



    然后。建立一个新的精灵。加入到当前场景Hello World

    auto sprite_2 = Sprite::create("player.png");
    sprite_2->setPosition(Point(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));
    // 图片略大,缩小一下
    sprite_2->setScale(0.4f);
    this->addChild(sprite_2);

    这样。已经增加了一个精灵,接下来要做的就是触摸事件的处理。


    我们要实现触摸一个位置,让精灵跟着移动到该位置。步骤为:

    ——定义监听事件的侦听对象

    ——定义侦听对象的回调方法

    ——在事件分发器上注冊


    由于点击一个位置,用OneByOne这个单点触摸就可以。

    首先。定义监听事件的侦听对象:

    auto listener=EventListenerTouchOneByOne::create();


    然后。定义回调方法。

    我们精灵所在的scene类继承自Layer类,Layer类中。有触摸的虚函数,

    因此,我们仅仅须要复制过来,进行覆盖就能够定制回调函数了。

    先到Layer类中,找到onTouchBegan,onTouchMoved,onTouchEnded



    然后,拷贝到HelloWorldScene.h中声明,并在.cpp中定义



    先进行一些简单的定义,然后在文件里,要制定回调方法,从下图可知:


    CC_CALLBACK_2有两个參数,_selector_ and _target_

    _selector_:选择哪个函数进行回调?   ——显然是当前类中的对应函数啦

    _target_:由哪个对象触发?——就是当前的场景

    所以,最后应该是:

    // 定义监听对象的回调方法
    listener->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);
    listener->onTouchMoved=CC_CALLBACK_2(HelloWorld::onTouchMoved,this);
    listener->onTouchEnded=CC_CALLBACK_2(HelloWorld::onTouchEnded,this);

    (PS:为虾米用CC_CALLBACK_2?

    点击进入它的定义。能够看到:

    // new callbacks based on C++11
    #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
    #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
    #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
    #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)

    CC_CALLBACK_..  这个事实上都是在用std::bind来进行的操作。

    白话来说,就是实现了一个对象和一个方法的绑定执行。

    要注意的是,后面的_几,并非代表有几个參数,而是有几个占位符。

    更加具体内容,能够看这个→  std::bind与CC_CALLBACK不得不说的故事  )


    *****这里也体现出了cocos2d-x 2.x和3.x的小差别:

    在2.x中。须要注冊一个事件侦听。

    而在3.x中。则须要定义一个侦听器的对象。然后定义回调方法。最后还要将侦听和事件分发器绑定。


    如今来向事件分发器加入:

    _eventDispatcher

    注冊一个侦听事件,主要有以下几种:









    我们用的是最后一种。基于场景图的优先级的。

    // 在事件分发器中注冊
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);

    两个參数,第一个表示侦听对象,第二个表示在哪个节点进行。


    说了这么多了。我们来试一试,到眼下为止。是否正确。

    也就是检測一下,我们的点击动作是否能被获取并分发。


    在,HelloWorld::onTouchBegan中,设置在控制台输出所点击的坐标:

    bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
    {
    	log("the location is: %lf,%lf !",touch->getLocationInView().x,touch->getLocationInView().y);
    	return true;
    }

    log就是打印功能。

    %lf,输出的坐标为 double型,

    getLocation是得到OpenGL坐标系(左下角为0,0点)

    getLocationInView是得到当前屏幕坐标系(左上角为0,0点)


    OK,搞定。执行!

    有错误!




    将Layer里onTouchBegan复制过来,没有给他们加命名空间,

    能够直接在HelloWorldScene.h中加一句:

    using namespace cocos2d;    

    或者 USING_NS_CC;

    再或者。不嫌麻烦。就在对应Touch和Event前加cocos2d::

     bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event); 
     void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event); 
     void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event); 

    好了,如今执行一下吧~



    恩,点击鼠标。输出对应的位置坐标。


    我们能够继续做下去了!

    我们的目标是。点击屏幕,然后让我们指定的精灵移动到该位置。

    如今,我们能够获取到点击屏幕的位置了,怎样让指定的精灵移动到该位置呢?

    要想指定精灵。那就要用到Tag,给精灵做一个标记,setTag

    sprite_2->setTag(33);

    我给它定义了一个编号33(当然,依照心情。随便设置的。)


    编号设置了,如今,让用户触摸这个点以后,得到这个精灵,便于后面进行对应操作。

    bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
    {
    	log("the location is: %lf,%lf !",touch->getLocationInView().x,touch->getLocationInView().y);
    	// 新建一个精灵。通过编号得到这个精灵
    	auto sprite=this->getChildByTag(33);
    	sprite->setPosition(Point(touch->getLocation().x,touch->getLocation().y));
    	return true;
    }

    如今,我们能够通过点击某个点。我们的精灵的中心就会在该点了,

    接下来。能够做一些动作了。不要立即出现,让它移动过去。


    这个,能够通过之前学习的  runAction中的MoveTo来解决:

    bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
    {
    	log("the location is: %lf,%lf !",touch->getLocationInView().x,touch->getLocationInView().y);
    	// 新建一个精灵。通过编号得到这个精灵
    	auto sprite=this->getChildByTag(33);
    //	sprite->setPosition(Point(touch->getLocation().x,touch->getLocation().y));
    	sprite->runAction(MoveTo::create(0.5,Point(touch->getLocation().x,touch->getLocation().y)));
    	return true;
    }

    完毕了,~(*^__^*) ~


    如今。来个更加难一点的。怎样进行拖动?

    事实上,也不难的,就是在onTouchMoved中,获取这个精灵,并setPosition。当然之前onTouchBegan的对应都要删除。

    void HelloWorld::onTouchMoved(Touch *touch, Event *unused_event)
    {
    	auto sprite=this->getChildByTag(33);
    	sprite->setPosition(Point(touch->getLocation().x,touch->getLocation().y));
    }

    OK,执行一下,耍一耍吧。



    恩,这次就到这里了。

    这次做的是。通过点击屏幕让 角色 移动到该位置,能够直接出现。也能够移动过去,还能够拖动。

    过程例如以下:

    1.创建一个所须要操作的精灵于场景中

    2.创建监听事件的侦听对象

    3.定义对象的回调函数

    4.在事件分发器中进行注冊

    5.更改onTouchBegan,onTouchMoved内对应内容,来实现目的。


    End。。




    ***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

  • 相关阅读:
    什么是MSI文件?
    学习window系统下的注册表
    AngularJS学习手册
    学习ajax 总结
    jquery基础教程读书总结
    overflow:hidden清除浮动原理解析及清除浮动常用方法总结
    javascript进阶-原型prototype
    javascript-函数进阶
    小技巧之a标签自动解析URL
    Myeclipse出现 java文件中文乱码问题
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6792361.html
Copyright © 2011-2022 走看看