我游戏的主要资源是mass,存储为随时间变化的浮点数。资源节点增加了质量,工厂将其排干了。例如,如果我有一个资源节点每秒产生5个质量,那么我将在5 * deltaT
每个游戏步骤中获得质量。质量显示四舍五入到最接近的整数,并且增益/损耗指示器显示十分之一。
我应该如何处理质量达到零的问题?如果多个工厂试图一次建立工厂,这将产生竞争条件:工厂排在第一位,或者消耗较少资源的工厂一旦获得更多资源而获得优先权,因此建造速度比其他工厂快。
我该如何处理?我应该完全跳过这一步吗?
我游戏的主要资源是mass,存储为随时间变化的浮点数。资源节点增加了质量,工厂将其排干了。例如,如果我有一个资源节点每秒产生5个质量,那么我将在5 * deltaT
每个游戏步骤中获得质量。质量显示四舍五入到最接近的整数,并且增益/损耗指示器显示十分之一。
我应该如何处理质量达到零的问题?如果多个工厂试图一次建立工厂,这将产生竞争条件:工厂排在第一位,或者消耗较少资源的工厂一旦获得更多资源而获得优先权,因此建造速度比其他工厂快。
我该如何处理?我应该完全跳过这一步吗?
Answers:
我同意彼得的观点:没有固定的方法可以做到。您想怎么做取决于您想如何设计游戏。
但是,在这种情况下,我认为您要尝试达到的机制很明显:您只希望事物在尽可能多的质量范围内尽可能快地生产。
我要从“最高指挥官”的书中抽出一片,因为您的系统非常类似于他们的系统:如果您生产的产能超过了产能,那么处理它的最简洁的方法就是全面降低产能。降低生产能力实际上非常简单。
在每个更新步骤中,您的工厂不仅会生产固定数量的产品:它们以生产速度运行,这决定了他们在每个步骤中取得了多少进展以及消耗了多少质量。当您以75%的产能生产时,您的工厂每一步的进度可提高75%,并且与100%的产能相比,将消耗75%的质量。
为了计算生产速度,在完全构建任何东西之前,您应该查询工厂以确定该步骤将满负荷使用的总资源。然后执行一个简单的计算:
production speed = (total mass capacity / mass required this step)
if (production speed > 1.0) production speed = 1.0
假设此步骤需要125质量才能满负荷生产,但此步骤只有100质量。该方程式的生产速度为0.8(十进制表示为80%)。当您告诉工厂实际执行建造时,您便将这个值交给他们,以告诉他们建造的速度:现在,您的生产全线减慢。
您也可以开始暂时关闭工厂,直到生产能力释放为止,并且当产能极低时,远离发电机的工厂会发生这种情况可能非常有趣。
由您决定如何处理;有很多选择。最简单的方法可能是计算每种资源的生产能力,然后选择最低的资源,这样,最弱的资源将成为所有其他资源的瓶颈。
尽管我喜欢Jonathan Hobbs的回答,但我认为队列系统甚至更简单:
Queue<Factory> queue = ...;
int numFactories = ...;
Update()
{
int resources = GetAllResourcesForThisStep();
for(int i = 0; i < numFactories; i++)
{
if(queue.Peak().RequiredResources <= resources)
{
Factory f = queue.Pop();
resources -= f.RequiredResources;
queue.Push(f);
}
else
{
break;
}
}
}
平均而言,这可能与乔纳森(Jonathan)的实施方式相同。但是,如果将工作速度设置得很低,并且我的实现中可能有一个工厂对此资源有很高的请求,而乔纳森的解决方案可能会阻塞其他工厂几个框架,那么乔纳森的解决方案可能会出现问题。
我正在自己的游戏中开发类似的供应系统,因此我也一直在思考如何解决供应锁定问题和偏爱。为了说明问题,我将创建一个简单的示例:
如果您有一个列表:[生产者1,消费者1,消费者2,消费者3],并且从供应= 0开始按顺序进行更新,则会得到以下信息:
producer1 produces 5 mass. You now have 5 mass
consumer1 wants 3 mass. Success, you now have 2 mass
consumer2 wants 3 mass. Fail
consumer3 wants 3 mass. Fail
[next tick]
producer1 produces 5 mass. You now have 7 mass
consumer1 wants 3 mass. Success, you now have 4 mass
consumer2 wants 3 mass. Success, you now have 1 mass
consumer3 wants 3 mass. Fail
etc...
消费者1得到所有的乐趣,而消费者2和3则挨饿,直到满足消费者1。根据您的游戏,这可能不是理想的。我知道在我的游戏中不是。当我解决这个问题时,我将创建一个队列,在此队列中被喂食的消费者将移至队列的下一个队列,这是Roy T.所追求的。上面的示例如下所示:
producer1 produces 5 mass. You now have 5 mass
consumer1 wants 3 mass. Success, you now have 2 mass. <-- Move to end of queue
consumer2 wants 3 mass. Fail
consumer3 wants 3 mass. Fail
[next tick]
producer1 produces 5 mass. You now have 7 mass
consumer2 wants 3 mass. Success, you now have 4 mass <-- Note the order change
consumer3 wants 3 mass. Success, you now have 1 mass
consumer1 wants 3 mass. Fail
etc...
这样,每个人都将获得应有的资源份额。
我还计划实现一个用作优先级队列的附加队列,以便用户可以选择某些具有资源优先级的结构。优先级队列将始终在标准队列之前提供。确保首先更新所有生产者,然后再消耗所有资源,否则当您在生产价格变动的途中生产资源并且某些消费者已经挨饿时,队列将中断。
总结一下:更新生产者,然后更新优先级队列,将联邦消费者移至优先队列的末尾,然后更新标准队列,将联邦消费者移至标准队列的末尾。
好吧,由于我们在聊天中对此进行了一些讨论,因此我将继续介绍John的想法。
编辑:实际上,仅当consumableAmount与工厂应多长时间获取一批资源相关时,此解决方案才是首选方案。如果都一样,那么您确实可以只使用一个队列。
我的解决方案:优先级队列中列出的所有工厂。由于工厂遭受饥饿之害,优先级增加了。工厂消耗资源时,饥饿优先级设置为零。头等大事总是获得下一批资源。
在确定哪个工厂获得什么资源时,采用某种伪代码:
iterator i = factoryqueue.start()
bool starvation = false
while(i.next())
if(i.ready)
if (!starvation)
if (i.consumeAmount < resource.count) starvation = true
else
i.consume(resource)
i.priority = 0
if (starvation)
i.priority += 1
这样,您的工厂将依次生产1种产品,如果您想通过考虑消耗量来进行调整,以便更便宜地生产便宜的产品,则可以将优先级提高1 / consumeAmount。