Я пишу игру, подобную тетрису, для 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)
вызова, то три следующих форм будут автоматически отбрасываться (это не то, что я хочу).
Это похоже на вас?
У вас есть исправления, советы или замечания?
Спасибо :-)
Нет, я могу синхронизировать весь метод _run() _, нет компиляции или ошибки времени выполнения. Проблема заключается в том, что вызов _sleep (m) _ возникает, когда блокировки удерживаются _run() _, а метод _onTouch() _ не может работать в течение этого времени. Что вы не понимаете в программе? Основной цикл: _wait (n); doPhysics(); doDraw() _, и если пользователь хочет сбросить фигуру, вызов _notify() _ прервет _wait (n) _, а затем вызовет _sleep (m) _. –
Как насчет того, чтобы иметь логическое значение, когда он спящий, это ложь, и вы не можете отбросить фигуру, и если она не является ложью, она может ее потерять? – dieend