俄罗斯方块和漂亮的图形

发布于 2024-07-20 15:27:49 字数 211 浏览 8 评论 0原文

假设您正在构建一款俄罗斯方块游戏。 作为任何合适的程序员,您的视图逻辑位于一侧,业务逻辑位于另一侧; 可能正在进行完整的 MVC。

当模型发送其 update() 时,视图将按预期重绘自身。

但是……如果您想添加一个动画来消失一条线,您将如何在视图中实现它?

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

Say you're building a Tetris game. As any proper programmer, you have your view logic on one side, and your business logic on the other side; probably a full-on MVC going on.

When the model sends its update(), the view redraws itself, as expected.

But then... if you wanted to add, say, an animation to vanish a line, how would you implement that in the view?

Make any assumptions you want---excepting that "Everything is properly encapsulated".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冧九 2024-07-27 15:27:49

就我个人而言,即使没有更新块位置,我也会尽可能频繁地单独绘制屏幕。 所以我会在某个地方有一个带有 "update""render" 部分的循环。 更新对进行或不进行任何位置更新和/或块移除的逻辑起作用。 渲染将球交给图形部分,图形部分将块绘制在它们应该在的位置。

现在,如果有要擦除的线,逻辑就会知道并可以标记要删除的线。 我在这里假设每块都由 4 个单独的块组成,并且这些块中的任何一个都是一个对象。 现在,当该块设置了“die”标志时,您可能需要一些渲染部分来使该块消失(比方说,爆炸需要 500 毫秒)。 此后,该物体可能会被丢弃,并且上方的方块会掉落。 为什么是 500 毫秒? 那么,您绝对应该使用基于时间的移动,因为这可以使游戏速度在不同的计算机上保持相同。

顺便说一句,已经有所谓的游戏引擎提供了这样的更新渲染循环。 例如 XNA,如果您选择 .NET 线路。 您也可以编写自己的引擎,但要注意,这不是一件容易的任务,而且非常耗时。 我这样做过一次,并不指望它会成为像 Source Engine 这样的引擎;-)

Personally, I would separate draw the screen as often as possible, even if there was no update of the block position. So I would have a loop somewhere with an "update" and a "render" part. Update plays the ball to the logic which does or does not any update of positions and/or block removal. Render plays the ball to the graphics part, which draws the blocks where they should be.

Now if there are lines to erase, the logic knows and can mark those lines to be removed. I assume here, that every piece consists of 4 single blocks and any of these blocks is a single object. Now when this block has the "die"-flag set, you may take some render-parts to vanish the block (let's say, 500ms to explode). After this time, the object may be disposed and the block a line above falls down. Why 500ms? Well, you should definitely use time-based movement as this keeps the game speed the same on different computers.

Btw, there are already so called game engines which provide such an update-render-loop. For example XNA, if you go the .NET line. You may also code your own engine but beware, it's not an easy task and it's very time consuming. I did this once and don't expect it to be an engine like the Source Engine ;-)

末が日狂欢 2024-07-27 15:27:49

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

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

Most games execute a loop that constantly redraws the view of the game as fast as possible, rather than waiting for a change in the model state and then refreshing the view.

If you like the model view pattern, then it might work well for the view to continue to draw some types of objects after they are removed from the model, fading them out over a few milliseconds.

泪冰清 2024-07-27 15:27:49

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

Another approach would be to combine class MVC with something like differential execution - the 'view' is a model of what is presented, but the drawing code compares the stream of events the 'view' creates with the stream from the previous rendering. So if in one stream there's a line, and the next there isn't, the drawing code can animate the difference. This allows the drawing to be abstracted away from the view . Frequently the 'view' in MVC is a collection of widgets, rather than being something which draws the display directly, so you end up with nested MVC hierarchies anyway: the application is MVC ( data model, view objects, app controller ), where the view object has a collection of widgets each of which is MVC ( widget state (eg button pressed ), look and feel/toolkit binding, mapping of toolkit events -> widget state ).

旧瑾黎汐 2024-07-27 15:27:49

我自己也经常想知道这个问题。

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

1)视图被赋予块的状态(形状,yada-yada),但带有额外的“过渡”数据:

2)必须删除一条线的事实被编码在状态,不在视图中计算。

3) 视图现在知道如何绘制过渡:

  • 没有变化:此特定块的状态相同
  • 从“下落”更改为“锁定”:状态“锁定”(通过掉落块)
  • 从“锁定”更改为“remove”:状态为“removed”(通过行完成)
  • 从“falling”更改为“remove”:状态为“removed”,但旧状态为“falling”

I've often wondered this myself.

My own thoughts have been along this line:

1) The view is given the state of the blocks (shape, yada-yada), but with extra "transitional" data:

2) The fact that a line must be removed is encoded in the state, NOT computed in the view.

3) The view knows how to draw transitions now:

  • No change: state is the same for this particular block
  • Change from "falling" to "locked": state is "locked in" (by a dropping block)
  • Change from "locked" to "remove": state is "removed" (by a line completion)
  • Change from "falling" to "remove": state is "removed", but old state was "falling"
赠佳期 2024-07-27 15:27:49

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

您的控制器显然是用户交互的中心点。 当它们发出键盘命令时,您的控制器将解释它们,并做出适当的状态调整。 然而,有时游戏会进入与特定事件同时发生的状态……例如用现在应该删除的块填充一行。

Scoregraphic 为您提供了良好的基础。 您的视图应按固定周期运行,以在计算机之间保持一致的速度。 但除了更新屏幕以呈现新状态之外,它还应该有一个事件队列,可以执行动画来响应。 在俄罗斯方块中填充线条的情况下,您的控制器可以将从某种基本事件类型派生的强类型事件对象发出到视图事件队列中,然后视图可以使用该对象来执行适当的动画响应。

Its interesting to think of a game as an MVC. Thats a perspective I've never taken (for some odd reason), but definitely an intriguing one that makes a lot of sense. Assuming you do implement your Tetris game with an MVC, I think there are two things you might want to take into account in regards to communication between your controller and your view: There is state, and there are events.

Your controller is obviously the central point of interaction for the user. When they issue keyboard commands, your controller will interpret them, and make the appropriate state adjustments. However, sometimes the game will enter a state that coincides with a particular event...such as filling a line with blocks that should now be removed.

Scoregraphic has given you a great foundation. Your view should operate on a fixed cycle to maintain consistent speed across computers. But in addition to updating the screen to render new state, it should also have a queue of events that it can perform animations in response to. In the case of filling lines in Tetris, your controller could issue strongly typed event objects that derive from some kind of base event type into the view event queue, which could then be used by the view to perform the appropriate animated responses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文