繁体   English   中英

ACTION_UP无效,但ACTION_DOWN正常

[英]ACTION_UP is not working, but ACTION_DOWN works fine

我一直在(慢慢地)学习如何使用Java和Android Studio对Android游戏进行编程。 我主要的学习资源是遵循Kilobolt教程网站上的教程 我发现这些功能非常有帮助,但是由于它们是有关Eclipse的Android ADT的教程,而且它们已有3年历史,因此我必须在每个部分进行很多学习才能学习Android Studio(这是一个巨大的过程)。

我发现,在大多数情况下,本教程中的逻辑是可靠的。 我的问题是,在Kilobolt提供的框架的SingleTouchHandler类中,ACTION_UP似乎不起作用。 这是输入类:

public interface Input {

public static class TouchEvent {
    public static final int TOUCH_DOWN = 0;
    public static final int TOUCH_UP = 1;
    public static final int TOUCH_DRAGGED = 2;
    public static final int TOUCH_HOLD = 3;

    public int type;
    public int x, y;
    public int pointer;

}

public boolean isTouchDown(int pointer);

public int getTouchX(int pointer);

public int getTouchY(int pointer);

public List<TouchEvent> getTouchEvents();

}

这是它的实现:

public class SingleTouchHandler implements TouchHandler {
boolean isTouched;
int touchX;
int touchY;
Pool<TouchEvent> touchEventPool;
List<TouchEvent> touchEvents = new ArrayList<TouchEvent>();
List<TouchEvent> touchEventsBuffer = new ArrayList<TouchEvent>();
float scaleX;
float scaleY;

public SingleTouchHandler(View view, float scaleX, float scaleY) {
    PoolObjectFactory<TouchEvent> factory = new PoolObjectFactory<TouchEvent>() {
        @Override
        public TouchEvent createObject() {
            return new TouchEvent();
        }
    };
    touchEventPool = new Pool<TouchEvent>(factory, 100);
    view.setOnTouchListener(this);

    this.scaleX = scaleX;
    this.scaleY = scaleY;
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    synchronized(this) {
        TouchEvent touchEvent = touchEventPool.newObject();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchEvent.type = TouchEvent.TOUCH_DOWN;
                isTouched = true;
                break;
            case MotionEvent.ACTION_MOVE:
                touchEvent.type = TouchEvent.TOUCH_DRAGGED;
                isTouched = true;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                touchEvent.type = TouchEvent.TOUCH_UP;
                isTouched = false;
                break;
        }

        touchEvent.x = touchX = (int)(event.getX() * scaleX);
        touchEvent.y = touchY = (int)(event.getY() * scaleY);
        touchEventsBuffer.add(touchEvent);

        return true;
    }
}

@Override
public boolean isTouchDown(int pointer) {
    synchronized(this) {
        if(pointer == 0)
            return isTouched;
        else
            return false;
    }
}

@Override
public int getTouchX(int pointer) {
    synchronized(this) {
        return touchX;
    }
}

@Override
public int getTouchY(int pointer) {
    synchronized(this) {
        return touchY;
    }
}

@Override
public List<TouchEvent> getTouchEvents() {
    synchronized(this) {
        int len = touchEvents.size();
        for( int i = 0; i < len; i++ )
            touchEventPool.free(touchEvents.get(i));
        touchEvents.clear();
        touchEvents.addAll(touchEventsBuffer);
        touchEventsBuffer.clear();
        return touchEvents;
    }
}
}

同样,这些是由Kilobolt的好人James Cho提供的框架,如果需要,可以在Kilobolt网站上轻松获得。

在我的实现中:TOUCH_DOWN(用于表示ACTION_DOWN用法的变量)可以正常工作。 但是,TOUCH_UP(对于ACTION_UP)根本不起作用。 这是我在游戏更新功能中使用的代码块:

    int len = touchEvents.size();
    for (int i = 0; i < len; i++) {
        TouchEvent event = (TouchEvent) touchEvents.get(i);
        if (event.type == TouchEvent.TOUCH_DOWN) {



        }

        if (event.type == TouchEvent.TOUCH_UP) {
            if (inBounds(event, 190, 350, 100, 100)) {

                game.setScreen(new Menu(game));
            }
        }
    }

在上面的代码中,当触摸离开屏幕时,TOUCH_UP应该允许我的游戏状态更改为“菜单屏幕”。 但是,什么也没有发生。

如果我放置game.setScreen(new Menu(game)); 在if语句中:

if (event.type == TouchEvent.TOUCH_DOWN)它工作正常。

这是代码中的错误,还是我对ACTION_UP和其他操作的工作方式有误解? 我使用三星Galaxy S5进行了测试。

谢谢你的帮助。 学习Android Studio和游戏开发一直是一个艰巨的过程,但是我肯定会越来越好。

您可能在ACTION_DOWN上返回false

仅当您在ACTION_DOWN事件上返回true时, ACTION_UP才有效。

您似乎在这里重新发明轮子。 您是否尝试过一种更简单的方法?

首先,实现实际的侦听器,例如View.OnTouchListener。 它很简单,是在API级别1中引入的,并且运行良好。

实际上,我什至没有SingleTouchHandler类(除非您计划在多个视图上设置此触摸侦听器。在这种情况下,请实现OnTouchListener而不是TouchHandler)。 我只需在OnTouchListener的构造函数中初始化onTouch方法,如下所示:

view.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event){
        //Synchronize if you wish
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //Press code
                break;
            case MotionEvent.ACTION_MOVE:
                //Move code
                break;
            case MotionEvent.ACTION_UP:
                //release code
                break;
        }
        return true;
    }
});

完全不需要任何额外的课程。 只需将其包含在View的子类的构造函数中即可。 它已经过测试,并且可以在SurfaceViews上按预期工作,如果您正在编写动态游戏,则无论如何都应该使用。 其次,如上所述,如果您希望在多个视图上设置此OnTouchListener,则需要使其成为自己的类,就像您已经拥有的类(SingleTouchHandler)一样,并使其实现View.OnTouchListener(而不是TouchHandler)。 但是,再次假设您正在编写动态游戏,则所有图形很可能都将绘制在一个SurfaceView上,这意味着将只有一个View可以在其上分配此OnTouchListener,从而无需一起使用类(使用方法如上所示)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM