我有一个关于在网络游戏上编程客户端/服务器通信的一般问题。 我使用TCP作为协议,通信......工作,但我不确定,如果它是一种有效的方式。
通常,客户端发生的操作将完成以下所有步骤:
是否真的有必要完成所有这些步骤?在标有[*]的所有步骤中,我需要为每个命令定义新的lineinterpreters / action,因此我将每个动作编码两次,client&服务器端。 我读了一些关于发送可序列化对象的内容,但是在genreal中这个想法对我来说似乎是一样的,我发送了一个对象,必须对其进行解释+处理,然后我发回一个对象......
任何提示?解决整个沟通更优雅,编码更少?或者更加有序 - 所有这些#F ## M##H#标签用于不同的操作使它变得越来越复杂:)
(实际上我实际上有以下处理程序/操作:
-move -Look /旋转 -hpchange -firearrow -spawn /断开 ...)
希望你理解我的意思 - 我知道,我可以继续这样编码,它会以某种方式工作,但它看起来似乎太复杂了。
谢谢!
答案 0 :(得分:1)
如果您:
,您可以采用更多OO方式
- 定义一个名为Action的对象或类似的对象,它具有以上所有参数 - 动作类型,动作方向(或 目标),造成的伤害等。
- 在游戏正常执行时创建这些Action对象
- 使用链接到TPC套接字的ObjectOutputStream将整个Action对象输出到服务器/将其传递回客户端。
- 在服务器上,通过检查ObjectInputStream中的接收对象来解释发生的情况。
醇>
我认为这种方式更简洁,更灵活,只需添加更多逻辑,而不仅仅是分析字符串,但速度不快(因为进入ObjectOutputStream的对象需要序列化)。
答案 1 :(得分:0)
在决定游戏是否需要进行任何更改之前,您需要先考虑几个因素。
首先,TCP是最好的沟通渠道吗?你有没有把它与UDP进行比较。使用UDP实现网络会更好吗?如果丢失一些数据包会不会有问题?如果网络很慢会发生什么?
其次,查看您轮询/推送到服务器的频率。这可以减少吗?游戏必须是实时的。游戏的所有部分都必须是实时的。也许某些事情可能是非实时的。一个火球将继续在一条直线路径上,所以你不必不断更新服务器的位置,你可以告诉它它的方向和速度。游戏的其他方面可能是非实时的。唯一需要发送的是球员位置和动作。碰撞检测等大多数其他内容可以卸载到客户端。
第三,是否需要将每个按键发送到服务器?如果用户靠墙并想要进一步移动,则客户端知道他们不能,因此不会将这些按键发送到服务器。如果用户已移至新的有效位置,则更新服务器。是否可以缓存某些内容并一次性发送到服务器,而不是向服务器发送多个查询。即如果我向前移动,跳跃并投掷一个火球,那就是客户端的3个按键,它们可以在接下来的500毫秒进行缓冲和发送吗?
如果您担心网络开销,那么您应该在位级工作。而不是发送长字符串“#F#270#130#” - 这是11个字节长,发送3个连续字节(24位)是否有意义。
7位表示动作(127种不同的动作)。 9位代表角度(1-512),但你只需要它可以达到0-360度。 8位代表力。
这种或任何其他字节格式更短,更容易在网络上使用,并产生更严格的代码。二进制比较也更快,因此现在可以更轻松地在服务器上编写动作解析器。即而不是寻找#F#的大型开关盒,只需查看前7位并将其与int进行比较。
您是否可以减少其他网络开销,而不是由客户端决定强制,服务器可以决定这一点。即标准力,或2级力(更好,因为这可以用1位表示)。这会阻止客户端和恶意用户将垃圾数据发送到服务器(如999的强制),现在力可以是0或1,即10或20的速度,没有什么愚蠢的。