![]() |
1
3
这听起来似乎可以从客户机/服务器方法中获益: 玩家是一个客户端-交互和渲染发生在这一端。所以播放器按下一个按钮,请求就转到服务器。服务器的回复返回,玩家的状态被更新。在这些事情发生的任何时候,屏幕都可以重新绘制,它反映出客户当前所知道的游戏状态。 人工智能也是一个客户机——它相当于一个机器人。 模拟是服务器。它在不同的时间从客户机获取更新并更新世界状态,然后根据需要将这些更新发送给每个人。这就是它与您的情况的联系:模拟/AI需要一个静态的世界,并且许多事情同时发生。服务器可以简单地将更改请求排队并应用它们,然后再将更新发送回客户端。就服务器而言,游戏世界并不是实时变化的,只要服务器决定了它的存在,游戏世界就会发生变化。 最后,在客户端,您可以通过执行一些快速的近似计算并显示结果(从而满足即时需求),然后在服务器与您交谈时显示更正确的结果,来防止按下按钮和查看结果之间的延迟。 请注意,这实际上不需要以TCP/IP的方式在Internet上实现,只是它有助于从这些方面考虑它。 或者,您可以将在模拟过程中保持数据一致性的责任放在数据库上,因为它们已经在构建时考虑到了锁定和一致性。类似于sqlite的东西可以作为非网络解决方案的一部分工作。 |
![]() |
2
0
我不确定是否完全理解您要查找的行为,但听起来您需要类似于状态更改线程/队列的东西,因此所有状态更改都由单个线程处理。 为状态更改队列创建一个API,可能类似于swingutilities.invokelater()和/或swingutilities.invokeAndWait(),以处理状态更改请求。 我认为这在GUI中的反映方式取决于您正在寻找的行为。也就是说,由于当前状态为$0,所以无法提取资金,或者在处理提取请求时,向用户弹出帐户为空的消息。(可能不是用这个术语;-) |
![]() |
3
0
最简单的方法是使模拟足够快以在EDT中运行。喜欢有效果的节目! 对于双线程模型,我建议将域模型与渲染模型同步。呈现模型应该保留来自域模型的数据。 更新:在模拟线程中锁定渲染模型。遍历渲染模型更新,其中内容与预期不同,请更新渲染模型。完成遍历后,解锁渲染模型并计划重新绘制。注意,在这种方法中,您不需要大量的听众。 渲染模型可以有不同的深度。在一个极端,它可能是一个图像,而更新操作只是用新的图像对象替换一个引用(例如,这不会很好地处理大小调整或其他表面交互)。您可能不需要检查项目是否有更改,只需要更新所有内容。 |
![]() |
4
0
如果更改游戏状态很快(一旦知道要将其更改为什么),则可以将游戏状态视为其他摆动模型,并且只更改或查看EDT中的状态。如果改变游戏状态不是很快,那么您可以同步状态改变并在Swing Worker/Timer(而不是EDT)中进行,也可以在单独的线程中进行,该线程与EDT处理类似(此时您将使用
|
![]() |
5
0
是否可以增量更新游戏状态,并且仍然有一个一致的模型?例如,在渲染/用户更新之间重新计算行星/玩家/舰队对象的子集。 如果是这样,您可以在EDT中运行增量更新,在允许EDT处理用户输入和呈现之前,只计算状态的一小部分。 在EDT中进行每次增量更新之后,您需要记住还有多少模型需要更新,并在执行任何挂起的用户输入和呈现之后,在EDT上安排一个新的swingworker来继续此处理。 这样可以避免复制或锁定游戏模型,同时保持用户交互的响应性。 |
![]() |
6
0
我认为你不应该让世界存储任何数据或对任何对象本身进行更改,它应该只用于维护对对象的引用,当需要更改该对象时,让玩家直接进行更改。在这种情况下,你唯一需要做的就是同步游戏世界中的每个对象,这样当一个玩家做出改变时,其他玩家就不能这样做了。下面是我想的一个例子: 玩家A需要了解一个星球,所以它向世界请求那个星球(如何依赖于你的实施)。world返回一个对a请求的行星对象播放器的引用。玩家A决定做一个改变,所以它是这样做的。假设它增加了一个建筑物。将建筑物添加到行星的方法是同步的,因此一次只能有一个玩家这样做。这座建筑将跟踪自己的建造时间(如果有的话),所以地球的“添加建造方法”几乎可以立即释放。这样,多个玩家可以同时在同一个星球上请求信息,而不会相互影响,玩家几乎可以同时添加建筑,而不会出现太多延迟。如果两个玩家正在寻找一个放置建筑的地方(如果这是你游戏的一部分),那么检查一个位置的适合性将是一个查询而不是一个变更。 很抱歉,如果这不能回答你的问题,我不确定我是否理解正确。 |
![]() |
7
0
如何实现管道和过滤器体系结构?如果过滤器不够快,管道会将过滤器连接在一起并对请求进行排队。处理发生在过滤器内部。第一个过滤器是人工智能引擎,而渲染引擎由一组后续过滤器实现。 在每一个计时器刻度上,新的动态世界状态是基于所有输入(时间也是一个输入)和 复制 插入到第一个管道中。 在最简单的情况下,渲染引擎是作为一个过滤器实现的。它只是从输入管道获取状态快照,并将其与静态状态一起呈现。在实况游戏中,如果管道中有多个状态,渲染引擎可能希望跳过这些状态,而如果正在进行基准测试或输出视频,则希望渲染每个状态。 将渲染引擎分解为的过滤器越多,并行性越好。也许甚至可以分解人工智能引擎,例如,您可能希望将动态状态分为快速变化和缓慢变化状态。 这种体系结构在没有大量同步的情况下提供了良好的并行性。 这种体系结构的一个问题是,垃圾收集将经常运行,每次都冻结所有线程,这可能会扼杀多线程带来的任何优势。 |
![]() |
8
0
看起来您需要一个PriorityQueue来放置对模型的更新,在这个队列中,用户对来自模拟和其他输入的更新具有优先权。我听到你说的是,当其他输入(模拟,否则)可能需要比一个模拟步骤更长的工作人员时,用户总是需要立即对其操作进行反馈。 然后在PriorityQueue上同步。 |