[轉錄][心得] 關於夏夜攻防戰 - 其四
為了驗證上面講的那堆有限機到底能不能達到我要的效果,我隨即開始寫
簡單的前置程式來測試。
我希望宣告一個物件,這個物件要內含上述的幾種State。
而每個State有兩個函式: Init() & runState()。
每當SEEKER從狀態A進入狀態B, 我就讓狀態A初始化。如此可以確保一些參數
回覆到一開始的狀態。
既然每個State有一個必備的Init(),我們可以宣告一個State的原形
再讓各個State繼承之。
這樣做最大的好處在於,我們可以用一個原形陣列去存取所有的State。
假如我想初始化SLEEP state, 我可以寫 sleep.init();
想初始化FIRE state, 寫 fire.init();
但是現在有一個問題在於PLAYER可以隨時隨地讓SEEKER進入"GOT"狀態
這意味著無論何時都有可能要初使化"某個"狀態
如果缺少了繼承的機制, 那麼寫出來的code可能會變成這樣:
switch (oldState){
case SLEEP:
sleep.init();
break;
case FIRE:
fire.init();
break;
.
.
.
}
明明可以很間單的事情卻因為對程式不夠了解的關係變成這樣,
這實在是很不漂亮的一件事情
繼承之後,我們只要宣告一個原形陣列,再把每個STATE的ptr塞進來就好
像這樣:
class proto{
virtual void init();
virtual void runState();
};
class sleep: public proto{
void init();
void runState();
};
class fire: public proto{
void init();
void runState();
};
//////////////
proto *store[2];
store[0] = new fire();
store[1] = new sleep();
///////////////////////////////////////////////////////
這個問題,等到了之後要實作武器庫的時候會再次碰到。
沒有繼承概念的程式碼,如何去應對總計17種不同的武器的選取?
實在難以想像。
總而言之,言而總之,最後關於Seeker的狀態機,寫出來的結果變成這樣:
seeker.loop(){
seeker.allState[this.state].runstate();
}
簡化過的程式碼變成這樣。這個seeker.loop() 就是放在主程式的部分,
每秒執行30次的那個,每一次執行,確認目前的狀態,然後執行此狀態的運算
其中如果有符合更改狀態的條件(如上篇文章的圖表所示),則透過更改this.state
來達成跳離STATE & 初始化的動作。
至於每個State的runState function,這邊就略過了。
大體就是把上篇文章的條件機制加以程式化而已。
畢竟講解Code是件無聊的事情。我還是主要講想法以及實作方式就好。
(續)
文章轉自暨大霞蔚山城 ★ HenryBBS (henry.twbbs.org)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 163.22.18.97
GameDesign 近期熱門文章
PTT遊戲區 即時熱門文章
16
23