首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多层FPS体系结构

多层FPS体系结构
EN

Software Engineering用户
提问于 2023-02-27 17:31:54
回答 4查看 198关注 0票数 2

我正在创建一个多人游戏,在为服务器端创建一个好的架构时遇到了一些困难。

到目前为止,我们在服务器上存储了一个玩家列表,这些玩家是主动连接的玩家,他们互动的主要方式是用枪射击对方。为了方便这一点,我决定一支枪只能开火,在发射Referee时,我会检查攻击是否与敌人发生碰撞,并引用当前的游戏模式TimedDeathMatch,其中包含要分配给玩家多少伤害的规则。

当我们还需要告诉每个客户在空间中的一个3d点上播放“枪声”的声音效果时,就会出现复杂性。在这种情况下,我这样做是为了让Referee也管理这个过程。回顾一下Referee之后,我意识到它做了以下工作:

  1. 管理武器交互
  2. 管理网络声音
  3. 管理游戏的当前状态(准备,现场,完成)
  4. 方便从客户端到服务器的chatbox消息传递。
  5. 帮助服务器发布公告(谁赢了比赛)

正因为如此,Referee代码变得相当长,并且正在一次执行多项任务。我正在考虑创建一个AudioEngineerAnnouncerMessenger,然后将其中的一些进程分配给它们,这样就更容易理解了。

我想在这里得到一些关于我如何构造服务器端架构的反馈,以及可能的更简单的替代方案。我也想知道,我的命名惯例,建模后的职称/人是可以做的。

EN

回答 4

Software Engineering用户

回答已采纳

发布于 2023-02-28 15:15:14

你陷入了一个陷阱,认为每个名词都应该是一个类,而不是每个类都是一个类。通常,患有这种综合症的人会对他们节目中的每一个名词--玩家、武器、水平--都进行分类,但你似乎是从电视转播的运动球游戏中得到了名词--裁判员、AudioEngineer、播音员。我不太清楚你是从哪里得到这个想法的。

无论如何,“为每个名词做一个类”通常都是不好的建议。是的,粗略地说,类是名词,但是当它们有用的时候,你仍然想使用它们,当它们没有用的时候,你不想使用它们,就像任何东西一样。你不是因为在某个地方看到一个名词就养成习惯的。

你做到了,现在你对这些无用的没有实际意义的类应该做什么感到困惑。

我的建议是:删除它们(您可以保留代码),并考虑一下您希望计算机做什么,然后实现它。你不想让电脑假装是一个音频工程师--你想让它播放音频。

在游戏中,出现一个包含大量游戏逻辑的“神类”并不少见。这听起来像你的裁判课。IMO,这是代码不应该出现在任何类中的一个迹象,但是您使用的是一种语言,它使您将代码放入类中。

您仍然应该在有意义的地方使用其他类。你可以让chatbox成为一个单独的东西,因为它与游戏无关。你可能会使游戏状态(准备,生活,完成)成为一个独立的东西,这取决于它对你的游戏意味着什么。事实上,你的游戏状态经理(锦标赛?)new能不能打一场全新的游戏(回合?)每次它想要开始一次。

对于您的音频问题,有一个相关的模式,即观察者模式(也称为侦听器)。您可以创建一个类似于GunshotListener的接口,然后您的枪弹代码(无论是哪个类)都包含对GunshotListeners的引用列表。当玩家开枪射击时,枪声代码会做一些类似for(gsl in gunshotListeners) {gsl.onGunShot(player, coordinates);}的事情。

对于实用性来说,这可能太具体了,因为在你的游戏中发生了200件事情,而200个一次性听者类太多了。也许你会用SoundEffectListener做得更好,那就是for(sel in soundEffectListeners) {sel.onSoundEffect(coordinates, GUNSHOT_SOUND_EFFECT);}

然后,在创建游戏时,您将创建网络声音系统(以及其他所有东西,如chatbox系统),并将其注册为侦听器,将其添加到列表中。如果你想要一个不同的声音系统,你可以添加一个替代,如果你不想声音系统,你就不能添加一个。

就我个人而言(这可能会引起争议),我会把枪弹代码放在最方便你的游戏。开枪不是枪干的事。在现实生活中,枪炮射击,但在计算机生活中,计算机计算命中扫描的基础上的类型和形状的水平和位置的其他玩家,而枪实际上并不是很重要的过程。也许如果你游戏中的枪是完全不同的,那么把它放在枪类中是有意义的,这样它就可以被覆盖到每种类型的枪上。再说一次,也许不是。许多游戏都会将这段代码放在主游戏类、级别类(因为它访问了级别几何)或GunshotCalculator中。

我不明白你为什么需要一个特别的叫做裁判的东西。玩家不能通过上传自己的枪类作弊,对吗?我希望他们不能,因为他们可以上传一个枪类来格式化服务器的硬盘。所以你知道枪是干什么的,你知道他们不允许作弊,因为你没有写代码让他们作弊,所以你不需要额外的课程来确保他们不作弊。

票数 2
EN

Software Engineering用户

发布于 2023-02-28 11:08:56

多人游戏的核心思想,至少在有任何竞争或欺骗的理由,是永远不信任客户。

使用此模型,客户端只是一个愚蠢的客户机。它向服务器发送鼠标和键盘事件,服务器运行游戏代码,并返回所有玩家的状态。也就是说,玩家的位置,健康,动画状态,声音等等。所以编程服务器在原则上应该和本地的游戏编程没有什么不同。我不认为有需要有“裁判”,因为只有当你能保证一个有效的比赛状态,而如果你有这个情况,裁判又有甚麽用处呢?

为了提高延迟,通常会稍微偏离这个模型,这样每个客户端都会保持游戏世界的短暂状态。因此,如果一个玩家开枪,他的本地客户可以立即播放声音。服务器可能会决定他实际上没有弹药,而且没有开火。但是,如果玩家试图欺骗,或者存在严重的数据包丢失,则应该主要发生这种情况。您还可以尝试预测敌人的移动等,并接受他们可能‘传送’到正确的位置时,从服务器“正确”的位置。

票数 1
EN

Software Engineering用户

发布于 2023-02-28 12:55:48

这是那种很难做好的事情。“回滚网码”的一般主题是值得你阅读的,因为它可以创造或破坏玩家的体验。您还可以从学习代码可用的游戏(如Quake )中获益。

相对于

以职称/人命名模特的惯例是可以做的。

说大也大吧。问题是,在面向对象的设计中,我们更喜欢谈论领域内的事情,而在普通的FPS中,没有裁判员和播音员等等。听起来你最终得到了一个“上帝物体”,当一个项目没有良好的结构时,这很容易完成。

通常情况下,你会围绕“演员”构建一个游戏,这是能够在游戏中扮演角色的东西--玩家或非玩家角色。可能会进一步委托作为参与者的武器,这样您就可以让fireWeapon()执行各种不同的事情。通常情况下,所有的命中扫描检测和结果分配都将在那里进行。你也可以做个别的抛射演员,尽管当你有很多抛射演员的时候,他们的表演可能会很糟糕。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/444206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档