【问题标题】:Touch Event on Sprite with Cocos2d-x 3.x?使用 Cocos2d-x 3.x 在 Sprite 上触摸事件?
【发布时间】:2016-01-25 02:40:23
【问题描述】:

在我的场景中,我有一个带有多个自定义精灵的矢量。当我点击其中一个时,我希望在场景中的另一个元素上触发一个动作,可以是向量中的另一个精灵,也可以是另一个节点。我一直在研究最好的方法来做到这一点,但我不太确定如何实现它。选项有:

  • 在场景中添加一个触摸监听器,并使用rect. containsPoint(point) 验证它是否在精灵边界内被点击。在那之后,我必须得到被点击的精灵来做我想要的动作。对我来说,这样做似乎不太干净。如果两个精灵重叠,我必须验证精灵是在后面还是在前面,以便检索所需的精灵。我按照这个例子:Touch Event example

  • 在精灵的子类中添加一个触摸监听器(我的自定义精灵)。并在其中添加onTouchBeganonTouchEnded。但是这样,我不知道如何修改另一个精灵的属性,或者场景中的另一个元素(是否可以像 Objective-C 那样使用委托?)。我按照这个例子:Subclass Sprite Example

我的主要问题是我不太了解如何让一个节点与场景中的另一个节点交互。我看过很多教程,但在所有教程中,当你与一个节点交互时,它只会改变它的属性,而不是其他节点的属性。

提前致谢。

【问题讨论】:

  • 你能发布一个完整的最小代码示例吗?
  • @Raptor 更新了我的问题。我的代码与提供的链接中的代码相同。

标签: c++ cocos2d-x-3.0


【解决方案1】:

我将提出“EventCustom”方式:)

您可以在您的 touchBegan / touchEnded 方法中添加(无论您将它们放在哪里......你明白了......)用于将 EventCusto 传递给 _eventDispatcher 并将其发布给全世界的附加代码;)

EventCustom *e = new EventCustom("MyAwesomeEvent");
e->setUserData(ptrMyFantasticData); //This function takes a void pointer. cheers :)
_eventDispatcher->dispatchEvent(e);

您可以继承 EventCustom 类,但这几乎没有必要。您始终可以使用 setUserData() 将对象挂在其上。

现在需要对事件做出反应的对象可以通过

_myCustomListener = EventListenerCustom::create(
                "MyAwesomeEvent",
                 CC_CALLBACK_1(
                     ListeningClass::onMyAwesomeEvent, 
                     this
                 )
             );
_eventDispatcher->addEventListenerWithXXXXXPriority(_myCustomListener, XXX);
//ScreenGraphPriority / FixedPriority depends on situation. Either should work.

当你离开时删除你的监听器总是一个好习惯,所以在某个地方,也许在 onExit(),你删除了触摸监听器的地方也删除了这个监听器,因为

_eventDispatcher->removeEventListener(_myCustomListener);

有点偏离轨道,澄​​清一下: CC_CALLBACK_X 是一个有点棘手的名字。 X 表示编号。 args 目标函数将获得。在这里,事件调度程序将传递 1 个参数,即 ptr 到您传递给它的 EventCustom 对象,因此我们使用 CC_CALLBACK_1。下一个参数——这里是“this”——是调用方法的对象。 简而言之,我们可以说这个回调将导致一个函数调用this->onMyAwesomeEvent(e);

对于 CC_CALLBACK_2 以后,我们可以指定其他参数,从第 3 个参数开始。

回到手头的问题,ListeningClass::onMyAwesomeEvent 看起来像

void ListeningClass::onMyAwesomeEvent(EventCustom *e)
{
    MyFantasticData *d = (MyFantasticData *) e->getUserData();
    CCLOG("[ListeningClass::onMyAwesomeEvent] %d", d->getMyPreciousInt());
}

希望对你有帮助:)

【讨论】:

    【解决方案2】:

    使用setTagsetName 设置元素标签或名称。然后,如果元素 x 被触摸,请使用 getChildByTaggetChildByName 获取它们并执行您需要执行的操作。

    【讨论】:

      【解决方案3】:

      使用上面列出的第二个选项。 要使一个节点与场景中的另一个节点交互,您可以将触摸回调函数添加到您的自定义精灵对象,如下所示: https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase

      在主场景中你可以定义函数来处理这个回调。所以你可以在你的场景中做任何事情来统一

      【讨论】:

        猜你喜欢
        • 2014-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多