cocos2d / cocos2d-x

Cocos2d-x is a suite of open-source, cross-platform, game-development tools utilized by millions of developers across the globe. Its core has evolved to serve as the foundation for Cocos Creator 1.x & 2.x.
https://www.cocos.com/en/cocos2d-x
18.24k stars 7.05k forks source link

onTouchMoved() repeatedly called when there is no movement occurring #14021

Open rbpolaris opened 9 years ago

rbpolaris commented 9 years ago

Issue found with cocos2d-x 3.71 running on Android 5.1.1 (lollipop) . When a touch-and-hold (with no movement) is executed, onTouchMoved() is continuously called until the touch is released. This has been confirmed by a second party on Lollipop with cocos2d-x 3.8, but they said it does not occur on 4.4.2 KitKat.

Add the following class (testNode.h) as a child of the HelloWorldScene example and run on Android 5.1.1 to recreate the problem:

testNode.h:

#pragma once
#include "cocos2d.h"

class testNode : public cocos2d::Node
{
public:
    testNode() {}
    ~testNode() {}
    CREATE_FUNC(testNode);

    virtual bool init();
    virtual void update(float dt);
    bool onTouchBegan(cocos2d::Touch*, cocos2d::Event*);
    void onTouchMoved(cocos2d::Touch*, cocos2d::Event*);
    void onTouchEnded(cocos2d::Touch*, cocos2d::Event*);
    void onTouchCancelled(cocos2d::Touch*, cocos2d::Event*);

private:
    cocos2d::DrawNode* d;
    int id;
    bool touchIsDown;
    float touchTime;
    cocos2d::Label *messageLabel;
    cocos2d::Vec2 center;
};

testNode.cpp

#include "testNode.h"
USING_NS_CC;

bool testNode::init()
{
    if (!Node::init())
    {
        return false;
    }

    setContentSize(Size(50, 50));
    Size size = Director::getInstance()->getWinSize();
    Size visibleSize = Director::getInstance()->getVisibleSize();
    setPosition(Vec2(size.width / 2.0f, size.height / 2.0f));
    center.x = size.width / 2.0f;
    center.y = size.height / 2.0f;

    d = DrawNode::create();
    addChild(d, 10);
    d->drawCircle(Vec2(0, 0), 50, (float)M_PI * 2, 50, false, Color4F::RED);

    auto touchListener = EventListenerTouchOneByOne::create();

    touchListener->setSwallowTouches(true);
    touchListener->onTouchBegan = CC_CALLBACK_2(testNode::onTouchBegan, this);
    touchListener->onTouchEnded = CC_CALLBACK_2(testNode::onTouchEnded, this);
    touchListener->onTouchMoved = CC_CALLBACK_2(testNode::onTouchMoved, this);
    touchListener->onTouchCancelled = CC_CALLBACK_2(testNode::onTouchCancelled, this);

    _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

    messageLabel = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 18);
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    messageLabel->setPosition(Vec2(0,0));
    addChild(messageLabel, 1);
    return true;
}

void testNode::update(float deltaTime)
{
    // When update is scheduled with scheduleUpdate(), this will increment the touchtimer
    // used for differenciating different touch actions.
    if (touchIsDown)
    {
        touchTime += deltaTime;
        if (touchTime > 0.25)
        {
            unscheduleUpdate();
        }
    }
}

bool testNode::onTouchBegan(Touch* touch, Event* event)
{
    Vec2 touchPoint = touch->getLocation();
    float startDistFromCenter = center.getDistance(touchPoint);
    touchTime = 0.0f;
    // Handle touch only if inside the radius of the circle
    if (startDistFromCenter <= 50)
    {
        // Track how long the touch is held without moving or releasing
        touchIsDown = true;
        scheduleUpdate();
        return true;
    }
    else
        return false;
}

void testNode::onTouchMoved(Touch* touch, Event* event)
{
    Vec2 pos = touch->getLocation();
    log("moving...pos = %f , %f", pos.x, pos.y);
    touchIsDown = false;
    unscheduleUpdate();
}

void testNode::onTouchEnded(Touch* touch, Event* event)
{
    touchIsDown = false;
    unscheduleUpdate();

    log("Hold Time: %f", touchTime);
}

void testNode::onTouchCancelled(Touch* touch, Event* event)
{
}

Sample Output showing the problem:

09-23 23:42:39.852: D/cocos2d-x debug info(32508): startDistFromCenter: 33.753014 09-23 23:42:39.902: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.902: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.920: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.935: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.969: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.969: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.989: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:39.999: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:40.027: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:40.043: D/cocos2d-x debug info(32508): moving...pos = 246.732849 , 126.925316 09-23 23:42:40.043: D/cocos2d-x debug info(32508): Hold Time: 0.042597

stirem commented 7 years ago

I have the same issue with Cocos2d-x 3.14.1 when using multi touch on iPhone 6. The issue is not present on iPhone SE, iPhone 5 or iPad mini. When I touch and hold finger on iPhone 6 screen, touchMoved is continuously called.