我目前正在为Android开发一款多人游戏卡片游戏,其中libgdx是游戏引擎。我的问题更多是基因。
我不确定这个架构中处理回调的最佳做法是什么。我的控制器是一个大型的状态机,它在游戏引擎的render()方法调用时反复检查输入。
我有两个主要的回调,来自gui的userinput和来自android google play服务部分的网络回调。
目前这些回调的methode / inputListeners只是设置成员变量,它们通过控制器/ statemachine的getter方法进行检查,例如我一遍又一遍地从控制器调用它,检查它是否为!= null并且如果是,则继续。
@Override
public Boolean allPlayersConnected() {
Boolean allConnected = null;
if (startGame != null) {
allConnected = startGame;
startGame = null;
}
return allConnected;
}
startGame" flag"来自谷歌游戏服务API的回调设置。
我不知道这是不是很好的做法,看起来不像。
我可以从设置控制器成员变量的google play services回调中调用控制器方法,并在每个渲染循环中检查这个,但那只是移动变量。
我还可以将控制器设计为这些事件的观察者,但是如果事件发生,我将在控制器内部的更新方法中做什么。我不认为我想在这些中改变统计数据,即使我可以访问这个状态。我用这个传播状态代码,一些在巨大的更新方法的不同部分,一些在实际的状态机代码中。在update方法中设置成员变量与我上面的想法非常相似。
另一件事是,直接从回调方法改变控制器状态。这将是更少的代码,更少的变量和更快的,但我认为我破坏了MVP概念,因为我从控制器拿走控制,让gui改变控制器的状态。
对此有任何意见吗?
编辑:
我想的越多,我认为观察者和指挥模式的结合就越多。
所以我确实可以删除当前状态机的大部分并将其打包到observer update()方法中。不是通过大命令枚举发送命令,我可以使用可用信息创建命令对象,并将它们传递给观察者(控制器),在那里我检查命令是否可行,并使用需要的信息调用执行,例如模型界面。
答案 0 :(得分:2)
首先,我认为您的命令是枚举还是命令对象与此处的主要问题无关 - 这是如何将用户和网络输入连接到状态管理。
我见过的最常见的游戏架构是一个更新循环,用于检查输入,迭代游戏模拟,然后渲染帧。在MVC世界中,这种结构只是同步这些步骤;你仍然有一个封装的视图和数据模型,控制器(游戏循环)充当这两个世界之间的桥梁。
输入,无论是来自本地用户还是来自网络的用户,通常被视为修改游戏状态的请求。也就是说,控制器(作为其循环的第一部分)读入待处理的输入消息并处理它们,随着状态的变化修改状态。这样,改变状态的代码就在一个地方:那个控制器。你是对的,在整个应用程序中传播状态修改代码是一种不好的做法;基本上,它不是MVC。
换句话说,所有回调都应该将输入转换为命令并将它们粘贴到队列中。您不希望将控制器(其修改状态的作业)与这些输入回调同步。您不知道何时会相对于游戏循环进行输入,因此最好将它们分离。使用游戏模拟序列化输入处理也应该使您的逻辑更简单。
您可以选择如何将回调连接到控制器;共享队列(一方写入其中,另一方从中读出)是一种强大的模式,易于使线程安全。