Cocos2d-x 没有移动时调用 onTouchMoved
Cocos2d-x onTouchMoved called when no movement is occurring
我正在编写一个 cocos2d-x 3.71 跨平台应用程序(ios、android、windows10),但我在实现触摸和按住时遇到了问题仅在 Android 上检测 (ios 和 windows 工作正常)。我已经将其原因归结为这样一个事实,即当按住触摸而不移动时,onTouchMoved() 不断发射。我已经合并了一个解决方法,但这似乎是一个错误,我想知道是否有人有任何想法。
我在基于 cocos2d-x HelloWorld 示例的最小应用程序中重现了该问题。我只是从 cocos2d::Node (testNode) 派生了一个 class 并创建了它,并将其作为子项添加到 HelloWorldScene。在 testNode 中,我重写了更新函数并使用来自 onTouchBegan() 的 scheduleUpdate() 对其进行调度。在 update() 函数中,我简单地计算时间直到达到 0.25s,然后使用 unscheduleUpdate() 禁用更新。我在 onTouchMoved() 中有另一个 unscheduleUpdate() 调用以停止计算保持时间以防触摸移动。问题是,在 Android 上,onTouchMoved() 在触摸静止时开始不断触发。
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)
{
}
touch/hold 事件的典型输出:
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
如您所见,该位置 并未 实际移动....给出了什么?
作为参考,我正在 Windows 10、Visual Studio 2015、cocos2d-x 3.71 上开发,并在 Android 5.1.1 上进行测试(OnePlusOne phone)
我测试了你的代码,这个问题与 android lollipop 有关。在 kitkat 上一切正常(测试设备 Huawei Ascend P7 android 4.4.2):
09-24 11:51:25.351: D/cocos2d-x debug info(1058): Hold Time: 0.252129
09-24 11:51:27.361: D/cocos2d-x debug info(1058): Hold Time: 0.251298
09-24 11:51:28.711: D/cocos2d-x debug info(1058): Hold Time: 0.252115
09-24 11:51:30.101: D/cocos2d-x debug info(1058): Hold Time: 0.251961
我也在棒棒糖设备上试过(LG,但我不记得确切的型号),就像你说的那样。触摸的垃圾邮件移动到相同的位置。
作为解决方法,您可以像 Alex G 所说的那样做,或者记住最后一个位置(在触摸开始时记住它)并忽略具有完全相同位置的事件。
顺便说一句,我正在使用 Mac OS X Yosemite 和 Cocos2d-x 3.8.
您应该在 cocos2d-x github 页面上开始一个问题。
我正在编写一个 cocos2d-x 3.71 跨平台应用程序(ios、android、windows10),但我在实现触摸和按住时遇到了问题仅在 Android 上检测 (ios 和 windows 工作正常)。我已经将其原因归结为这样一个事实,即当按住触摸而不移动时,onTouchMoved() 不断发射。我已经合并了一个解决方法,但这似乎是一个错误,我想知道是否有人有任何想法。
我在基于 cocos2d-x HelloWorld 示例的最小应用程序中重现了该问题。我只是从 cocos2d::Node (testNode) 派生了一个 class 并创建了它,并将其作为子项添加到 HelloWorldScene。在 testNode 中,我重写了更新函数并使用来自 onTouchBegan() 的 scheduleUpdate() 对其进行调度。在 update() 函数中,我简单地计算时间直到达到 0.25s,然后使用 unscheduleUpdate() 禁用更新。我在 onTouchMoved() 中有另一个 unscheduleUpdate() 调用以停止计算保持时间以防触摸移动。问题是,在 Android 上,onTouchMoved() 在触摸静止时开始不断触发。
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)
{
}
touch/hold 事件的典型输出:
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
如您所见,该位置 并未 实际移动....给出了什么?
作为参考,我正在 Windows 10、Visual Studio 2015、cocos2d-x 3.71 上开发,并在 Android 5.1.1 上进行测试(OnePlusOne phone)
我测试了你的代码,这个问题与 android lollipop 有关。在 kitkat 上一切正常(测试设备 Huawei Ascend P7 android 4.4.2):
09-24 11:51:25.351: D/cocos2d-x debug info(1058): Hold Time: 0.252129
09-24 11:51:27.361: D/cocos2d-x debug info(1058): Hold Time: 0.251298
09-24 11:51:28.711: D/cocos2d-x debug info(1058): Hold Time: 0.252115
09-24 11:51:30.101: D/cocos2d-x debug info(1058): Hold Time: 0.251961
我也在棒棒糖设备上试过(LG,但我不记得确切的型号),就像你说的那样。触摸的垃圾邮件移动到相同的位置。
作为解决方法,您可以像 Alex G 所说的那样做,或者记住最后一个位置(在触摸开始时记住它)并忽略具有完全相同位置的事件。
顺便说一句,我正在使用 Mac OS X Yosemite 和 Cocos2d-x 3.8.
您应该在 cocos2d-x github 页面上开始一个问题。