Почему не view.invalidate сразу перерисовывает экран в моей игре для Android - PullRequest
13 голосов
/ 22 сентября 2009

Я пытаюсь сделать игру для Android.

У меня есть игровой класс, который расширяет активность и обрабатывает весь пользовательский ввод. Затем у меня есть класс missionView, который расширяет представление и рисует уровень на экране.

Когда пользователь нажимает на дверь, я хочу добавить анимацию.

Что происходит: игра вызывает door.open. Изменяет состояние так, чтобы функция view.onDraw рисовала дверь наполовину открытой. Игра вызывает view.invalidate, который должен перерисовать экран. Затем игра спит полсекунды. Затем он снова вызывает door.open. При втором вызове функции она меняет состояние, поэтому функция view.onDraw полностью открывает дверь. Затем игра снова вызывает view.invalidate.

Проблема в том, что он не перерисовывает экран, когда попадает в view.invalidate. Если я установлю точку останова на строке, запусту отладчик и нажму на шаг, он не переходит в мою функцию view.onDraw. Он даже не может показать мне код, который он выполняет.

Что у меня есть: Дверной класс:

public boolean open()
{
   if (doorState == DoorState.Closed)
   {
       doorState = DoorState.Opening;

       return true;
   }
   else if (doorState == DoorState.Opening)
   {
        doorState = doorState.Open;
        return true;
   }
   else
   {
      return false;
   }
}

Игровой класс:

if (tile instanceof DoorTile)
{
    DoorTile doorTile = (DoorTile) tile;
    Door door = doorTile.getDoor();

    if (door.isClosed())
    {
        door.open();
        selectedEntity.openDoor();
        view.invalidate();    // This line does not work

        try 
        {
            Thread.sleep(500);
        } 
        catch (InterruptedException e1) 
        {
             // TODO Auto-generated catch block
             e1.printStackTrace();
        }
        door.open();

        // Handled touch event so break switch statement
        break;
     }
}

Ответы [ 3 ]

22 голосов
/ 22 сентября 2009

View # invalidate говорит системе перерисовать (через onDraw) представление, как только основной поток выйдет из режима ожидания. То есть, вызывая invalidate, вы планируете перерисовать ваше представление после того, как завершится вся остальная немедленная работа. Если код в вашем классе Game вызывается из основного потока и переводит этот поток в спящий режим, вы не просто приостанавливаете рендеринг, вы все время приостанавливаете обработку ввода (обычно это плохая идея). Как правило, никогда не спите, если вы не знаете, что делаете.

Если вы хотите, чтобы ваша игровая логика периодически задерживалась с использованием Thread # sleep, запустите ее в отдельном потоке и используйте view.postInvalidate (), чтобы дать сигнал основному потоку проснуться и вызвать onDraw.

14 голосов
/ 22 сентября 2009

Для игр я бы на самом деле использовал более низкий уровень доступа к графике. LunarLander от Google является отличным примером для этого. Вам нужно сделать две вещи:

  • вместо просмотра используйте SurfaceView
  • получить обработчик из SurfaceView
  • замените view.invalidate () на собственный метод repaint (), который будет содержать

    private void repaint() {
      Canvas c = null;
      try {
        c = surfaceHolder.lockCanvas();
        paint(c);
      } finally {
        if (c != null) {
          surfaceHolder.unlockCanvasAndPost(c);
        }
      }
    }
    

Метод рисования будет содержать то, что у вас есть в View.onDraw на данный момент

0 голосов
/ 15 декабря 2014

Я столкнулся с той же проблемой в моем приложении.

В моем случае я пытался вызвать invalidate() из [doInBackground()][1] метода [AsyncTask][2].

Проблема была решена путем перемещения invalidate() в [onProgressUpdate()][3] метод AsyncTask. То есть вы не можете обновить пользовательский интерфейс из doInBackground() метода AsyncTask. Он упоминается в документации для Android, но о нем так легко забыть ... так что не забудьте проверить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...