2009-11-27 58 views
1

我正在寻找基于C++风险的联网棋盘游戏。我的想法是拥有一个中央服务器,该中央服务器托管着游戏大厅,供用户连接和制作/加入游戏。观察者模式在这种情况下似乎很有吸引力,因为我可以在服务器上托管所有的游戏模型/逻辑,客户端只是观察者,并使用视图显示当前的游戏状态。在网络上使用观察者模式进行棋盘游戏

我的第一个问题:这种方法可行吗?我所听到/想到的大多数是客户有他们自己的游戏模型。不过,我正在考虑一个不是计算密集型的游戏,服务器托管的单一模型会有优势(不会出现不同步问题,防止作弊等)。

我的第二个问题:我该如何去实现网络上的Observer模式?由于我无法通过网络进行直接的方法调用,因此我需要一些简单的方法来使用数据来模拟此操作。使用“拉”(观察者请求更新游戏数据)还是“推”(服务器将新的更新数据推送给所有客户端)方法会有更多优势吗?

+0

什么是您的连接限制?我所知道的大多数游戏都使用TCP/IP连接来保持与服务器的连接并获得有关事件的实时通知 – FrenchData 2009-11-28 23:00:27

+0

Observer是关键设计模式之一。它也广泛用于网络游戏体系结构。 – kyoryu 2010-07-28 05:04:13

回答

3

从您的问题陈述中,您似乎需要实现分布式观察者模式或分布式发布/订阅。 PubSub是一个消息传递范例,可以通过MOM(面向消息的中间件)轻松实现 - (请参阅RabbitMQ,ActiveMQ,OpenMQ),其中MOM负担繁重。

XMPP也可以为您的目的服务(请参阅XEP-0060)。所有你需要的是一个Jabber服务器和一个C++ XMPP库(gloox是一个好的并且支持XEP-0600)。您可能也有兴趣pubsubhubbub

+0

很好的答案!我会推荐XMPP作为传输协议。使用任何XMPP客户端(如Pidgin)手动调试很容易。请注意,您仍然需要做以下工作:(1)序列化 - 从/到字符串表示形式编组/解组对象;(2)路由 - 将接收到的消息对象连接/路由到适当的观察者/监听器对象/方法;(3)绑定/映射 - 将消息中的对象映射回方法参数(或者为了简单起见,单个对象参数)。 – 2010-12-30 18:29:10

+0

有用的概念参考:http://www.eaipatterns.com/PublishSubscribeChannel.html,http://www.eaipatterns.com/ObserverJmsExample.html – 2010-12-30 18:32:27

+0

检查我在这里做了什么:http:// spring-java-ee。 blogspot.com/2010/01/advanced-event-notification-framework.html。我在那里使用了Apache Camel,是的,它使用Java。我还会质疑“C++”部分,如果它不是严格的要求,那么使用Java或其他更好的JVM语言(Scala,Groovy)会更有效率。 – 2010-12-30 20:58:43

0

看来你正在使用Observer模式来实现双重目的。你是游戏客户将会“观察”服务器,但这不是全部。他们也会将播放器信息传回服务器。所以他们真的做的不仅仅是观察。也许只是使用基本的客户端/服务器范例,不用担心“设计模式”。或者,如果您想要设计图案化方法,可以查看服务器是介体的介体模式。就个人而言,我会坚持客户端/服务器方法。

对不起,我知道这并不回答你的具体问题,但只是把它作为思考的食物。

+0

这不是任何GUI的情况吗? GUI获取用户输入并将其发送到模型,但GUI也充当使用Observer模式的模型的视图。 – MahlerFive 2009-11-27 17:46:24

+0

确实,有些GUI使用观察者模式更新显示状态,并使用其他方法更新用户信息。有些实际使用中介模式将UI与基础逻辑分开。 – nathan 2009-11-27 17:53:20

2

如果你真的想这样做,让你的具体观察者也实现代理模式。代理处理发送/接收数据,主要是将本地方法调用转换为远程方法调用。

由于您正在处理异步数据,因此您可能需要查找名为“发布/订阅”的观察者变体。这些观察是由具体的观察者听取事件,然后在需要交流时提出事件。例如,接收数据可能会引发一个事件。

你也可以看看远程处理,这就是你在这里要做的事情。尽管对于你想要做的事情来说它可能有点太重。

0

对于你的第一个问题:是的,它是每个客户端服务器游戏使用的模型。

对于第二个问题:在定时同步和bandwitch方面,“推”方法更好。使用RPC库(远程过程调用)模拟函数调用。如果你使用C++,我推荐Raknet。如果您使用的是Java,我推荐使用Jnag或原始缓冲区。