2009-05-21 87 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中填充行的情況下,控制器可以將強類型事件對象從某種基本事件類型派生到視圖事件隊列中,視圖事件隊列可以被視圖用來執行適當的動畫響應。