五毛的cocos2d-x学习笔记06-处理用户交互

前几篇感觉自己在写教育文章,╮(╯▽╰)╭。今天换成开发者的口吻,毕竟我也是在边学边写博客。

处理用户交互包括:单点触摸、多点触摸、事件传递、传感器、物理按键等部分。

单点触摸:

触摸事件传递顺序

onTouchBegan——>onTouchMoved——>onTouchEnded。还有一个onTouchCancelled。

这些事件的监听都是闭包函数(匿名函数,lambda表达式),

[](Touch *t, Event *e){

    //return false;//只有onTouchBegan需要返回bool值
}

如果事件的onTouchBegan监听返回false,则触摸事件不会向后传递。

添加事件监听有3个步骤:1、创建事件监听对象指针;2、实现触摸事件监听;3、分发触摸事件监听

下面是一个示例,我在控制台打印输出3个事件名称。

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if (!Layer::init())
    {
        return false;
    }

    Size size = Director::getInstance()->getVisibleSize();

    LabelTTF *label = LabelTTF::create("Click me", "Courier", 30);
    label->setPosition(size.width / 2, size.height/2);
    addChild(label);

    //一次只能监听到一个触摸点
    EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [](Touch *t, Event *e){
        /*if (e->getCurrentTarget()->getBoundingBox().containsPoint(t->getLocation())){
            log("onTouchBean");
            return true;
        }*/
        /*if (label->getBoundingBox().containsPoint(t->getLocation())){
            log("onTouchBegan");
            return true;
        }*/
        log("onTouchBegan");
        return true;
    };
    listener->onTouchMoved = [](Touch *t, Event *e){
        log("onTouchMoved");
    };
    listener->onTouchEnded = [](Touch *t, Event *e){
        log("onTouchEnded");
    };
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, label);
    return true;
}
View Code

运行效果中,我先用鼠标左键点击了一下窗体界面,控制台输出onTouchBegan,然后松开鼠标左键,控制台输出onTouchEnded;重复一次;然后点击之后移动,控制台不停输出onTouchMoved,然后松开,控制台输出onTouchEnded。

运行效果:

多点触摸:

多点触摸的事件监听变成了onTouchesBegan, onTouchesMoved, onTouchesEnded。还有一个onTouchesCancelled。

事件监听的闭包函数:

[](std::vector<Touch*> ts, Event *e){
    //只有onTouchesBegan需要返回bool值
}

这个测试的话要用真机。

举个栗子:

监听当前层的触摸事件,手指触摸手机屏幕并移动的时候,控制台输出触摸点的个数。

代码如下:

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if (!Layer::init())
    {
        return false;
    }

    Size size = Director::getInstance()->getVisibleSize();

    //监听多点触摸事件
    auto listener = EventListenerTouchAllAtOnce::create();
    listener->onTouchesBegan = [](std::vector<Touch*> *ts, Event *e){
        log("onTouchesBegan");
    };
    listener->onTouchesMoved = [](std::vector<Touch*> ts, Event *e){
        log("touches moved, and touch count is %d", ts.size());
    };
    //监听当前的层
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    return true;
}
View Code

运行效果:

算了,不运行了。(⊙o⊙)…

等我写一篇把windows平台的代码编译到Android平台的流程再说。

传感器:

这里介绍加速度传感器的调用。

关键代码:

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if (!Layer::init())
    {
        return false;
    }

    Device::setAccelerometerEnabled(true);//开启加速器

    auto listener = EventListenerAcceleration::create([](Acceleration* a, Event *e){
        //%g是自动选择%f和%e中总位数最短的来表示浮点数,%f是浮点数形式,%e是指数形式
        //x, y, z是double类型
        log("x:%g, y:%g, z:%g", a->x, a->y, a->z);
    });

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    return true;
}
View Code

这个需要真机运行才能看到效果,意味着需要编译到Android、ios或wp平台。后面我会写一篇编译并运行到Android真机的博客。

物理按键交互:

这里的代码示意的是Android平台的返回键的监听:

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if (!Layer::init())
    {
        return false;
    }

    auto listener = EventListenerKeyboard::create();
    listener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event *e){
        log("key code : %d", keyCode);
        switch (keyCode)
        {
            //listen in the back key in Android Devices
        case EventKeyboard::KeyCode::KEY_BACKSPACE:
            Director::getInstance()->end();
            break;
        }
    };

    return true;
}
View Code

还是需要用真机测试。

原文地址:https://www.cnblogs.com/rainmer/p/4690003.html