cocos2dx学习之路----第八篇(初识触摸机制中的单点触摸)

来源:互联网 发布:php ajax 编辑:程序博客网 时间:2024/06/05 19:58

上一篇中介绍了坐标转换的问题,这一篇就来浅谈关于cocos2dx中比较重要的一个知识点-------触摸机制。

在游戏中,不仅仅只需要画面的变动,更多的是需要与其中的实体对象进行交互。PC端的游戏可以通过鼠标、键盘,而对于移动端更多的是用触摸。所以,这里所讲的触摸也基本针对移动端的。当然,往往在我们PC端开发过程中,鼠标能够当作一个触摸点来进行交互。但是,这远远不够的,毕竟移动端在触摸的时候肯定有多点的交互。

好了,说的那么多,我们就进入正题吧~

cocos2dx的触摸机制中,有单点触摸及多点触摸。这里先来说说单点的触摸。

我们先来看看我们需要做出什么效果,如下图所示:


通过上图可以看出,场景中有两个颜色方块,我们通过鼠标点击方块后移动鼠标可以拖动方块。移动后的方块可以显示在另外一个方块的上面,即覆盖它。

这是个简单的例子,在解释如何实现之前,我们需要知道要实现触摸大概的步骤,有三步:

1.创建触摸监听器;

2.为监听器分配相关的触摸回调方法;

3.分发监听器

好,现在就直接来看实现的源码吧:

TouchEventTest.h:

#ifndef __TOUCH_EVENT_TEST_H__#define __TOUCH_EVENT_TEST_H__#include "cocos2d.h"USING_NS_CC;class TouchEventTest : public Layer{public:    static Scene* createScene();    virtual bool init();CREATE_FUNC(TouchEventTest);};#endif


TouchEventTest.cpp:

#include "TouchEventTest.h"Scene* TouchEventTest::createScene(){    auto scene = Scene::create();auto layer = TouchEventTest::create();    scene->addChild(layer);    return scene;}bool TouchEventTest::init(){    if ( !Layer::init() )    {        return false;    }auto visibleSize = Director::getInstance()->getVisibleSize();//方块一LayerColor *layer1 = LayerColor::create(Color4B::RED, 100, 100);this->addChild(layer1);layer1->ignoreAnchorPointForPosition(false);<span style="white-space:pre"></span>//不忽略锚点layer1->setAnchorPoint(Vec2::ANCHOR_MIDDLE);<span style="white-space:pre"></span>//设置锚点为中心点layer1->setPosition(visibleSize.width / 2, visibleSize.height / 2);//方块二LayerColor *layer2 = LayerColor::create(Color4B::GREEN, 100, 100);this->addChild(layer2);layer2->ignoreAnchorPointForPosition(false);layer2->setAnchorPoint(Vec2::ANCHOR_MIDDLE);layer2->setPosition(Vec2(layer1->getPositionX() + 200, layer1->getPositionY()));//创建监听器auto listener1 = EventListenerTouchOneByOne::create();listener1->setSwallowTouches(true);//为监听器分配回调函数listener1->onTouchBegan = [](Touch *t, Event *e){CCLOG("listener1 touch begin!!!!");/*********************************获取被点击的对象,**并获取点击的点是否在对象中,这里点击的点是OpenGL的坐标点,转换为当前对象内的点**如果在,设置透明度为180,**并确认对象被点击事件,即return true************************************/auto target = dynamic_cast<Node*>(e->getCurrentTarget());auto pos = target->convertToNodeSpace(t->getLocation());Rect rect = { 0, 0, target->getContentSize().width, target->getContentSize().height };if (rect.containsPoint(pos)){//设置透明度,范围是:0~255,显示程度逐渐递增target->setOpacity(180);return true;}return false;};listener1->onTouchMoved = [](Touch *t, Event *e){CCLOG("listener1 touch Move!!!!");/***************************************************移动被点击对象,随着鼠标位置的变化进行相对应移动**************************************************/auto target = dynamic_cast<Node*>(e->getCurrentTarget());auto pos = Vec2(target->getPosition() + t->getDelta());target->setPosition(pos);};listener1->onTouchEnded = [=](Touch *t, Event *e){CCLOG("listener1 touch Ended!!!!");/******************************把被点击对象透明度设置回来,并判断应该覆盖的对象**************************/auto target = dynamic_cast<Node*>(e->getCurrentTarget());target->setOpacity(255);if (target == layer1){layer1->setLocalZOrder(10);layer2->setLocalZOrder(0);}else if (target == layer2){layer1->setLocalZOrder(0);layer2->setLocalZOrder(10);}};//克隆监听器一auto listener2 = listener1->clone();//分发监听事件_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, layer1);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener2, layer2);    return true;}
以上就是那个例子的实现。可能在分发函数的回调的时候会有点疑虑,就是这个:
var->onTouchBegan = [](Touch *t, Event *e){    //....}
这是C++11所支持的新特性,lamda表达式,它是一个匿名函数。而这里所分发的就是回调的函数,所以里面所实现的就是回调函数所需要的。

在lamda表达式中,有一个关键的地方,就是[ ]里面的符号问题,我们来看下它的语法:

[capture list] (parameter list) ->return type { function body }

关于方括号里面的所填的内容一般如下:

"this" : 把当前节点作为捕获的值,所以可以捕获当前节点中所有的子类或是变量属性;

"=" : 把该lamda函数外的一层属性变量拷贝一份,所以可以捕获外层的属性变量;

"&" : 把该lamda函数外的一层属性变量引用进来,所以可以捕获外层的属性变量并改变其值。

对于上面的代码,方括号里面填了“=”的来获取外面一层的所有变量并复制一份。这样,外面一层的方块变量layer1和layer2均可获取得到。

好了,以上就是单点触摸的简单介绍,下一篇会更进一步的对触摸相关的进行讲解。





0 0
原创粉丝点击