草庐IT

c++ - 2D 物理游戏的多人/网络选项

coder 2024-02-23 原文

总结:

我完成了 50% 的 2D 横向卷轴游戏,使用 Box2D 作为物理引擎,最终版本应该支持多人游戏。然而,目前的代码只是一个单人游戏。

  • 我现在应该做什么?
  • 更重要的是,我应该如何实现多人游戏并将其与单人游戏结合起来?
  • 将单人模式与多人模式分开编写代码是不是一个坏主意(就像 Notch 在 Minecraft 中所做的那样)?

单人游戏的性能应该尽可能好(使用环回服务器模拟物理来实现单人游戏模式会是一个问题)

完整背景/问题:

我正在使用 C++ 开发一个相对较大的 2D 游戏项目,物理是其中的核心元素。 (我为此使用 Box2D)

完成的游戏应该有完整的多人游戏支持,但是我犯了一个错误,我没有正确规划网络部分,直到现在基本上都是在单人游戏上工作。

我认为多人支持可以以一种相对简单明了的方式添加到即将完成的单人游戏中,但显然,据我所读,这是错误的。

我什至读到多人游戏应该从一开始就被编程为一个游戏,单人游戏模式实际上只包括托管一个不可见的本地服务器并通过环回连接到它。 (我发现大多数 FPS 游戏引擎都是这样做的,例如 Source)

所以我在这里,我的 2D 横向卷轴游戏已经完成了一半,但我真的不知道如何继续下去。

简单地继续在单人游戏/客户端上工作现在对我来说似乎毫无用处,因为我以后不得不重新编码和重构更多。

首先,向可能遇到这种情况的任何人提出一个一般性问题:

  • 我应该如何进行?

然后,更具体的一个 - 我一直在努力找出如何为我的游戏处理网络部分:

  • 单人游戏的隐形/环回服务器

这样做的好处是单人模式和多人模式基本上没有区别。不需要太多额外的代码。

一个很大的缺点:单人游戏的性能和其他限制。将运行两个物理模拟。一个用于客户端,一个用于环回服务器。

即使您通过为环回服务器的数据提供直接路径来解决问题,例如通过线程直接通信,单人游戏也会受到限制。

这是一个问题,因为人们应该被允许同时玩弄大量的物体。

  • 独立的单人/多人模式

单人模式不会涉及服务器。

我不太确定这会如何运作。但至少我认为会有很多额外的工作,因为所有单人游戏功能都必须重新实现或粘附到多人游戏模式。

  • 多人游戏模式作为单人游戏的模块

这只是我的一个快速想法。多人游戏可以包含一个单人游戏,加载一个额外的网络模块并连接到服务器,该服务器发送和接收数据并更新单人游戏世界。

回想起来,很遗憾没有早点规划多人模式。我真的被困在这一点上,我希望这里有人能够帮助我!

最佳答案

我认为Notch正在感受到分别开发SP和SMP的痛苦。特别是自从他告诉 Bukkit 开发团队他计划过渡到“单人本地服务器”方法(正如你所说,就像 Source 引擎。)

没有理由必须运行多个物理模拟,本地服务器和客户端之间的延迟可以忽略不计,延迟补偿可以完全禁用。

此时您可以使用两种基本模型: 一个专用的服务器程序,它可以处理你游戏的所有大脑并让客户端连接。 一个监听服务器,游戏基本上可以根据用户设置充当服务器或客户端。没有单独的服务器程序。

制作客户端的最简单方法是向您的对象添加“虚拟”标志,这样这些虚拟对象将直接由服务器控制。然后,进入插值。 (以 60 Hz 的频率传输对象更新是不现实的,因此点之间的平滑使事情看起来仍然不错。Source 通过添加一点人为延迟来做到这一点,如果您曾经在低于标准的互联网连接上玩过 GTA4 多人游戏,您可以看到效果在快车上做得太过了。)

此外,推荐阅读: http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

关于c++ - 2D 物理游戏的多人/网络选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5135393/

有关c++ - 2D 物理游戏的多人/网络选项的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 我需要从 facebook 游戏中抓取数据——使用 ruby - 2

    修改(澄清问题)我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;但是,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的检查元素工具手动查找我需要的html-它似乎位于iframe中。但是,当我尝试抓取该iframe时,它​​是空的(属性除外):如果我使用浏览器的“查看页面源代码”工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案不是它是由AJAX之后添加的。(我知道这既是因为“查看页面源代码”可以读取Ajax添加的数据,也是因为我有b/c我一直等到我可以看到数据页面之后才抓取它,但它仍然不存在)。发生这种情况是因为

  9. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐