游戏编程通过......进行客户端/服务器通信? (JAVA)

时间:2013-08-07 14:14:35

标签: java tcp client communication serializable

我有一个关于在网络游戏上编程客户端/服务器通信的一般问题。 我使用TCP作为协议,通信......工作,但我不确定,如果它是一种有效的方式。

通常,客户端发生的操作将完成以下所有步骤:

  1. 某些动作(例如,投射火球)
  2. [*]对于这个动作,我定义了一个字符串(例如#F#270#130#,这意味着'F'表示它是火球,270表示(例如)角度,130 - 射击的火球的速度。)
  3. String进入Client&的outputpuffer。 waitingqueue
  4. 发送字符串
  5. 服务器
  6. 收到字符串
  7. [*]服务器需要一个可以检测字符串含义的lineinterpreter(这里:F是什么意思?它是火球!)&根据收到命令的客户端添加唯一标识。
  8. [*]服务器需要根据发生的动作计算逻辑(火球会对某人造成伤害,是否会立即击中某人或者是先飞行?)
  9. 服务器向所有客户端发送(更新的)操作字符串。 (例如,火球可能由于某种原因速度减慢 - 这将是一个更新的字符串(#F#12345#270#90# - 12345是唯一的玩家身份)
  10. 客户收到字符串
  11. [*]客户端将字符串解析为命令+处理它(触发animationsequence ...)
  12. 最初发送命令的客户端将接收到的字符串与waitqueue中的字符串进行比较 - 当相等时,不执行任何操作(平滑某些操作,否则通过连接问题/延迟,某些操作会发生两次或从一个位置跳到另一个位置,基于平
  13. 是否真的有必要完成所有这些步骤?在标有[*]的所有步骤中,我需要为每个命令定义新的lineinterpreters / action,因此我将每个动作编码两次,client&服务器端。 我读了一些关于发送可序列化对象的内容,但是在genreal中这个想法对我来说似乎是一样的,我发送了一个对象,必须对其进行解释+处理,然后我发回一个对象......

    任何提示?解决整个沟通更优雅,编码更少?或者更加有序 - 所有这些#F ## M##H#标签用于不同的操作使它变得越来越复杂:)

    (实际上我实际上有以下处理程序/操作:

    -move -Look /旋转 -hpchange -firearrow -spawn /断开 ...)

    希望你理解我的意思 - 我知道,我可以继续这样编码,它会以某种方式工作,但它看起来似乎太复杂了。

    谢谢!

2 个答案:

答案 0 :(得分:1)

如果您:

,您可以采用更多OO方式
  
      
  1. 定义一个名为Action的对象或类似的对象,它具有以上所有参数 - 动作类型,动作方向(或   目标),造成的伤害等。
  2.   
  3. 在游戏正常执行时创建这些Action对象
  4.   
  5. 使用链接到TPC套接字的ObjectOutputStream将整个Action对象输出到服务器/将其传递回客户端。
  6.   
  7. 在服务器上,通过检查ObjectInputStream中的接收对象来解释发生的情况。
  8.   

我认为这种方式更简洁,更灵活,只需添加更多逻辑,而不仅仅是分析字符串,但速度不快(因为进入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的速度,没有什么愚蠢的。