假设您正在构建俄罗斯方块游戏。作为任何合适的程序员,您的视图逻辑在一侧,业务逻辑在另一侧;可能是一个完整的 MVC 正在进行。
当模型发送它的update()
时,视图会按预期重绘自己。
但是……如果你想添加一个动画来消失一条线,你将如何在视图中实现它?
做出你想要的任何假设——除了“一切都被正确封装”。
假设您正在构建俄罗斯方块游戏。作为任何合适的程序员,您的视图逻辑在一侧,业务逻辑在另一侧;可能是一个完整的 MVC 正在进行。
当模型发送它的update()
时,视图会按预期重绘自己。
但是……如果你想添加一个动画来消失一条线,你将如何在视图中实现它?
做出你想要的任何假设——除了“一切都被正确封装”。
就个人而言,我会尽可能多地单独绘制屏幕,即使没有更新块位置。所以我会有一个带有“更新”和“渲染”部分的循环。更新根据执行或不执行任何位置更新和/或块移除的逻辑进行处理。Render 将球传给图形部分,该部分将块绘制到它们应该在的位置。
现在,如果有要擦除的行,逻辑知道并可以标记这些要删除的行。我在这里假设每一块都由 4 个单个块组成,并且这些块中的任何一个都是一个对象。现在,当此块设置了“die”标志时,您可能需要一些渲染部件来使该块消失(假设 500 毫秒爆炸)。在此时间之后,可以处理对象并且上面一行的块落下。为什么是 500 毫秒?好吧,您绝对应该使用基于时间的移动,因为这可以使不同计算机上的游戏速度保持相同。
顺便说一句,已经有所谓的游戏引擎提供这样的更新渲染循环。例如 XNA,如果您使用 .NET 行。您也可以编写自己的引擎,但要注意,这不是一件容易的事,而且非常耗时。我做过一次,没想到它会是像 Source Engine 这样的引擎;-)
大多数游戏都会执行一个循环,尽可能快地不断重绘游戏视图,而不是等待模型状态发生变化然后刷新视图。
如果您喜欢模型视图模式,那么视图在某些类型的对象从模型中移除后继续绘制它们并在几毫秒内淡出它们可能会很好。
另一种方法是将 MVC 类与差异执行之类的东西结合起来——“视图”是所呈现内容的模型,但绘图代码将“视图”创建的事件流与来自先前渲染的流进行比较。因此,如果在一个流中有一条线,而下一条没有,则绘图代码可以为差异设置动画。这允许将绘图从视图中抽象出来。MVC 中的“视图”通常是小部件的集合,而不是直接绘制显示的东西,所以无论如何你最终都会得到嵌套的 MVC 层次结构:应用程序是 MVC(数据模型、视图对象、应用程序控制器),其中视图对象有一个小部件集合,每个小部件都是 MVC(小部件状态(例如按钮按下)、外观/工具包绑定、工具包事件映射 ->
我自己也经常这样想。
我自己的想法一直沿着这条线:
1)视图被赋予了块的状态(形状,yada-yada),但带有额外的“过渡”数据:
2)必须删除一行的事实是在状态中编码的,而不是在视图中计算的。
3) 视图现在知道如何绘制过渡:
将游戏视为 MVC 很有趣。这是我从未采取过的观点(出于某种奇怪的原因),但绝对是一个有趣的观点,很有意义。假设您确实使用 MVC 实现了俄罗斯方块游戏,我认为在控制器和视图之间的通信方面您可能需要考虑两件事:状态和事件。
您的控制器显然是用户交互的中心点。当他们发出键盘命令时,您的控制器将解释它们,并进行适当的状态调整。然而,有时游戏会进入与特定事件相吻合的状态......例如用现在应该移除的块填充一行。
Scoregraphic 为您打下了良好的基础。您的视图应该以固定的周期运行,以保持跨计算机的一致速度。但除了更新屏幕以呈现新状态之外,它还应该有一个事件队列,它可以执行动画来响应。在俄罗斯方块中填充线条的情况下,您的控制器可以将派生自某种基本事件类型的强类型事件对象发布到视图事件队列中,然后视图可以使用该对象来执行适当的动画响应。