- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Opengl 和 Jbox2d 用 Java 编写实时 2d 游戏。
我想开始编写网络组件。
虽然它使用 box2d,但我的游戏非常小,我想使用 Kryonet 库创建一个基本架构。
程序本身是一个像国际象棋一样的“比赛游戏”。我能想到的最合乎逻辑的系统是拥有存储所有玩家数据的专用服务器。
PlayerA 和 PlayerB 将连接到专用服务器,这将促进他们计算机之间的 TCP 链接。
比赛结束后,双方玩家会将结果数据传回专用服务器,服务器将进行身份验证,然后保存各自的玩家数据。
对于那些熟悉的人来说,暗黑破坏神 2 实现了类似的设置。
我希望此 TCP 连接仅将形状坐标 vector 数据从主机(比如玩家 A)发送到客户端(玩家 B),然后客户端将自行呈现。
然后我希望客户端将鼠标/键盘数据发送回主机。所有处理都将在主机的计算机上运行。
我的第一个问题:这个网络逻辑有什么缺陷吗?
我的第二个问题:如何使用 Kryonet 实现准系统服务器/客户端数据包传输(如所述)?
注意:我已经使用不同的库在 C++ 中完成了这种类型的数据包传输。我为 Kryonet 找到的文档/教程很糟糕。建议另一个具有良好支持的库是可以接受的答案。
最佳答案
我知道这是一个老问题,我确信 OP 已经以某种方式得到了他们的答案,但为了好玩,我想我还是会回答。自从我最近一直在使用 Kryonet 进行游戏开发以来,我一直在想这个问题。
一些早期的网络游戏,比如Bungie's Marathon (1994)看起来他们确实是这样做的:每个玩家的事件都将使用 UDP 发送给其他玩家。因此,如果玩家移动或射击,玩家的移动或射击的方向、速度等将被发送给其他玩家。这种方法存在一些问题。如果玩家的某个 Action 在网络上暂时丢失,则玩家或玩家似乎与其他人不同步。在这种情况下,游戏状态没有“真相”或“和解”。
另一种方法是让玩家在客户端计算他们的移动和 Action ,并将更新后的位置发送到专用服务器。通过服务器接收所有玩家状态更新,就有机会协调它们。如果某些数据在网络上丢失,它们也不会永久不同步。
与前面的例子相比,这相当于每个玩家将他们的位置发送到服务器,然后让服务器将每个玩家的位置发送给所有其他玩家。如果这些更新之一由于某种原因丢失,后续更新将对其进行更正。但是,如果仅发送按键,则丢失一次按键会使游戏不同步,因为所有客户端都在分别计算其他客户端的位置。
对于 Action 游戏,您可以使用混合方法来最大程度地减少明显的延迟。我一直以这种方式成功地将 Kryonet 用于 Action 游戏。每个玩家在每次渲染时都会将他们的状态发送到服务器(尽管这可能是过度的并且应该被优化)。状态包括位置、剩余投篮次数、生命值等。玩家还发送他们的投篮(起始速度和位置)。
服务器只是将这些内容回显给客户端。每当客户端收到射门时,都会在客户端进行计算,包括射门是否击中 catch 球员。由于接收玩家只计算他们自己的状态,所以从他们自己的角度来看,一切似乎都保持同步。当他们被击中时,他们会感觉到被击中。当他们击中另一名球员时,他们认为自己击中了另一名球员。由玩家“接收”一次射击来更新他们的健康状况并将该信息发送回服务器。
这确实意味着投篮在理论上可能会滞后或“丢失”,并且玩家可能认为他们的投篮击中了另一名玩家,而在另一名玩家的屏幕上却没有击中。但在实践中,我发现这种方法很有效。
这是一个例子(伪代码,不要指望它能编译):
class Client {
final Array<Shot> shots;
final HashMap<String, PlayerState> players; // map of player name to state
final String playerName;
void render() {
// handle player input
// compute shot movement
// for shot in shot, shot.position = shot.position + shot.velociy * delta_t
// if one of these shots hits another player, make it appear as though they've been hit, but wait for an update in their state before we know what really happened
// if an update from another player says they died, then render their death
// if one of these shots overlaps _me_, and only if it overlaps me, deduct health from my state (other players are doing their own hit detection)
// only send _my own_ game state to server
server.sendTCP(players.get(playerName));
}
void listener(Object receivedObject) {
if(o instanceOf PlayerState) {
// update everyone else's state for me
// but ignore my own state update (since I computed it.)
PlayerState p = (PlayerState)o;
if(!p.name.equals(playerName) {
players.add(p.name, p);
}
} else if (o instanceof Shot) {
// update everyone else's shots for me
// but ignore my own shot updates (since I computed them.)
Shot s = (Shot)o;
if(!s.firedBy.equals(playerName) {
shots.add(s);
}
}
}
}
class Server {
final HashMap<String, PlayerState> players; // map of player name to
void listener(Object receivedObject) {
// compute whether anybody won based on most recent player state
// send any updates to all players
for(Connection otherPlayerCon : server.getConnections()) {
otherPlayerCon.sendTCP(o);
}
}
}
我确信这种方法也存在缺陷,并且可以通过多种方式对其进行改进。 (例如,它很容易让“被黑”的客户端占据主导地位,因为他们总是可以发送不考虑任何损坏等的更新。但我认为这个问题超出了问题的范围。)
关于Java 游戏网络与 Kryonet : Bare-bones packet transfering,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32020436/
? 关联的消息组件
Packet packet = new Packet(); while(packet != null ) { packet = jpcap.get
我有一个 python 脚本,它使用 dpkt 捕获以太网上的数据包,但我如何区分哪些数据包是 tcp,哪些是 udp。 最终,我希望获得在时间间隔内建立的每个 tcp 连接的数据包列表。 我的代码是
当我尝试将电缆与网络摄像头连接时,系统提示电缆无法连接到该端口。有人能帮我拿一下这个吗?
我正在尝试为 IPv6 建立 TCP 握手。 SYN 数据包被发送。接口(interface)收到SYN/ACK。 我对收到的数据包进行了十六进制转储,还对 pkt.show() 进行了处理。我得到以
我正在尝试使用套接字发送数据包,但出现错误。 invalid conversion from ‘omnetpp::cPacket*’ to ‘inet::Packet*’ [-fpermissive]
我在我的 Android 应用程序中使用 aSmack 与我的 XMPP 服务器通信,我打开了 Smack 的调试,这样我就可以看到所有 XML 的来来去去。我的问题是我正在使用 PacketList
自从升级到 Xcode 4.2 以来,我经常遇到错误,尝试调试应用程序失败,并显示消息“未知数据包回复:环境数据包“超时”。”重新启动设备并不能始终解决问题(尽管有时可以解决),重新启动 Xcode
我得到了一个派生自 sf::Packet 的类,它在其构造函数中传递了一个引用 iots 类型的 Integer。现在在构造函数中,我尝试将 Integer 添加到 sf::Packet 的数据中,如
我正在使用 Debian 操作系统。我正在编写网络仿真程序,我想获取所有数据包并停止 Debian从响应任何发送的数据包。 到目前为止,我已经打开了一个套接字,并且收到了所有数据包,但 Debian
对于一个应用程序,我需要能够创建一个多用户聊天室并加入其中。聊天服务器是一个 openfire 服务器。 我曾经有过: MultiUserChat chat = new MultiUserChat(c
我正在研究 中的核心音频转换服务 Learning Core Audio 我对他们 sample code 中的这个例子感到震惊: while(1) { // wrap the destina
我在my.cnf中添加了如下内容 [mysqld] max_allowed_packet=32M [mysql] max_allowed_packet=32M 而且我还在 JDBC 查询中添加了以下内
我需要测试 FTP 应用程序的数据包丢失情况。我用了Wireshark数据包嗅探器,我得到了 TCP 流。 如何使用 Wireshark 查找丢包情况? 最佳答案 数据包丢失和其他相关指标(例如误码率
每个人。这就是我们的门记录系统 Falco。当员工在读卡器上刷他/她的 ID 时,信号会传送到 Falco 服务器并将数据(卡 ID、时间)输入数据库。 Falco 的报告真的没有帮助,所以我们的人力
我正在研究 iSCSI 协议(protocol),现在我处于使用 Wireshark 捕获要查看的数据包的阶段,哪些数据包用于维护事件 session ,以及当我将文件复制到我的逻辑卷时,哪些数据包被
我无法理解网络上的任何人如何使用数据包嗅探器。 我对网络的工作原理知之甚少,但让我这样说吧:假设 postman 过来把包裹送到我家门口。为什么我可以翻遍他的所有其他包裹并环顾四周? postman
我已经看到(通过实际读取 tun 设备)Linux 上的 tun 驱动程序可以在一次读取中返回多个 IP 数据包。反之亦然 - 您可以在一次写入 tun 设备中写入多个 IP 数据包吗? 最佳答案 实
这个问题确实集中在我的问题上,与我在该主题上找到的任何其他问题无关。 PSA:当我说“数据包”时,我的意思是在单个 socket.recv(maxsize) 中接收到的完整字符串 我在 Java(我的
我想提高数据包传输性能。在此之前我使用原始套接字,现在我研究 packet_mmap。我有数据包(帧),我已经从另一台 PC 的内核模块中捕获了这些数据包(帧),并将其放入当前 PC,现在我想通过以下
我正在尝试使用带有一些标志的 tshark,并为每个过滤的跟踪获取时间戳。我正在使用它来过滤系统中的所有 DNS 查询。我无法获得时间戳以及过滤器工作。例如,如果我尝试类似 tshark -t ad
我是一名优秀的程序员,十分优秀!