2013-02-25 45 views
0

我正在制作一个基于文本的RPG游戏,我真的很想效仿时间。
我可以在每次玩家输入一些东西之间进行一些时间传递,但是如果可能的话,它会比这更好。我想知道多线程是否是一个很好的方法来做到这一点。在文本冒险中实现实时?

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

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

+0

http://www.cplusplus.com/reference/ctime/有什么问题? – thiagoh 2013-02-25 04:35:20

+0

它会完成这项工作。但是如果你采取这种方法,它会让你对熟悉互斥体的人产生一些伤心。 – 2013-02-25 04:36:05

+0

为什么有这样的线程比替代方案更好? – 2013-02-25 04:40:08

回答

3

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

在你的情况下,如果时钟线程遵循相当严格的规则,你可能会“确定”。

  1. 时钟线程是唯一允许设置/修改时间变量的线程。
  2. 主/ UI线程只允许读取时间。
  3. 您仍然必须使用系统时间函数,因为线程休眠函数的准确性不可信(取决于系统活动,线程的更新循环可能在您请求运行后几毫秒内才会运行)。

如果你像那样实现它,那么你甚至不需要熟悉互斥体就可以安全地启动并运行线程,并且你的时间将是准确的。

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

+0

不知道我最后的评论是否经过o.O.无论如何,如果它没有:我是相当新的编码(只需要为java,C++和汇编几个类),所以它会花一点时间让我理解你的意思。感谢您的快速回答:) – 2013-02-25 05:05:45

+0

在您的回答中,您说时钟线程是唯一能够操控时间的线程。但id需要我的球员能够休息。有没有办法让我的主线程发出信号通知我的时钟线前进若干小时? – 2013-02-25 05:11:55

+0

为此,您可以:1.做一个完整的互斥体排除设计,2.挂起时钟线程,3.向消息队列发送时钟线程的时钟重置请求。我已经按他们所代表的难度顺序(1是最简单的)列出了它们。请记住,对于每1000毫秒只“执行一些操作”的线程,99%的时间很可能仍然可以正常工作。所以可能你永远不会知道你是否做得对。 – jstine 2013-02-25 15:48:25

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); 
0

我会假设你的程序目前花费在等待用户输入其大部分的时间 - 这块您的主线程不规则,并且时间相对较长,这会阻止您进行短时间更新。而你想避免复杂的解决方案(线程)。

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

如果您在等待用户输入时不需要在后台执行任何操作,您是否可以根据等待时已过的时间计算新值的函数?你可以有一些变量LastSystemTimeObserved,每当你需要使用一个你的时间依赖变量时,它就会被更新 - 调用一些函数来计算变量的变化值,这个函数根据上次被调用的时间过去了多少时间,而不是每次都重新计算一次值第二。

如果你确实做了一个单独的线程,请确保你的线程都访问了任何变量。