0

我正在制作基于文本的 RPG,我真的很想模仿时间。
我可以在玩家每次输入内容之间留出一些时间,但如果可能的话,我希望它比这更好。我想知道多线程是否是一个很好的方法来做到这一点。

我在想可能只是在后台有第二个非常简单的线程,它只有一个循环,每 1000 毫秒循环一次。每通过一次循环,世界时间将增加 1 秒,玩家将恢复一点生命值和法力值。

这是多线程可以做的事情,还是有一些我不知道的东西会使这不起作用?(如果它不能帮助我完成这个项目,我宁愿不要花很多时间努力学习它。)

4

3 回答 3

3

是的,多线程当然可以做到这一点,但要担心线程通常比替代方案更复杂(这将是主线程轮询各种更新事件作为其主循环的一部分,无论如何应该至少每 100 毫秒左右运行一次)。

在您的情况下,如果时钟线程遵循非常严格的规则,您可能会“没问题”。

  1. 时钟线程是唯一允许设置/修改时间变量的线程。
  2. main/ui 线程只允许读取时间。
  3. 您仍然必须使用系统时间函数,因为不能信任线程睡眠函数的准确性(根据系统活动,线程的更新循环可能要等到您请求它运行几毫秒后才会运行)。

如果你这样实现它,那么你甚至不需要熟悉互斥锁就可以让线程安全运行,而且你的时间是准确的。

但!这里有一些值得深思的地方:如果您想在一天中的特定时间绑定游戏内触发器怎么办?例如,将发布给用户的消息“太阳已经落山”或类似的消息。无论如何,所需的代码都需要在主线程上运行(除非您想实现跨线程消息通信队列!),并且可能看起来很像基本的周期性检查和更新时钟代码. 因此,此时您最好还是保留一个简单的统一线程模型。

于 2013-02-25T04:51:28.347 回答
0

我通常使用一个名为 Simulation 的类来推进时间。我在 C++ 中没有它,但我已经在 J​​ava 中完成了线程,它可以向前推进时间并根据计划(或计划时间的随机事件)激活事件。您可以将其转换为 C++ 或用于查看面向对象的实现如何。

package adventure;

public class Simulation extends Thread {

    private PriorityQueue prioQueue;

    Simulation() {
        prioQueue = new PriorityQueue();
        start();
    }

    public void wakeMeAfter(Wakeable SleepingObject, double time) {
        prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time);
    }

    public void run() {
        while (true) {
            try {
                sleep(5); 

                if (prioQueue.getFirstTime() <= System.currentTimeMillis()) {
                    ((Wakeable) prioQueue.getFirst()).wakeup();
                    prioQueue.dequeue();
                }

            } catch (InterruptedException e) {

            }

        }
    }

}

要使用它,您只需实例化它并添加您的对象:

 `      Simulation sim = new Simulation();

        // Load images to be used as appearance-parameter for persons
        Image studAppearance = loadPicture("Person.gif");

        // --- Add new persons here ---
        new WalkingPerson(sim, this, "Peter", studAppearance);
于 2013-02-25T06:04:07.603 回答
0

我将假设您的程序当前大部分时间都在等待用户输入 - 这会不规则地阻塞您的主线程并且会在相对较长的时间内阻塞,从而阻止您进行短时间相关的更新。并且您想避免复杂的解决方案(线程)。

如果你想在主线程中访问时间,没有单独的线程访问它是比较容易的(看例子)。

如果您在等待用户输入时不需要在后台执行任何操作,您就不能编写一个函数来根据等待时经过的时间计算新值吗?您可以在LastSystemTimeObserved每次需要使用某个时间相关变量时更新一些变量 - 调用一些函数,该函数根据自上次调用以来经过的时间计算变量的更改值,而不是每秒重新计算值.

如果您确实创建了一个单独的线程,请确保正确保护两个线程都访问的任何变量。

于 2013-02-25T06:08:43.133 回答