在俄罗斯方块游戏中正确使用 wait()/notify()

发布于 2024-10-31 19:08:21 字数 1729 浏览 1 评论 0原文


我正在为 Android 编写一个类似俄罗斯方块的游戏,并且正在尝试实现“实时部分”。我有一些似乎有效的东西,但我想确保我的实现是正确的。

我想要的是:

  • 形状以固定速率下降(假设每次形状的 y 递减时我想等待 n 毫秒)

  • 玩家可以随时放下形状,等待 n 毫秒的计时器必须立即中断,并仅针对下一个形状重新启动

  • 当形状掉落或形状无法再下降时,游戏会在创建另一个形状之前等待 m 毫秒

  • 系统必须能够随时停止线程

我正在做的事情如下(系统可以使用 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) 调用期间尝试删除三倍的形状,那么接下来的三个形状将自动删除(这不是我想要的)。

您认为这正确吗?
您有什么更正、建议或评论吗?

谢谢 :-)

I’m writing a Tetris-like game for Android and I’m trying to implement the “real-time part”. I have something which seems to work, but I want to be sure that my implementation is correct.

What I want is:

  • The shapes are going down at a fixed rate (say that I want to wait n milliseconds each time the y of the shape is decremented)

  • The player can drop the shape at any time and the timer waiting for the n milliseconds must then be immediately interrupted and start again only for the next shape

  • When the shape is droped or when the shape cannot go down anymore, the game waits m milliseconds before creating another shape

  • The system have to be able to stop the thread at any time

What I am doing is the following (the system can stop the thread with 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();
        […]
    }
}

In particular, the part synchronized(this) { wait(n); } looks funny because if I understand correctly this will take a lock on this and release it immediately.

But wait() requires to be used in a synchronized(this) block (why?) and I cannot either synchronize the whole run() method, because then if I try to drop three times the shape during the sleep(m) call, then the three next shapes will be automatically dropped (which is not what I want).

Does this seem correct to you?
Do you have any correction, advice, or remark?

Thank you :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月无声 2024-11-07 19:08:21

wait()方法用于使当前运行的线程等待调用wait()的对象调用notify()(在本例中这)。 synchronized(this) 部分需要确保当时只有一个线程访问 this

您无法同步整个 run() 方法,因为 run() 来自父(Thread)类,并且父类在声明中没有使用同步。

我不知道如何解决你的其他问题,因为我不明白你的程序现在是如何工作的。

The wait() method is used to make the current running thread to wait the object invoking wait() invoke notify() (in this case this). The synchronized(this) part needed to make sure only one thread at that time accessing this.

You can't synchronize the whole run() method, because the run() is from the parent (Thread) class and the parent didn't use synchonized in the declaration.

I don't know how to solve your other problem because I don't get how your program works right now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文