在文本冒险中实现实时?

时间:2013-02-25 04:32:21

标签: c++ multithreading time game-engine adventure

我正在制作一个基于文本的角色扮演游戏,我真的很想模仿时间 我可以在每次玩家输入内容之间花一些时间,但是如果可能的话,我觉得它比那更好。我想知道多线程是否是一种很好的方法。

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

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

3 个答案:

答案 0 :(得分:3)

是的,mutlithreading当然可以做到这一点,但是厌倦了线程通常比替代方案更复杂(这将是主要线程轮询各种更新事件作为其主循环的一部分,它应该每100ms至少运行一次或者无论如何)。

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

  1. 时钟线程是唯一允许设置/修改时间变量的线程。
  2. 主/ ui线程只允许读取时间。
  3. 您仍然必须使用系统时间函数,因为线程休眠函数的准确性不受信任(取决于系统活动,线程的更新循环可能会在您请求它运行后几毫秒才运行)。
  4. 如果你这样实现它,那么你甚至不需要熟悉互斥体,以便安全地启动和运行线程,并且你的时间将是准确的。

    但是!这里有一些值得思考的问题:如果你想在一天的特定时间绑定游戏中的触发器怎么办?例如,将发布给用户“太阳已设置”或类似的消息。无论如何,执行该操作所需的代码需要在主线程上运行(除非您想实现跨线程消息通信队列!),并且可能看起来非常像基本的定期检查和更新时钟代码。所以在那时你最好只保留一个简单的统一线程模型。

答案 1 :(得分:0)

我通常使用名为Simulation的类来前进时间。我没有在C ++中使用它,但我已经完成了Java中的线程,它正在踩时间并根据计划(或计划时间的随机事件)激活事件。您可以将其转换为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);

答案 2 :(得分:0)

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

如果您想访问主线程中的时间accessing it without a separate thread is relatively easy(请查看示例)。

如果您在等待用户输入时不需要在后台执行任何操作,则根据等待时间过去的时间,您是否无法编写计算新值的函数?每次需要使用一个与时间相关的变量时,你可以得到一些变量LastSystemTimeObserved - 调用一些函数根据自上次调用以来经过的时间来计算变量的变化值,而不是每秒重新计算值。

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