我正在尝试制作一款多人网络游戏。每个玩家在屏幕上用矩形表示。我正在使用OpenGL作为图形,并且用户输入(MOVE-LEFT,MOVE-RIGHT等命令)将由它(或GLUT或sumthing)处理。
我有以下游戏架构。
游戏中有4个玩家(节点)。每个播放器都使用UDP发送和接收数据。每个玩家都可以将数据发送给任何其他玩家。
如果来自相应用户的任何输入,则需要由玩家发送数据。 (例如MOVE-LEFT命令等)。 每当玩家(比如说p1)收到任何其他玩家的任何数据(比如p2)(比如屏幕上玩家p2的新位置),玩家p1的屏幕应该立即更新。
我正在思考以下几点: 创建一个线程来处理图形。 使用UDP创建另外2个线程,每个线程用于接收和发送数据。
每当图形线程从用户那里获得'myposition'的输入时,它就会更新共享的全局变量'myposition'。正在等待此变量的网络发送线程被激活,并告诉其他所有玩家新的位置。
类似地,当从任何其他玩家“i”接收到“位置”更新时,网络接收线程更新全局变量播放器[i] .position。图形线程现在将使用更新的位置重绘场景。
这个设计是否正确。如果是的话,这个设计有多好,我该如何改进呢?
答案 0 :(得分:5)
网络游戏编程是一个主题的怪物,因此很难说“是的,这就是你设计网络架构的方式”。它完全取决于您的游戏要求。您计划发送什么样的数据包?每帧会发送一个数据包,表明玩家A持有左键吗?此流量是否仅限于局域网?
对于像4个客户端之间同步移动一样简单的事情,将发送,接收和呈现放在不同的线程中似乎有些过分。也许作为一个起点,你应该从一个更简单的设计开始,当你觉得你的数据包输出速度不够快时就转向多线程。
例如,您可能希望拥有如下所示的游戏循环(全部在同一个帖子中):
while (running):
readUpdSocketForIncomingPackets();
updateGameObjects();
renderGameObjects();
sendPacketsToPeers();
在每个帧的开头,您可以读取您的udp套接字以获取传入的数据包并更新位置(以及您发送给同伴的任何其他内容),然后绘制。在处理游戏输入时,在分组队列中创建和累积分组。这样做,允许您执行优化,例如将多个消息填充/合并到一个数据包中,删除重复的消息(例如,仅发送最新的位置更新)等。因此,在每个游戏循环结束时,最终的队列数据包被处理并发送给对等体。
但同样,这是一个很大的话题,我已经掩饰了很多细节。
看一下gaffer的博客: http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/
他有一些很棒的文章可以解决网络游戏编程的一些基本原理。