java - 这通常是 Java 接口(interface)用于设置事件处理程序的方式吗?这种方法是否存在隐藏的缺点?

标签 java android cocos2d-android

大家好,我对 Java 还是比较陌生,正在寻找完整性检查。

我一直在研究 Cocos2D 的这个 Java 端口并注意到 CCLayer 类具有对 Android native 触摸事件的内置 Hook 。这很好,但我真正喜欢的是像 CCSprite 这样的对象直接响应触摸事件,而不必在层中监听这些事件并遍历所有子项以找到哪些恰好与事件的 x/y 坐标相交.所以我认为这将是测试我对如何设置一些事件处理程序和创建 CCSprite 的子类的理解的绝佳机会,该子类实际上监听触摸而无需通过 CCLayer 来了解它。此外,我希望能够在特定的基础上为不同的 CCSprite 实例分配不同的行为,而无需进一步显式子类化,就像 Android Buttons 不需要被子类化只是为了给它们一个触摸事件的处理程序。

这是我第一次通过时想出的:

// My touch interface for all touchable CCNode objects.

package com.scriptocalypse.cocos2d;

public interface ITouchable {

    boolean onCCTouchesBegan();
    boolean onCCTouchesEnded();
    boolean onCCTouchesMoved();

}

现在使用 ITouchable 接口(interface)进行回调的类...

public class CCTouchSprite extends CCSprite implements CCTouchDelegateProtocol {

    protected ITouchable mTouchable;

    public void setTouchable(ITouchable pTouchable){
        mTouchable = pTouchable;
        boolean enable = mTouchable != null;
        this.setIsTouchEnabled(enable);
    }

    public void setIsTouchable(boolean pEnabled){
            // code to enable and disable touches snipped...
    }



    /////
    //  And now implementing the CCTouchDelegateProtocol...
    /////
    public boolean ccTouchesBegan(MotionEvent event) {

        Log.d("hi there", "touch me");
        if(mTouchable != null){
        mTouchable.onCCTouchesBegan();
        }
        return CCTouchDispatcher.kEventHandled;  // TODO Auto-generated method stub
    }

    public boolean ccTouchesMoved(MotionEvent event) {

        if(mTouchable != null){
            mTouchable.onCCTouchesMoved();
        }
        return CCTouchDispatcher.kEventIgnored;  // TODO Auto-generated method stub
    }

    public boolean ccTouchesEnded(MotionEvent event) {
        Log.d("hi there", "not touch me");
        if(mTouchable != null){
            mTouchable.onCCTouchesEnded();
        }
        return CCTouchDispatcher.kEventIgnored;  // TODO Auto-generated method stub
    }

}

最后,实例化类并实现接口(interface)...

final CCTouchSprite sprite = new CCTouchSprite(tex);
sprite.setIsTouchEnabled(true);
sprite.setPosition(CGPoint.ccp(160,240));
sprite.setTouchable(new ITouchable(){
    @Override
    public boolean onCCTouchesBegan() {

        Log.d("SWEET SUCCESS", "I got a touch through my interface!");

        return true;
    }

    @Override
    public boolean onCCTouchesEnded() {
        Log.d("SWEET SUCCESS", "You stopped touching my interface!");
        sprite.runAction(CCRotateBy.action(1, 360));
        return false;
    }

    @Override
    public boolean onCCTouchesMoved(){
        Log.d("SWEET SUCCESS", "You moved the touch");
        return false;
    }
});

所以所有这些都有效。子类确实成功地向 Cocos2D 触摸调度程序注册,它成功地调用了那些 ccTouches 函数并将它们传递给 MotionEvents,如果接口(interface)已被实例化,这些函数又会调用我的接口(interface)函数。

这是做这件事的“正确”方法吗(按照您认为合适的方式定义“它”,从使用接口(interface)创建事件处理程序到使用 Cocos2D,再到编写 Java)?这有我不知道的缺点吗?这在某种程度上是否比遍历所有作为 CCLayer 子对象的 CCNode 对象更糟糕?如果是这样,那怎么可能?

最佳答案

我认为您已经掌握了正确设置监听器的基础知识。不过,有些事情我会改变。

首先是setter setIsTouchable。有点奇怪。您需要一个监听器对象来向右传递触摸事件吗?那么当你将它传递为真时(就像你的例子那样),这个 setter 会做什么?您截断了代码,但将 boolean 字段设置为 true 在这里似乎不正确,因为它会使 Sprite 对象处于不一致的内部状态。我会放弃那个二传手。 getter 可以只评估 mTouchable 是否已分配或为空。

其次,为什么要将自己限制为一个听众?将 mTouchable 更改为 mTouchables,成为 ITouchable 的列表。然后将 setTouchable 更改为 addTouchable 并可能添加 removeTouchable 和 clearTouchables 方法。通过这种方式,您可以为必须响应相同事件的不同行为添加多个监听器。这也是大多数其他事件系统的工作方式。然后,您只需更改 isTouchable 即可检查列表是否为空。

关于java - 这通常是 Java 接口(interface)用于设置事件处理程序的方式吗?这种方法是否存在隐藏的缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5178131/

相关文章:

java - 方法签名中的 GWT RPC 特定集合类型 - 仍然推荐吗?

php - 我在 Android 中将 JSON 对象解析为 String 时出错

java - 我无法运行 WiEngine 骨架项目

android - 表面 View 作为 android 中的位图

java - 如何停止 BufferedReader readline()?

java - 为什么当 Intent 双值时我得到 null

java - 当我的spark作业出现内存不足错误时应该如何调试?

java - 当Android应用程序处于概览状态时如何更改 Activity/ View

android - 通过 Whatsapp 或 Facebook 分享图片和文字

Android:1024px 图像大小限制?