Android обработка касаний для игры

222
07 января 2018, 06:28

Здравствуйте. Подскажите как реализовать задержку между событиями касаний и с мультитачем, пожалуйста.

Есть такой код:

public boolean onTouch(View v, MotionEvent event) {
    int action = event.getActionMasked();
    int index = event.getActionIndex();
    int x = (int)event.getX(index);
    int y = (int)event.getY(index);;
    int id = event.getPointerId(index);

    switch (action) {
        case MotionEvent.ACTION_DOWN : {
            Touch touch = Touch.create(id, x, y, Touch.DOWN);
            TouchManager.addTouch(touch);
        }
        case MotionEvent.ACTION_POINTER_DOWN : {
            Touch touch = Touch.create(id, x, y, Touch.DOWN);
            TouchManager.addTouch(touch);
            break;
        }
        case MotionEvent.ACTION_UP : {
            TouchManager.updateTouch(id, x, y, Touch.UP);
        }
        case MotionEvent.ACTION_POINTER_UP : {
            TouchManager.updateTouch(id, x, y, Touch.UP);
            break;
        }
        case MotionEvent.ACTION_MOVE : {
            TouchManager.updateTouch(id, x, y, Touch.MOVE);
            break;
        }
    }
    return true;
}

Он работает, но не совсем так, как хотелось бы. Дело в том, что если нажать на экран, то сразу вызывается "DOWN", а если отпустить, то "UP" не вызывается. Если же сразу начать водить пальцем по экрану, то "DOWN" не вызывается, а сразу вызывается "MOVE", а если отпустить палец, то вызывает "UP". Да и события слишком быстро проходят.

Мне нужно, что было так: Нажимаем на экран. Вызываем "DOWN" и если поднять пале менее, чем за 0.5 секунды, например, то вызывает "UP". Ну если продолжить двигать палец, то чтоб вызывало "MOVE", а после отпускания "UP".

Т.е down > move(если начать движение)|up(меньше 0.5 секунд палец на экране) > up(если было движение).

Надеюсь понятно объяснил.

Буду благодарен за помощь.

Answer 1

Ну во-первых, если вы написали код правильно, работать всё должно так: Нажали на экран - получили Down (в любом случае, даже хоть сразу стали двигать, Down есть всегда) , начали двигать - всегда Move. Отпустили и получили UP, даже если вы на мгновение коснулись и отпустили, или если коснулись подождали десять сек и потом отпустили , UP будет.
Если вы хотите, чтобы UP не вызывался, если вы быстро палец оторвете придется применять условие: В case поставить секундомер и в момент отпускания проверять прошло ли пол секунды, если прошло, то break , хотя я break не использовал. Насколько знаю используются return true или false . Сейчас покажу пример кода и станет ясно.
И кстати Ваши проблемы, я думаю, вызваны тем, что вы везде расставили break. Я не профи, но не понимаю зачем вам на вход View v, я не вижу где вы его используете. Вот как я делал: переопределяю метод onTouchEvent(MotionEvent event)

@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //выполняю код
                return true; //если вернуть ложь, я думаю, move не выполнится. 
            case MotionEvent.ACTION_MOVE:
               //выполняю код
                return true;
            case MotionEvent.ACTION_UP:
                //выполняю код и ничего не возвращаю, так как для меня это было последнее событие.
        }
        return false; //Что будет, если здесь вернуть истину я не знаю, буду рад если кто-нибудь пояснит.
    }

Ну и для того, чтобы UP вызывался, только при быстром поднятии пальца, можно реализовать таймер. Если мы находимся в DOWN более 0,5 сек , то возвращаем ложь и MOVE выполниться не должен.
Я например замечал, что тяжело поднять палец так, чтобы не отработал MOVE , малейшая дрожь в пальце и MOVE вызывается.

READ ALSO
приложение вылетает android studio

приложение вылетает android studio

Почему вылетает приложение при отладке на девайсе? Просто не запускается

255
Вылазит NullPointerException [дубликат]

Вылазит NullPointerException [дубликат]

На данный вопрос уже ответили:

242
sqlite запросы в Room

sqlite запросы в Room

В DAO у меня Query в которую мне бы нужно подставить запрос where из конструктораWHERE всегда разный, но не пойму как подставить запрос целиком

224
перевод Double значения времени( сек) в unix формат

перевод Double значения времени( сек) в unix формат

Например, вот такая дата со временем: 201701

231