将物理和游戏逻辑与UI代码分开


12

我正在研究一个简单的基于块的益智游戏。

游戏过程由游戏区域中的许多移动块组成,因此这是一个简单的物理模拟。但是,我认为我的实现还远远不够理想,我想知道您是否可以为我提供任何有关如何更好地实现的建议。

我将代码分为两个区域:游戏逻辑和UI,就像我处理许多益智游戏一样:

  • 游戏逻辑负责游戏的一般规则(例如国际象棋中的正式规则系统)
  • UI显示游戏区域和棋子(例如棋盘和棋子),并负责动画(例如棋子的动画移动)

游戏逻辑将游戏状态表示为逻辑网格,其中每个单位是一个单元格在网格上的宽度/高度。因此,对于宽度为6的网格,可以将宽度为2的块移动四次,直到其与边界碰撞。

UI会获取此网格,然后通过将逻辑大小转换为像素大小(即,将其乘以一个常数)来绘制它。但是,由于游戏几乎没有任何游戏逻辑,因此我的游戏逻辑层[1]除了碰撞检测之外没有其他工作。运作方式如下:

  1. 玩家开始拖动一块
  2. 用户界面要求游戏逻辑确定该棋子的合法移动区域,并让玩家将其拖到该区域内
  3. 玩家放手
  4. UI将样片捕捉到网格(以便它位于有效的逻辑位置)
  5. UI告诉游戏逻辑新的逻辑位置(通过mutator方法,我宁愿避免)

我对此不太满意:

  • 我正在为我的游戏逻辑层而不是UI编写单元测试,结果所有棘手的代码都在UI中:阻止该部分与其他对象或边界碰撞并将其捕捉到网格中。
  • 我不喜欢UI告诉游戏逻辑有关新状态的事实,我宁愿让它调用movePieceLeft()方法或类似的方法,就像我在其他游戏中一样,但是我对这种方法没有了解,因为游戏逻辑对用户界面中可能发生的拖动和捕捉一无所知。

我认为最好的办法是摆脱游戏逻辑层,改为实现物理层。我对此有一些疑问:

  1. 这样的物理层是常见的,还是让游戏逻辑层更典型地做到这一点?
  2. 捕捉到网格和片段拖动代码是属于UI还是物理层?
  3. 这样的物理层通常可以与像素大小或某种逻辑单位(例如我的游戏逻辑层)一起使用吗?
  4. 我曾经在游戏的代码库中看到过基于事件的碰撞检测,即玩家只需拖动棋子,UI就会顺从地渲染并通知物理系统,物理系统将调用onCollision()方法一旦检测到碰撞,就会在工件上撞上。更常见的是什么?这种方法还是先要求法律流通领域?

[1] 可能不是我所要表达的正确词,但是子系统听起来有些夸大其词,而却是错误的,因为每一层都可以包含多个类。


我的回答是否有帮助,需要任何进一步的信息?
Will Marcouiller

请帮助或接受答案(如果有帮助的话),或者告诉您您在实施此类体系结构或某些方面时遇到的问题,但是请及时告知您您的情况,以便我们为您提供更好的帮助。=)
Will Marcouiller

Answers:


3

尽管我没有太多的游戏开发经验,因为我仍然只是学习,所以我将尝试回答这个问题,因为我可以理解您的要求。

正如我所看到的,您要将GUI代码与游戏逻辑和域对象(即拼图)分开。这些确实是三个独立的层-是的,layer我认为这是一个适当的术语。它通常用于解释将系统的每个对象层划分为彼此独立的子系统的概念。

关于面向对象的编程,每个对象应为一个类。因此,您的难题的每一部分本身都应包含一个类,因此游戏板也是如此。游戏板应包含X个拼图,具体取决于您想给玩家的大小和移动能力。

因此,这是我对该主题的看法-希望对您有所帮助:

  1. GUI层:该层应仅包含在游戏板上显示棋子的方法,以允许游戏本身与玩家之间进行交互;
  2. 游戏控制器层:负责玩家的输入。那是应该告诉棋子朝不同方向移动的层,并询问游戏板在移动时是否会发生碰撞等。
  3. 业务层:该层应包含所有业务类,即游戏的各个部分以及包含拼图的游戏板对象。

在这种体系结构中,您将使GUI层显示玩家的游戏状态,每个拼图的位置。然后,GUI层将负责获取玩家的输入,并将其传递到底层的游戏控制器层,然后该层将负责碰撞检测。如果没有,则可以命令该部分向该输入方向移动。为此,您只需将其称为MoveLeftMoveRight,等等使作品动起来的方法。您不妨让游戏板知道您要移动的棋子,然后由棋盘自己命令棋子的运动,然后棋子向所需方向移动。这种体系结构使将每段代码测试到不同的层变得容易,然后允许您进行单元测试,集成测试和功能测试。

我知道这看起来似乎有点令人困惑,如果不是的话,感谢上帝!如果您需要更多详细信息和帮助,请随时询问,尽管我是游戏​​开发的初学者,但我将竭诚为您提供最好的帮助。

谢谢阅读!=)


2
听起来与Model View Controller非常相似。
tenpn 2011年

老实说,从底层实现抽象接口的任何描述都听起来像是Model View Controller。但这是因为使用的术语和技术是相同的(抽象了实现细节,将用户界面与实现分开了)。但是它假设一个非常简单的环境。这里有多层,每一层都有控制器。在这里,将视图与模型分开是不够的,您还需要将用户交互控件与游戏控件分开。
MrCranky 2011年

我想知道这里有什么复杂的事情,因为我们正在将难题的一部分移到分隔的游戏板上。控件是从GUI获取的,这实际上是一种好方法,然后传递给抽象层,即游戏控制器。游戏控制器检查移动时是否有碰撞,如果没有检测到碰撞,则告诉棋子移动。然后,拼图块会正确地朝请求的方向移动,并通过其Position属性获取器功能显示其新位置,因此游戏控制器现在需要GUI将移动的拼图显示到新位置。
Will Marcouiller

嘿,几个月前,我在游戏开发中撰写了有关“ MVC”的博客。是的,对于那些不熟悉游戏开发的人来说,这是一个很好的网关概念:codecube.net/2010/08/xna-for-the-everyday-developer
Joel Martinez

1
抱歉,我迟到了,很遗憾我暂时离开了该项目。我真的很喜欢控制器方法,我会采用它!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.