Использование TouchScreens для управления игрой - PullRequest
8 голосов
/ 15 марта 2009

Я работаю над своей первой видеоигрой для платформы Android в виде проекта ночей и выходных.

Это идет хорошо, но я очень недоволен чувствительностью к контролю.

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

/-------------------------\
|                         |
|                         |
|                         |
|       Game Area         |
|                         |
|                         |
|                         |
|                         |
|                         |
/-------------------------\
|                         |
|       Touch Area        |
|                         |
\-------------------------/

В настоящее время я использую переменную состояния для хранения «MOVING_LEFT, MOVING_RIGHT, NOT_MOVING» и обновляю местоположение объекта проигрывателя каждый кадр на основе этой переменной.

Однако мой код, считывающий ввод с сенсорного экрана и устанавливающий эту переменную состояния, либо слишком чувствительный, либо слишком медленный, в зависимости от того, как я его настраиваю:

public void doTouch (MotionEvent e) {
    int action = e.getAction();

    if (action == MotionEvent.ACTION_DOWN) {
        this.mTouchX = (int)e.getX();
        this.mTouchY = (int)e.getY();           
    } 
    else if (action == MotionEvent.ACTION_MOVE) {
        if ((int)e.getX() >= this.mTouchX) {
            this.mTouchX = (int)e.getX();
            this.mTouchY = (int)e.getY();   
            if (this.TouchRect.contains(this.mTouchX, this.mTouchY)) {              
                this.mTouchDirection = MOVING_RIGHT;
            }
        } 
        else if ((int)e.getX() <= this.mTouchX) {
            this.mTouchX = (int)e.getX();
            this.mTouchY = (int)e.getY();
            if (this.TouchRect.contains(this.mTouchX, this.mTouchY)) {              
                this.mTouchDirection = MOVING_LEFT;
            }
        }
        else {
            this.mTouchDirection = NOT_MOVING;
        }               
    } 
    else if (action == MotionEvent.ACTION_UP) {
        this.mTouchDirection = NOT_MOVING;
    }       
}

Идея состоит в том, что при любом движении я проверяю предыдущее местоположение пальца пользователя, а затем выясняю, в каком направлении перемещать игрока.

Это не очень хорошо работает, я полагаю, что здесь есть некоторые разработчики для iPhone / Android, которые выяснили, как сделать хорошее управление с помощью сенсорного экрана, и могут дать несколько советов.

Ответы [ 2 ]

2 голосов
/ 15 марта 2009

Одна очевидная проблема заключается в том, что вы нигде не учитываете время с момента последнего касания.

Я бы посоветовал вам рассматривать касание игроков как выражение желаемого движения в аналоговом диапазоне от -x/+x и -y/+y, а затем выполнять фактическое движение в другом месте на основе времени.

1007 * Е.Г. *

objectPos += objectPos + (joyPos * timeDelta * maxSpeed);

Таким образом, если максимальная скорость вашего объекта составляет 10 мс-1, а палец игрока находится на 0,5 на панели управления, то объект будет перемещаться на 5 метров каждую секунду. Если ваша игра работает на скорости 10 кадров в секунду, то каждый кадр объекта будет двигаться на 0,5 метра.

Эти цифры являются вымышленными, но, надеюсь, демонстрируют необходимость отделить контроль от движения и затем учитывать время.

2 голосов
/ 15 марта 2009

Вы можете попробовать что-то похожее на «перетаскивание прямоугольников» в Windows. Когда вы удерживаете кнопку мыши на чем-то, вы не начинаете операцию перетаскивания, пока мышь не переместится за пределы небольшой области вокруг места для мыши. Причина в том, что при щелчке очень сложно удерживать курсор на одном пикселе.

Таким образом, первая попытка может быть (int)e.getX() >= this.mTouchX + DEAD_ZONE и аналогичной для другого случая, где DEAD_ZONE - это небольшое целое число.

Однако это не относится к развороту одним и тем же ударом. Вы можете справиться с этим, повернув влево только тогда, когда текущая позиция находится не менее DEAD_ZONE пикселей слева от последней позиции после поворота вправо, и наоборот.

...