《cocos2d-x游戏开发之旅》学习笔记(二)

第5章

5.1.单点触摸的实现

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [](Touch *t,Event *e){
    	Point pt1 = t->getLocation();
    	Point pt2 = t->getLocationInView();
    	Point pt3 = Director::getInstance()->convertToGL(pt2);
    
    	log("onTouchBegan! pt1 x=%f,y=%f", pt1.x, pt1.y);
    	log("onTouchBegan! pt2 x=%f,y=%f", pt2.x, pt2.y);
    	log("onTouchBegan! pt3 x=%f,y=%f", pt3.x, pt3.y);
    	return true;
    };
    
    listener->onTouchEnded = [](Touch *t, Event *e){
    	log("onTouchEnded!");
    };
    
    listener->onTouchMoved = [](Touch *t, Event *e){
    	log("onTouchMoved!");
    };
    
    listener->onTouchCancelled = [](Touch *t, Event *e){
    	log("onTouchCancelled!");
    };
    
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    //Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}

效果:

《cocos2d-x游戏开发之旅》学习笔记(二)_第1张图片

常用的触摸事件有4个:

  • onTouchBegan:触摸事件开始,也就是手指按下时
  • onTouchMoveed:触摸移动事件,也就是手指在屏幕滑动的过程
  • onTouchEnded:触摸事件结束,也就是手指松开时
  • onTouchCancelled:打断触摸事件事件,一般是系统层级的消息,如手机来电,触摸事件就会被打断
t->getLocation():获取单击坐标,基于3D
t->getLocationInView():获取单击坐标,基于2D
Director::getInstance()->convertToGL(pt2):获取单击坐标,基于Cocos2d-x

_eventDispatcher是一个事件管理器,可以通过Director::getInstance()->getEventDispatcher()获得,是一个单例类

addEventListenerWithSceneGraphPriority函数的声明为:
void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
  • EventListener*listener:事件监听对象,当触摸事件发生时通过它来回调
  • Node*node:绑定的对象,当node对象被释放时,监听事件的注册也会被取消。当有多个触摸事件发生时(比如几个按钮叠加在一起),会根据node的层次优先回调(越在上面的对象越优先回调)
也可以用addEventListenerWithFixedPriority函数来注册监听事件,但需要手动指定触摸事件回调的优先级,并且需要手动取消监听事件。



5.2.单点触摸-截断事件

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [](Touch *t, Event *e){
    	auto target = static_cast(e->getCurrentTarget());
    	Point pt = Director::getInstance()->convertToGL(t->getLocationInView());
    
    	if (target->getBoundingBox().containsPoint(pt))
    	{
    		target->setOpacity(100);//设置透明度
    		return true;
    	}
    
    	return false;
    };
    
    listener->onTouchEnded = [](Touch *t, Event*e){
    	auto target = static_cast(e->getCurrentTarget());
    	target->setOpacity(255);
    };
    
    listener->setSwallowTouches(true);
    
    Sprite *sp1 = Sprite::create("sprite1.png");
    sp1->setPosition(Point(200, 200));
    this->addChild(sp1);
    
    Sprite *sp2 = Sprite::create("sprite2.png");
    sp2->setPosition(Point(200, 200));
    this->addChild(sp2);
    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, sp1);
    //此处传给参数1的是listener的复制对象
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener->clone(), sp2);

	
    return true;
}

效果:

点击重叠部分:
《cocos2d-x游戏开发之旅》学习笔记(二)_第2张图片

关键的函数是setSwallowTouches,给它传递参数true,表示启动截断功能,也就是说可以决定是否要将触摸事件向下传递。
另外要注意的一点是注册监听事件时一个事件监听对象只能与一个目标对象绑定,否则运行会出错,可以使用clone函数来产生另一个事件监听对象。
还有,在onTouchBegan函数中,return true表示将触摸事件截断,return false表示不截断。


5.3.多点触摸

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    Label *lb1 = Label::create("", "Arial", 24);
    lb1->setPosition(Point(400, 280));
    this->addChild(lb1, 1, 1);
    
    Label *lb2 = Label::create("", "Arial", 24);
    lb2->setPosition(Point(400, 200));
    this->addChild(lb2, 1, 2);
    
    Label *lb3 = Label::create("", "Arial", 24);
    lb3->setPosition(Point(400, 100));
    this->addChild(lb3, 1, 3);
    
    auto listener = EventListenerTouchAllAtOnce::create();
    
    listener->onTouchesBegan = [&](const vector& touches, Event *e){
    	auto logText = (Label *)this->getChildByTag(1);
    	logText->setString(Value((int)touches.size()).asString() + " Touches");
    };
    
    listener->onTouchesMoved = [&](const vector& touches, Event *e){
    	auto logText = (Label *)this->getChildByTag(2);
    	string text = Value((int)touches.size()).asString() + " Touches:";
    	for (auto &touch:touches)
    	{
    		text += "[touchID" + Value(touch->getID()).asString() + "],";
    	}
    	text.erase(text.end()-1);
    	logText->setString(text);
    };
    
    listener->onTouchesEnded = [&](const vector& touches, Event *e){
    	auto logText = (Label *)this->getChildByTag(3);
    	logText->setString(Value((int)touches.size()).asString() + " Touches");
    };
    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}

效果:

《cocos2d-x游戏开发之旅》学习笔记(二)_第3张图片


你可能感兴趣的:(《cocos2d-x游戏开发之旅》学习笔记(二))