精灵作为演员


12

我没有游戏开发方面的经验,但是是一名程序员。据我所知,在Scala语言中,您可以使用Actors进行可扩展的多任务处理,非常稳定。您甚至可以立即运行成千上万个它们,而不会出现问题。

所以我想,也许您可​​以将它们用作2D精灵的基类,以突破需要遍历所有精灵并移动它们的游戏循环事物。他们基本上会移动自己,受事件驱动。

这对游戏有意义吗?像这样多任务吗?毕竟,它将在JVM上运行,尽管如今这应该不成问题。

编辑:

摸索了一段时间之后,我注意到该想法只有一个真正的优势:多核支持。一个简单的游戏循环将仅在一个内核上运行,并将依次处理所有事情。

由于现代计算机,即使是现在的家用计算机,如今都内置了两个或多个内核,我认为让游戏程序员有效地使用其他内核是一个好主意。毕竟,我认为通常玩家只会在他的八核计算机上运行游戏,所以为什么不这样做呢。

我看到的另一个优点是,在Scala中,您可以拥有RemoteActors,可以用相同的方式来对待它,但可以在另一台计算机上运行。因此,这也许也可以简化网络游戏。

我打算尽快将其构建到我的Scala 2D引擎中。


我很想知道结果如何。我看过Scala几次,但之前从未涉足。
Davy8 2011年

许多人会争辩说,对于显式多核支持,您最好使用线程而不是进程(Scala actor对进程进行建模)。这是因为您可以利用线程之间的共享内存。当然,Actor模型不容易出错。
Kylotan

Scala actor在线程池的顶部多路复用,因此它们可能比线程更轻量。这意味着只要正确同步共享内存,他们就可以操纵共享内存进行通信。如果使用远程角色,则它们可能处于不同的进程中,唯一的通信方式是发送消息。
axel22 2011年

Answers:


7

我没有尝试,但是我是Scala程序员,我会说这不是最好的方法。精灵需要同步制作动画。演员无法保证它们会被公平地执行-因此某些精灵可能比其他精灵更快,这不是您想要的。您可能想使用障碍来同步它们,但是,那么-为什么要使用参与者。如果仅依赖消息传递,则实现这种同步(为1000个以上的参与者设置障碍)是过大的选择。

另一个问题是-您将消息传递用于什么?您需要精灵来交流吗?您可以由主演员发送一条消息,告诉每个子画面移至下一帧,但是就性能而言,这比直接调用方法并迭代一组子画面要大得多。

在我看来,您这里需要的是一种非常轻量级的多任务处理,根本没有消息传递。如果想确保公平,引入自己的类似于演员的实现可能是最好的方法,但是这太多了,却得不到太多收益。要看的另一件事是函数式反应式编程和scala.react,我相信这是该用例的更好匹配。

我已经在Scala中实现了2D等距游戏引擎。我只使用了1位全球演员来更新可见的动画精灵。

您可能希望使用参与者来实现您的游戏逻辑-例如,将游戏地图不同部分的计算分配给不同的参与者,以便他们并行更新游戏状态-并获得性能提升。我不会为每个游戏对象使用单个actor,而是为每个区域使用actor。如果粒度太细,性能会受到影响。

不过,如果我是你,我会尝试一下,只是看看会发生什么。


1

所以我想,也许您可​​以将它们用作2D精灵的基类,以突破需要遍历所有精灵并移动它们的游戏循环事物。他们基本上会移动自己,受事件驱动。

是什么事件会打动他们?

每帧会发出一次事件吗?

如果是这样,这如何实际改变了系统?

当最初在C ++上下文中研究面向对象时,我了解到有些人喜欢考虑这样的语句,例如xyz.doThis(x)含义“将doThis消息发送给xyz(带有x的有效载荷)并等待立即响应”。在此级别上看,基于事件或消息的系统与常规过程系统之间没有内在区别。


Actor是一个多线程解决方案。通信不同步。Scala actor(来自Erlang的概念)允许轻松进行多核编程。
埃利斯,

您确实有一个要点,但是这里的区别是基于Actor的精灵在执行动作时不会阻塞游戏循环,而方法接近则等待xyz.doThis(x)完成。我认为这甚至可以帮助提高游戏逻辑,特别是在多核系统上。
兰博

确实,它使跨多个内核分布实体处理变得更加容易。但是这样做的代价是,如果没有其他消息或消息中发送了额外的数据,您就无法轻易地将一个参与者推荐给另一个参与者。因此,您很快意识到这里的幼稚方法无法帮助您-您可以制定一种基于参与者的执行更新的方式吗?
Kylotan

当前,我正在尝试某种分布式更新:我的actor就像树结构中的节点,更新根目录将通过消息分发来更新子级。而且,真正的优势将是联网:在Scala中,可以通过相同的消息以相同的方式来处理Actor和RemoteActor(另一个系统上的Actor)。
Lanbo

是的,但是问题不在于触发更新,而是确保消息的接收者拥有执行该消息所需的所有信息。
Kylotan

0

这是考虑更新游戏对象的一种很酷的方法。我不了解Scala,但我想试一试,看看结果如何,甚至更好地发布您的结果!

我想到的主要问题是:如何管理某些游戏对象与其他对象的更新频率?您是否需要担心Sprite actor占用过多的周期,以致渲染系统没有时间每1 / 60th | 30th | 24th绘制一帧?

需要考虑的另一件事是,这将如何影响依赖于一系列快速事件顺序的玩家与AI交互的分辨率。根据游戏类型的不同,这可能关系不大。


Scala Actor的伟大之处在于它们是消息驱动的。他们每个人都有自己的消息/事件队列。我不确定'Draw'是消息还是调用方法。我认为是后者,这样无论事件队列的状态如何,都可以随时绘制Sprite。他们可以互相发送消息,以确保事情按一定顺序完成。
兰博

在那里要小心,我认为让每个子画面都有Draw方法或事件不会有用,除非它可以作为切换可见性的标志。在游戏循环的渲染阶段,将精灵渲染到屏幕的顺序对结果有很大影响。如果您有一个精灵位于另一个精灵的前面(尺寸朝向显示器),则希望将其绘制第二个。我看到Scala的Actors对于游戏循环的更新/逻辑部分很有用。
michael.bartnett

通常,那里只有一个draw方法,因此以这种方式实现它与处理sprite的常规方法应该没有太大区别。
兰博

好的,我误会了您的描述。我在某种程度上想象着精灵可以随时随地渲染自己。让我们知道结果如何!
michael.bartnett

0

好吧,我也不是一个程序员,但是您的建议没有任何问题。我什至没有想到这种培养演员的方法。

这可能是一个很大的挑战,因为IA必须非常准确才能避免意外行为,但是除此之外,我认为这是一个很好的建议


0

如果用精灵来表示游戏实体,那么可以肯定。

游戏实体不应该吸引自己。他们应该更新图形手柄,以描述需要在何处以及如何绘制它们。渲染系统或场景图或实际绘制的任何内容。有一张图形卡,此外,图形卡必须每16ms同步一次。像这样的设置不适用于分布式异步处理。

渲染系统应该是一个演员(如果有技巧,也可以是一对)。当游戏实体更新图形手柄时,它将消息发送到渲染系统。渲染系统可以使他们做出各种决策和/或优化,例如批处理渲染,遮挡,物理抖动平滑等。

我不是Scala开发人员,但是我在Erlang上做了很多工作。因此,如果我的某些Scala术语不正确,请原谅我。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.