Erlang中的怪物AI - 如何勾选过程,如何阅读玩家的健康

时间:2014-06-13 13:59:59

标签: erlang

试图围绕Erlang的流程,这里有两个关于游戏服务器的问题:

第一个问题:如果空闲,怪物应该每隔x秒随机移动一次。什么是每隔x秒更新或勾选一个过程的正确方法?最优雅的方法是什么?

第二个问题:怪物想要攻击一名玩家,但想先检查一下它的位置。常见的方法是:

if dist(mob_pos, player_pos) < 10 then send attack message to player

我知道我可以通过发送一个“请求发布”来检查该播放器的位置。消息并在下次更新时读取结果。但问题在于:它的下一次更新,并且怪物不会知道它只是要求pos攻击玩家。什么是Erlang检查位置然后向玩家发送攻击消息的方式?

2 个答案:

答案 0 :(得分:1)

问题1: 标准库中有一个很好的计时器模块: http://www.erlang.org/doc/man/timer.html 这可以为您的申请打勾。

问题2: 好像你想知道怪物和玩家之间的同步。 如果你在玩家和怪物之间进行异步消息传递,那么问题和响应之间可能会有一个滴答声从计时器到达(尽管非常不可能)。 您可以做的是进行同步调用,这将阻止进程直到操作解决。

你可以将怪物和玩家建模为gen_server,并使用他们的强制转换(异步)和调用(同步)方法。看到: http://www.erlang.org/doc/man/gen_server.html

答案 1 :(得分:0)

  

第一个问题:怪物应该每隔x秒随机移动一次   如果闲着什么是每个x更新或勾选一个过程的正确方法   秒?最优雅的方法是什么?

如果您使用了receive / after子句,则会唤醒erlang进程以执行此&#34;&#34;

代码块。这是做你想做的最有效的方法:

receive
  msg_a -> ...;
  mg_b -> ...;
  ...
  after <milliseconds> ->
     do_whatever you have to
end.

erlang VM无法跳过&#34;&#34;&#34;代码块。同样,&#34;&#34;&#34;代码块不是来自邮箱的邮件,您不能丢失它。并且它保证会被执行。

但如果你使用这个方案,你的怪物将是独立的演员。 例如。 Monster1诞生了。然后他睡了10000毫秒。在另一个怪物出生的另一个 - 他睡了10000毫秒。因此,当第二个怪物睡了一秒钟时,Monster1会被唤醒一秒钟。

在现实世界中,一切都如上所述,但:) 每个人的生物时间标记独立。但物理时间同时为所有对象打勾。

所以这取决于你想要使用的时间 - 生物或物理(在游戏方面) Erlang更适合生物学。但物理可以使用同步来实现。

  

第二个问题:怪物想要攻击玩家,但是想要   首先检查它的位置。常见的方法是:   如果dist(mob_pos,player_pos)&lt; 10然后向玩家I发送攻击消息   我知道我可以通过发送一个“请求发布”来检查玩家的位置。   消息并在下次更新时读取结果。但这是   问题:它的下一次更新,怪物不会知道它   刚刚要求pos攻击玩家。 Erlang的方式是什么?   检查位置,然后向玩家发送攻击消息   事后?

这是您系统的设计缺陷。 强盗是否会在你想抢劫你的时候问你的位置或其他什么? :)))

应该有#34;游戏&#34;处理。这个过程

  1. 只有当您使用&#34;物理时间&#34;,&#34;&#34;&#34;子句发送同步(call&lt; - &gt; handle_call)&#34; time tick&#34;消息到所有游戏对象。他们会在#34;时间刻度&#34;
  2. 上做他们需要的任何事情
  3. 此游戏过程应观察对象的所有位置。它可能甚至不是唯一的过程,但它可能是一个监督树。比如,#34;游戏&#34;物体在10秒后从一个时刻开始询问强盗:&#34;你在哪里&#34;,他回答&#34;我在pos(x,y,z)&#34;,然后&#34;游戏&#34;要求一个生物被抢劫&#34;家伙,你在哪里?&#34;。这个松散的生物回答:&#34;我在位置(x1,y1,z1)和#34;并且如果所有通信都在可接受的范围内,并且如果距离是由#34;游戏&#34;被抢劫的生物和强盗之间的对象位于可抢夺的界限内 - 强盗抢劫。(#34;游戏&#34;向他发送消息&#34;抢劫&#34;)。

    你可以考虑一个游戏&#34;对象就像是某种神。

  4. 这只是一种方法。同步的。

    但您可以实施其他方法/设计。一个异步的,就像常见的相对论问题一样:)是一个恩斯坦:)当一个强盗没有问过&#34;关于受害者的位置。但他&#34;看到&#34;如果可以,受害者的位置。

    在这种情况下,应该有一个&#34;灯&#34;对象/进程,可以判断是否可以看到另一个对象。

    例如,强盗的受体(眼睛)正在接受&#34;州。所有&#34;光束&#34;进程将有关附近地形的信息转移给强盗。

    为此,您应该将erlang进程绑定到每个单元格。并且应该允许每个单元仅将消息传递给附近的单元。例如,如果你使用像文明5那样的6面细胞,那么就会有6个附近的细胞。通过这种方式,您甚至可以模拟当地的物质时间&#34;像  Enstein's works

    这是另一个更复杂的架构。我不会在这里解释它,请注意它将需要更多的字母和页面:)

    我给了你一个想法,2个概念。你可以使用erlang推进它们。祝你好运!