2009-05-21 19 views
2

假设你正在制作俄罗斯方块游戏。作为任何合适的程序员,你的观点逻辑都在一边,而你的业务逻辑在另一边;可能是一个完整的MVC。俄罗斯方块和漂亮的图形

当模型发送update()时,视图会按预期重新绘制自己。

但是,如果你想添加一个动画来消除一条线,你会如何在视图中实现它?

做任何你想要的假设---除了“一切都被正确封装”。

回答

4

就我个人而言,即使没有更新块位置,我也会尽可能经常地单独绘制屏幕。所以我会有一个循环某处“更新”“渲染”部分。更新可以执行或不更新位置和/或阻止删除的逻辑。渲染将图形部分弹起,将图块绘制到应该在的位置。

现在,如果有行要擦除,逻辑知道并可以标记要删除的行。我在这里假设,每一块都由4个单独的块组成,而这些块中的任何一个都是单个对象。现在,当这个区块拥有“死亡”标志集时,你可以采用一些渲染部分消除该区块(比方说,500毫秒爆炸)。在这段时间之后,物体可能被丢弃,并且上面的一条线块掉下来。为什么500ms?那么,你绝对应该使用基于时间的移动,因为这样可以在不同的计算机上保持游戏速度不变。

顺便说一句,已经有所谓的游戏引擎提供这样的更新 - 渲染循环。例如XNA,如果你去了.NET线。您也可以编写自己的引擎,但要小心,这不是一件容易的事,而且非常耗时。我做了一次,不要指望它是一个类似Source Engine的引擎;-)

2

大多数游戏执行一个循环,不断重新绘制游戏视图,而不是等待模型状态发生变化,然后刷新视图。

如果您喜欢模型视图模式,那么在视图从模型中删除之后,视图可以继续绘制某些类型的对象,并在几毫秒内淡出它们。

1

另一种方法是将类MVC与差分执行相结合 - “视图”是呈现内容的模型,但绘图代码将'视图'创建的事件流与先前渲染的流进行比较。因此,如果在一个流中存在一条线,而下一条线不存在,那么绘图代码可以使差异动画化。这使得绘图可以从视图中抽象出来。 MVC中的'视图'通常是一些小部件的集合,而不是直接绘制显示的东西,因此无论如何,最终都会嵌套MVC层次结构:应用程序是MVC(数据模型,视图对象,应用程序控制器),其中视图对象有一个小部件集合,每个小部件都是MVC(小部件状态(例如按下按钮),外观和感觉/工具包绑定,工具包事件映射 - >小部件状态)。

1

我经常想知道这件事。

我自己的想法一直沿着这条线:

1)视图给出块(形状,亚达,亚达)的状态,但额外的“过渡性”的数据:

2)必须移除行的事实是在状态中编码,而不是在视图中计算。

3)视图知道现在该怎么画的转变:

  • 没有变化:状态是这个特定块
  • 从“下降”到“锁定”
  • 变化相同:状态是“锁定“(通过删除块)
  • 从”锁定“更改为”删除“:状态为”已删除“(线路完成)
  • 从”下降“更改为”删除“:状态为”已删除“但旧的状态是“下降”
1

有趣的是,将游戏视为MVC。这是我从未采取过的一个观点(出于某种奇怪的原因),但绝对是一个很有意思的观点。假设你使用MVC来实现你的Tetris游戏,我认为在你的控制器和你的视图之间的沟通方面你可能需要考虑两件事情:有状态,有事件。

您的控制器显然是用户交互的中心点。当他们发出键盘命令时,控制器会解释它们并进行适当的状态调整。然而,有时候游戏会进入一个与某个特定事件相吻合的状态......比如填写一个现在应该删除的块。

Scoregraphic给了你一个很好的基础。您的观点应该以固定周期运行,以保持计算机之间的一致速度。但除了更新屏幕以呈现新状态之外,它还应该有一个可以执行动画以响应的事件队列。在Tetris中填充行的情况下,控制器可以将强类型事件对象从某种基本事件类型派生到视图事件队列中,视图事件队列可以被视图用来执行适当的动画响应。