【问题标题】:Is it possible to do real time network games in Actionscript 3.0Actionscript 3.0可以做实时网络游戏吗
【发布时间】:2011-04-14 08:05:17
【问题描述】:

问题:是否可以通过套接字连接更新 Flash Player 中的 100 多个对象?更多细节和我自己的尝试如下!

详情

在实习期间,我有时间创建一个多人物理游戏。我稳定地工作了三个月。我的实习即将结束,我无法完成我的游戏。

我的问题是每个时间步都很难将多个数据包发送到服务器并返回。我发送的数据包是其他客户端的对象和鼠标的位置更新。

我将尝试解释网络/游戏流程。

  1. 客户端使用 AS3 中的二进制 Socket 类连接到服务器
  2. 服务器要求验证,客户端发送名称和缩略图。
  3. 服务器等待 4 个客户端连接(一些匹配等)
  4. 服务器选择 4 个客户端并让它们在单独的线程上运行(合并为一个团队)
  5. 客户端将他的性能分数发送到服务器范围 1-100。
  6. 服务器将最佳客户端作为物理主机和其他 3 个从机的主机
  7. 主机游戏设置关卡并在关卡中制作大约 1-100 个形状(主要形状和复杂形状,如桥梁、马达、弹簧)
  8. 每个时间步,主机都会获取形状的所有更新属性并将它们发送给客户端(x、y、旋转、睡眠)
  9. 客户端将所有形状属性应用于正确的形状

我尝试了不同的时间步长,并注意到在 1/15 秒的时间步长之前,客户端(从机)不会注意到游戏中有任何滞后。我还尝试选择较低的时间步长并对形状的移动进行补间,但这确实在客户端(从属)端产生了一些奇怪的移动。

我将举一个单个对象更新包的例子。

<O|t=s:u|x=201|y=202|f=automaticoo</O
<O|t=m:p|x=100|y=345|f=automaticoo</O

我注意到 Flash Player 可以在发送之前在缓冲区中堆叠大量数据包。例如,如果我一次发送大量数据包,它会将它们堆叠起来并将它们一起发送到服务器。使用更快的时间步长,您不会在客户端(从)端获得更多更新,而是在同一数据包行中获得更多更新。

尝试

  1. 使用新的 RTMFP(udp & p2p) 协议进行更新。 (性能稍好,但可靠性较差)
  2. 用 c++ 而不是 Air(使用 ServerSocket)对我的整个套接字服务器进行编码(性能更好,但注意到滞后的部分不是服务器,而是 Flash Player)
  3. 使用ByteArray压缩方式和AMF序列化格式(性能差不多,只是c++服务器不能反序列化消息)

你们认为在 Flash Player 中是否有可能在每个时间步处理如此多的更新请求。

发现

ActionScript 3.0 中有一个多人模式的棍子竞技场游戏。他们使用了很多技巧,即便如此,我还是得到了大约 300 毫秒的 ping,它只会不断更新玩家(一个大厅里有 4 个玩家)。

抱歉,帖子太长了。

【问题讨论】:

  • 主机是否通过服务器向其他客户端发送数据?与服务器计算物理时相比,客户端将获得双倍的往返时间。
  • 从 1client->server->3client 到 server->4clients 的唯一区别是有一个客户端发送数据包而不是接收数据包。我曾经决定在客户端计算物理,因为当有很多游戏正在进行时,它会大量卸载服务器。也许你是对的,我能不能更好地在服务器端用 C++ 做物理。
  • 我想知道客户端是否可以直接将数据发送给其他人(并通过广播)。 AIR 已经有一些 p2p 功能,不确定浏览器内的 Flash。
  • 您可以从 Adob​​e 自己查看 Stratus 页面。它是一个 p2p udp 协议。它仍然是 Flash Player 10.1 中的一个测试版,它首次向公众发布。

标签: c++ actionscript-3 sockets flash


【解决方案1】:

我相信您的问题归结为游戏类型和数据。

这又被分解成:

  • 服务器速度(需要计算世界/玩家数据的 CPU + RAM 要求)
  • 连接速度(服务器带宽)
  • 数据大小(需要多少信息以及频率)
  • 玩家交互表单(事件或 FPS)
  • 客户端到服务器的距离(ping)

MMORG

例如。魔兽世界,据我所知,在非 PVP 世界中使用“客户端是一个视口”和“客户端发送击键”,“服务器验证并执行,并告诉客户端发生了什么”在 CLIENT-SERVER 基础上。

这为游戏提供了很多可接受的延迟,因为您只需将命令从客户端传输,然后将结果传输到客户端。其余部分绘制在客户端上。

它是由事件驱动的,从你点击一个图标或按下一个键,你的“咒语”需要一些时间才能在服务器上触发。其次,不需要玩家碰撞。这让服务器也可以处理更少的数据,并降低对服务器 CPU 的要求。


反恐精英/战场等

FPS,快节奏的动作,快速的反应,需要时刻获取关于每一个细节的信息。这就对精度提出了更高的要求。碰撞对玩家和武器来说都是必须的。

这类游戏通常不会在一张地图上处理超过 32 名玩家,因为他们都需要能够非常快速地分享他们的位置、子弹、爆炸等,所有这些数据都必须经过服务器验证这又是任何类型的在线游戏的瓶颈。


网络延迟

在一个完美的世界中,这将是 0 毫秒,但我们都知道。从客户端到服务器再返回的所有硬件都需要时间。通过网络堆栈和互联网连接(交换机、路由器、调制解调器、光纤中心等),因此许多现代实时游戏解决此问题的方式是通过“预测”。让服务器看看你的方向和速度。然后他们尝试预测(很像 GPS 在隧道中所做的那样)您最后一次被看到以 +4 的速度向前移动,因此在给定时间范围内您已经移动(时间范围 x 4) - 但是如果您减速或加速怎么办向上?然后他们要么立即将您从 A 跳到 B,这让您感觉像是一场滞后的游戏,要么他们轻松到达真实位置,因此您的“英雄”会更快或更慢地滑入正确的位置。

这种技术在网上很多地方都有解释,所以这里不需要详细说明,但是需要时间和调整才能从中获得良好的性能 - 但它很有效,并且为程序员省去了很多麻烦。


需要哪些网络数据?

我阅读了您的问题并认为:这可能会被压缩很多。其次,我使用纯 ByteStream 进行了 Flash 套接字聊天,效果非常好。一开始很难跑,但是一旦我开始运行它就很快。

Flash 客户端/播放器本身并不是最大的网络客户端,因此预计也会有很多速度损失。我会为网络部分选择 10-15 fps,然后对来回发送的数据使用更原始的方法。

最后,尽量让数据保持简单。

例如。对某些数据/事件使用命令/快捷方式。 就像服务器数据字节串可以是:0x99,0x45,0x75,0x14,0x04,0x06

其中 0x99 表示:在以下坐标处发生大爆炸:(0x45,0x75) 那么 0x14 表示:PLAYER 0x14(十进制的玩家 20)已经移动到 (0x04, 0x06)

因此,启动操作码会告诉客户端和服务器中的网络协议处理程序接下来会发生什么。 (顺便说一句,CPU 知道如何读取内存。)

在我的聊天中,我为每种类型的数据解析了命令。一个用于登录,一个用于广播,用于告诉用户名等。因此,一旦客户端登录,客户端就会收到一个命令+一群在线用户。这仅传输给客户一次。之后,每个附加的客户端也收到一个带有新用户名称的“新用户在线”命令。每个客户都维护自己的当前用户和 ID 列表,因此我只需要告诉哪个客户编号说文本。这使流量保持在最低限度。坐标或操作命令也是如此。 “玩家 #20 向北”等可能是 0x14、0x41、0xf0(0x41 可能是 MOVE,0xf0 可能是 NORTH、0xf1 EAST 等)


到游戏的物理距离

这个您无法更改,但您可以设置一些限制或让服务器在全球多个位置运行,具体取决于您想要制作的游戏类型。 Amazon EC2 是此类项目的绝佳平台,因为它们在世界各地都有数据中心,然后您可以根据这些数据中心对用户网络进行基准测试,然后将用户重定向到您正在运行服务器的最近的数据中心。


黑客/作弊

另外请记住,如果某件事变得流行并且您开始从中赚钱,迟早有人会尝试破坏协议或破坏帐户以访问服务器、信息或作弊以获取更多的项目/积分游戏。你也可能受到 DDOS 的攻击,他们用错误的数据轰炸你的网络,只是为了让一切崩溃并使游戏无法使用。

一开始不要太介意,只要记住,一旦你上网,你就永远不知道世界上谁或他们在世界上的什么地方。我不是想让你偏执,但有些病人会试图通过欺骗别人来赚钱。

所以在你的结构中考虑这一点,不要在不需要的网络包中显示数据。不要相信来自客户的数据总是正确的。在服务器端验证数据。

如果您同时有 100 名活跃玩家,这也需要时间。

但是一旦你这样做了,如果它对你来说是一个巨大的成功,你可以睡得更好,我真的希望。


这是我根据经验得出的想法。希望其中一些可能有用,尽管我没有完全回答是否有 100 名玩家。

事实上我想说:是的,100 名玩家是可能的,但这取决于他们是否都同时移动,是否涉及碰撞测试,以及您是否接受延迟。

【讨论】:

  • +1 对于这个非常详尽的答案,阅读详细答案总是一种乐趣。 :)
  • 不客气,谢谢你,但作为一个“老游戏开发者”,这东西很贴近我的心。 :o)
  • 我是一个有抱负的人,尤其是操作码的东西很高兴知道以备后用。 :)
  • 哦,我忘了,还有一件事是为了避免滞后。如果可能,让“位置”位于明确定义的网格中。因此,如果您制作 C&C/星际争霸类游戏,单位必须在“瓷砖/网格”中移动,但您只需要告诉“目标瓷砖坐标”,客户端可以轻松计算出坦克从帧到帧的位置,无需发送每个像素更改。只有目标命令!把它想象成一门大炮的弹道射击。您只需要知道子弹的威力、角度和重量。然后,您可以准确计算出影响将在哪里。这段代码在客户端是可以的。所以FIRE+P+A+W
  • +1 并接受答案。感谢您的详细信息。这是我希望得到的答案。感谢您描述当前游戏用于帮助存档多人游戏中的良好性能的解决方案。
【解决方案2】:

问题:是否可以通过套接字连接更新 Flash Player 中的 100 多个对象?

Phosphor 2 seems to pull it off.

【讨论】:

  • 那好像用的是Shockwave Player插件而不是Flash Player插件。
  • 我总是对 Shockwave Player 的管理能力印象深刻。太糟糕了,Flash Player 中的 3D 与此相比仍然微不足道(希望随着 MoleHill 的变化而变化)。但是,Phosphor 仍然只更新玩家坐标而不是洞图。它发送一次地图,客户端需要渲染所有内容。我已经阅读了很多关于如何在多人游戏中管理玩家动作的 Valve 网络文档(这都是关于欺骗玩家)。我没有找到任何文档如何管理 Flash Player 中每个时间步包含大量 tcp 数据包的实时连接。
  • 如果您愿意将平台切换到例如。 Shockwave 播放器,然后看看 Unity3D。它制作真正的 3D 游戏,很像 Flash,但它是纯 3D 引擎。
【解决方案3】:

也许最好的选择是在服务器和每个客户端上进行物理同步(服务器对象位置覆盖客户端)。这样,所有客户端都会获得相同的延迟。在差异很小(应该如此)之前,更正将不会被注意到。如果您使用 Box2D,则您已准备好 AS3 和 C++ 版本。但这是完全不同的架构,需要 3 个月的时间自行实现。你在空旷/简单的舞台上会遇到什么滞后?在有限的时间内,简化可能是您唯一的选择。

【讨论】:

  • 在非常快的互联网连接上,我的 ping 延迟大约为 100 毫秒。很不错的建议。在每个客户端上模拟物理并尝试每 2 秒与服务器同步一次。你知道在 AS3 和 c++ 中浮点数和数字精度差异是否没有任何问题。值得一看。
猜你喜欢
  • 1970-01-01
  • 2017-06-11
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
相关资源
最近更新 更多