четверг, 19 апреля 2012 г.

5. Контроллер

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

5. Контроллер


Для того, чтобы заставить плашки перемещаться, требуется создать Контроллер, обрабатывающий внешние события (нажатия клавиш или TouchPad-а). Мы не будем оформлять Контроллер отдельным классом и просто определим обработчик событий TouchPad-а в MainView:

package com.whiterabbit.tags;

...
public class MainView extends View {

    private float x = -1;
    private float y = -1;

    ...
    private float abs(float x) {
        if (x >= 0) {
            return x;
        } else {
            return -x;
        }
    }
   
    private int sign(float x) {
        if (x < 0) {
            return -1;
        } else if (x > 0) {
            return 1;
        }
        return 0;
    }
   
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x = event.getX();
                y = event.getY();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if ((x >= 0)&&(y >= 0)) {
                    float dx = event.getX() - x;
                    float dy = event.getY() - y;
                    if (abs(dx) > abs(dy)) {
                        dy = 0;
                    } else {
                        dx = 0;
                    }
                    Tag t = model.findTag(x, y);
                    if (t != null) {
                        if (model.moveTag(t, sign(dx), sign(dy))) {
                            invalidate();
                        }
                    }
                }
                x = -1;
                y = -1;
                break;
        }
        return true;
    }
}


В Model доопределим метод поиска плашки по экранным координатам:

package com.whiterabbit.tags;

...
public class Model {

    ...
    public int getTagSize() {
        return tagSize;
    }
   
    public int getMarginX() {
        return marginX;
    }
   
    public int getMarginY() {
        return marginY;
    }

    public Tag findTag(float x, float y) {
        for (Tag t: tags.values()) {
            for (Item i: t.getItems()) {
                float tagSz = getTagSize();
                float startX = getMarginX();
                float startY = getMarginY();
                if (((i.getX()-1) * tagSz + startX <= x) &&
                    ((i.getX()-1) * tagSz + startX + tagSz > x) &&
                    ((i.getY()-1) * tagSz + startY <= y) &&
                    ((i.getY()-1) * tagSz + startY + tagSz > y)) {
                    return t;
                }
            }
        }
        return null;
    }
}


Запускаем и убеждаемся, что плашки начали двигаться :) Разумеется в этом коде есть место для разнообразных улучшений (например можно поделить расстояние между точкой касания и точкой отпускания TouchPad-а на размер плашки и перемещать (если такая возможность имеется) ее сразу на несколько клеток одним ходом или добавить анимацию перемещения), но все эти улучшения можно смело отложить до следующей итерации как низкоприоритетные.

Сейчас для нас важно, что прототип готов, его можно кому-то показать и его можно полноценно отлаживать. Вместе с тем, нашему прототипу еще очень и очень далеко до того уровня на котором приложения принято выкладывать на Android Market. Каковы недостатки текущей реализации, не позволяющие считать прототип полноценным релизом?

  1. Не сохраняется состояние приложения при его выгрузке (напомню, что Android может выгрузить Activity автоматически, например, при загрузке другого приложения). Фактически это означает, что при каждой загрузке приложения головоломку придется решать заново :(
  2. Мы запрограммировали всего одну головоломку. Несмотря на то, что головоломка эта достаточно сложная, решать раз за разом одно и то-же как-то не очень интересно
  3. В текущей реализации отсутствует какая-либо обработка завершения решения головоломки. Плашки можно перемещать до бесконечности, но чего-либо принципиально нового при этом не произойдет
  4. При загрузке головоломки отсутствует какая-либо справка. Просто непонятно, что нужно делать
Выполнив этот несложный анализ, мы получаем список задач, которые необходимо решить для завершения релиза первой итерации. В первую очередь, очевидно, что нам требуется какая-то база данных (БД), для хранения описания головоломок, текущего состояния и т.п.
Её проектированием мы и займемся на следующей неделе.

Комментариев нет:

Отправить комментарий