天天看點

初始的設計思路

我們把那個底盤稱為Board,該Board類實一個容器,是一個6*6(n*n)的棋盤。對于該棋盤,我們抽象的看,那是不是一個表格呢?

是以我設想,這個Board類從我們的Table類繼承,該Board類負責對底盤中的所有容器的控制。

Board類應該封裝一個6*6(n*n)的棋盤的事實(細節),然後應該提供一個AddDevice(obj,x,y)的方法,x和y很顯然,就是裝置要放置的位置,這個obj就是允許放置的裝置。

我們所需要的裝置有

光線源頭(line_head)

水晶(crystal)

傳光器(line_transmission)

阻礙物(obstacle)

炸彈(bomb)

時間漏鬥(time_funnel)

變色器(colour_changing)

選取框(choice_box)

如果,我建立一個Devicebase類作為這些裝置的基類,估計也沒有什麼不妥,不過這些裝置之間有的相同點實在是不多,是以要建立Devicebase類似乎意思不大。我又考慮這些裝置應該有的共同點是:

Draw,在給定的x和y的範圍内繪制自己的形狀和外觀

GetFocus,當得到焦點的時候,要在目前裝置框的周圍繪制出搖桿标記

LostFocus,當失去焦點的時候,要在目前裝置框的周圍撤銷搖桿标記

是以我打算聲明一個接口IDevice,該接口聲明了以上的方法。

是以Board類的AddDevice為:IDevice,x,y這樣會比較好點,感覺。

然後,我要添加一個新的裝置:空白(blank),6*6的表格預設存放的都是空白,該blank當然也實作IDevice接口。

接下來,我們要考慮光,光是不是對象呢?那一定是的。我們需要一個Light類。從遊戲的直覺角度來講,line_head需要一個Send方法,其他的裝置需要一個Receive方法。

具有Receive方法的裝置展現多态,每個裝置有自己對光的處理模式:延伸,阻隔和爆炸等。延伸其實就是繼續對光線的繪制。是以,我們在設計的時候,如果考慮對光的繪制是由裝置來控制的,我感覺就錯了。

我的設計是:光由自己繪制,但繪制的控制權由Board負責,裝置向Board描述光的方向性。

比如:

line_head向Board發出消息要求從x,y開始沿什麼方向繪制什麼顔色Light

Board沿方向計算Table中沿途的第一個裝置,然後将控制權給Light繪制。

Light繪制完畢後,Board通知第一個遇到的裝置接受光線

該裝置依據自身的規則計算光線的延伸,并發消息給Board,Board再計算。

如果Board計算出的第一個裝置是bomb,則遊戲結束

有些裝置允許旋轉和移動

是以我們要再聲明

IRotate接口

ToClockwise 順時針

ToCounterclockwise 逆時針

IMove接口

ToUp

ToDown

ToLeft

ToRight

我們希望當裝置得到焦點的時候,繪制出的句柄可以有明顯的提示讓使用者該裝置是不是可以旋轉或移動,或都不行。

(所有用具的移動和旋轉都需要靠選取框來完成~~選取框移動到沒有用具的格子或該用具不可移動和旋轉的時候~選取框表示成狀态1~~當移動到可移動和旋轉的用具時候~選取框表示成狀态2~~玩家第一次确認後,就可移動該用具,選取框表示成狀态3~玩家第二次确認後,就可旋轉該用具,選取框表示成狀态4~~玩家第三次确認後,完成對該用具的操作,選取框表示成狀态2~~當選取框處于狀态1和狀态2的時候~可以上下左右的移動~來捕捉用具~~在狀态3下,移動用具即移動選取框,選取框的狀态應同時帶進新的Cell中~~)

<a href="http://blog.51cto.com/attachment/201203/233350543.png" target="_blank"></a>

選中了以後~先是移動~再是旋轉~~

我考慮底盤的每個單元格都應該是一個對象,我們把它聲明為Cell對象,該對象是一個容器對象,當Board初始化的時候,每一個Cell都存放的是Blank對象,當Board使用AddDevice方法放入裝置時,其實是将裝置放入Cell中。

為什麼我要這樣做呢?我這樣考慮的,依據MVC,視圖(玩家直接觀察的部分)的變化其實是對資料(Board)的操作呈現。Board提供所有對遊戲行為的支援,隻不過這些行為分為兩種

一種是:Board的直接行為,比如提供使用者對Cell選擇确定等控制

一種是:對裝置的控制,這些行為其實是包裝了裝置的行為。

是以,底盤(Board)需要一個CurrentCell屬性,描述目前具有焦點的單元格。底盤實作上下左右的方法(IMove接口),這些方法影響CurrentCell屬性。CurrentCell總是傳回目前Board有焦點的那個Cell。

當Board執行IMove接口的方法時,會激發單元格焦點改變的事件,該事件會通知單元格中的裝置改變繪制搖桿(就是那個選取框)。得到焦點的時候繪制搖桿,失去焦點的時候消除搖桿。

繪制選取框是一個很值得考慮的問題,從效果來說,我們希望每個裝置的選取框都不一樣,感覺好看點,還有裝置的可旋轉和可移動也希望選取框有不同的繪制效果,但是也有可能大部分裝置的選取框繪制效果一樣,如果你認為要寫一個DeviceBase來實作選取框的繪制也可以,不過我提供另外的思路。

Cell來實作預設的焦點得失時的選取框的繪制。

首先裝置要實作Can系列屬性,向它所在的單元格描述目前裝置是否可以旋轉或者移動等。這個我們可以在IDevice接口中聲明CanRotate,CanMove,當Cell得到焦點的時候,它根據它所容納的裝置的Can系列來繪制選取框。如果裝置提供了自己的選取框,那Cell将用裝置的繪制方法替換Cell的預設,這種方式是我從ASP.Net學來的。這種設計模式,要比繼承更靈活有意思。

本文轉自shyleoking 51CTO部落格,原文連結:http://blog.51cto.com/shyleoking/806249

繼續閱讀