2011-04-09 4 views
1


Я пишу игру, подобную тетрису, для Android, и я пытаюсь реализовать «часть в реальном времени». У меня есть что-то, что работает, но я хочу быть уверенным, что моя реализация верна.Правильное использование wait()/notify() для игры Tetris

Что я хочу:

  • Форма идет вниз по фиксированной ставке (говорят, что я хочу ждать п миллисекунд каждый раз, когда у формы декрементируется)

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

  • Когда форма падает на порядок или когда форма не может пойти вниз больше, игра ждет м миллисекунды до создания другой формы

  • Система должна быть в состоянии остановить поток в любое время

Что я делаю следующее (система может остановить поток с interrupt()):

class TetrisThread extends Thread { 
    private int n = 3000; // for testing purposes, in the real game n will be smaller ;) 
    private int m = 1000; 

    @Override 
    public void run() { 
     doDraw(); 
     while(!interrupted()) 
     { 
      try { 
       synchronized (this) { 
        wait(n); 
       } 
       doPhysics(); 
       doDraw(); 
      } catch (InterruptedException e) { 
       Thread.currentThread().interrupt(); 
      } 
     } 
    } 

    // This method is the one which will drop the shape, it is called from another thread 
    synchronized public boolean onTouch([…]) { 
     […] 
     // The shape has to be dropped 
     dropShape(); 
     notify(); 
     […] 
    } 

    private void doPhysics() throws InterruptedException { 
     […] 
     // The shape cannot go down or has been dropped 
     sleep(m); 
     createNewShape(); 
     […] 
    } 
} 

В частности, часть synchronized(this) { wait(n); } выглядит забавно, потому что, если я правильно понимаю, это займет блокировку на this и немедленно отпустите ее.

Но wait() требует, чтобы использоваться в synchronized(this) блоке (почему?), И я не могу либо синхронизировать весь run() метода, потому что тогда, если я пытаюсь бросить три раза формы во время sleep(m) вызова, то три следующих форм будут автоматически отбрасываться (это не то, что я хочу).

Это похоже на вас?
У вас есть исправления, советы или замечания?

Спасибо :-)

ответ

0

Метод wait() используется, чтобы сделать текущий выполняемый поток ждать объект вызывающего wait() вызвать notify() (в данном случае это). Часть synchronized(this) должна была удостовериться, что только один поток в то время получил доступ к this.

Вы не можете синхронизировать весь метод run(), поскольку run() из родительского класса (Thread), а родительский элемент не использует синхронизацию в объявлении.

Я не знаю, как решить вашу другую проблему, потому что я не понимаю, как работает ваша программа прямо сейчас.

+0

Нет, я могу синхронизировать весь метод _run() _, нет компиляции или ошибки времени выполнения. Проблема заключается в том, что вызов _sleep (m) _ возникает, когда блокировки удерживаются _run() _, а метод _onTouch() _ не может работать в течение этого времени. Что вы не понимаете в программе? Основной цикл: _wait (n); doPhysics(); doDraw() _, и если пользователь хочет сбросить фигуру, вызов _notify() _ прервет _wait (n) _, а затем вызовет _sleep (m) _. –

+0

Как насчет того, чтобы иметь логическое значение, когда он спящий, это ложь, и вы не можете отбросить фигуру, и если она не является ложью, она может ее потерять? – dieend