从零点五开始用Unity做半个2D战棋小游戏(三)
好久不見。
這是第19篇與游戲開發有關的文章。
| 寫在最前
這次想要一個簡單且傳統的戰棋小游戲,大概的玩法是:在2D世界里創建一張由六邊形地塊組成的戰斗地圖,敵我雙方依據體力在地圖上輪流行動并向對方發動攻擊,先消滅掉所有敵人的一方將獲得勝利。
預計將分為以下幾篇(未完成前可能會調整...):
1、創建戰場(已完成)
根據預定尺寸生成戰場地圖,并隨機一些障礙物。
2、添加地圖功能 (已完成)
實現戰場格子點擊反饋,地圖導航及范圍選定。
3、添加對戰雙方
向戰場中添加作戰單位,作戰單位輪流行動,可進行移動、攻擊。
4、加入玩家控制
玩家可控制一個戰斗單位,手動選擇移動目標及攻擊單位。
5、添加戰場UI
添加可以隨時顯示戰況的Hud、為作戰單位添加血條等。
6、擴展作戰單位
豐富作戰單位的類型,添加職業,并加入若干不同類型的技能。
7、擴展戰場地圖
豐富戰場地圖,加入地形及道具等元素。
8、規范戰斗配置
可以通過規范化的數據結構配置戰場、職業、技能、道具等。
上次的主題是:添加戰場地圖功能。
本次的主題是:添加對戰雙方。
| 目標
向戰場中添加戰斗單位,完成簡單的戰斗循環,看起來的樣子是:
1、戰場中的對戰雙方輪流行動,可進行移動、攻擊;
2、攻擊將對敵人造成傷害;
3、沒有生命值的戰斗單位會被從戰場中移除;
4、當一方被全部消滅時,戰斗結束。
實現后的效果如下圖:
| 準備工作
在開始之前,我們先做一些準備工作。
顯示格子坐標
為格子添加Text Mesh Pro組件以顯示格子坐標,方便調試。
添加了坐標顯示,調試起來感覺方便多了呢
增加地圖功能:放置出生點
我不想看到戰斗單位在剛進入戰場的時候是隨機擺放位置的,因此我需要為它們提供一些出生點。這樣當戰斗單位初入戰場時,會向戰斗地圖請求一個本方可用的出生點,如果請求成功則加入戰場,并設定在那個位置上;如果請求失敗則不會進入戰場,避免出現亂占位置的情況。
想象中出生點的位置,最上、最下排奇數位置放置出生點
實際生成的情況(綠色為出生點)
增加地圖功能:尋找最近可用格子
指定一個起點和一個終點,返回一個環繞終點的距離起點最近、且可用的格子。這主要是為了戰斗單位在確定攻擊目標后,需要選擇一個它身邊的格子作為移動的目標格子(目前假定所有戰斗單位的攻擊半徑都為1)。
這里選擇了一種比較偷懶的方法,就是將二手手游賬號買號導航位置直接設定在目標單位的身上,如果導航成功,則將到達終點的前一個格子作為目標格子,這樣不僅確定了目標格子,同時還將導航路徑一并算出。
點擊起點和終點進行測試(紅:起點,藍:終點,灰:障礙,青色:目標格子)
準備工作到此為止,下面開始加入戰斗單位。
| 添加戰斗單位
因為是六邊形瓦片地圖組成的戰棋游戲,因此我將戰斗單位也表示成六邊形,目前來看兩者的Prefab并沒有什么差別,通過設置Order值來確保戰斗單位顯示在地圖格子的上方。
為了更好的區分戰場雙方戰斗單位的差異,我們給它們設置不同的顏色。
雖然從顯示方式來看,戰斗單位與地圖格子并沒有什么差別,可是如果從數據角度出發,兩者的差別可就大了。為了更好的介紹戰斗單位,讓我們從上至下來梳理一下整個戰場與戰斗系統吧。
| 戰場與戰斗信息
一個戰場就是一場完整的戰斗。每一個戰場目前都包含三大部分:戰場地圖、對戰雙方以及戰斗過程。
戰場地圖
地圖在之前的文章中已經做了說明,這里不再贅述。
對戰雙方 對戰雙方的單位是戰斗組,這里用戰斗組編號區分各組,而不是僅用兩個枚舉來簡單表示,是考慮到有很多組同時存在且同時對戰的情況。
真正發生戰斗的被稱為戰斗單位,每個戰斗組由若干戰斗單位組成。戰斗數據、戰斗組與戰斗單位之間的關系如下圖。
戰斗過程
戰斗打響時,從兩個戰斗組進入戰場,到雙方輪流移動、攻擊,最終分出勝負,發生的一切事情,都是戰斗過程,這個后面會詳細說明。
| 戰斗的流程
戰斗流程包含了戰斗的核心邏輯,是戰斗能正常進行且完成的規則,我們用下圖來描述一場戰斗的基本流程。
| 將數據與顯示分離
這里還是采用了將數據與顯示分離的處理方法,先看一張數據處理的流程圖吧。
圖中很關鍵的一個內容是戰斗過程數據,上面提及它其實是包含了自戰斗單位進入戰場,到戰斗最終完結之間的所有過程數據。
其實,當開始一場自動戰斗時,戰斗計算器會瞬時計算完整場戰斗的過程及結果,但這些結果只是數據,并沒有呈現給玩家。
當我們需要把這場戰斗呈現出來時,把這份數據傳遞給一個對應的顯示(播放)器即可。就好像后端和前端的分工一樣,一個負責產生數據,一個負責將數據呈現。
數據與對應的顯示器
戰斗數據的顯示器
地圖格子顯示器
戰斗單位顯示器
| 順序分步呈現數據
我這里使用協同函數(Coroutine)的嵌套來分步呈現戰斗過程。
戰場顯示器開啟逐步呈現戰斗過程(戰斗單位的行動)
戰斗單位顯示器根據自己的動作數據呈現具體動作,如:
進入戰場
選擇目標并移動(青色框:發動攻擊方,黃色框:攻擊方的目標)
選擇目標并攻擊(青色框:發動攻擊方,黃色框:被攻擊方)
| 分離的意義
走吧,走吧,人總要學著自己長大。
人是這樣,數據也是。
其實直接使用一個繼承與MonoBehaviour的腳本,把各種需要的數據都裝在里面,直接掛在Prefab上,然后用一個控制器一邊算一邊呈現給玩家,實現起來非常容易。
但是,考慮到后臺可能有多場戰斗同時在進行;且后期可以在短時間內進行多場戰斗、收集數據來做戰斗數值平衡。將數據分離,讓數據可以自行計算,就變得十分重要了。
20x20地圖下,10 vs 10的千場戰斗結果計算,可以在很短的時間內完成
| 寫在最后
至此,添加對戰雙方篇就介紹到這里,詳細代碼可以移步Github下載。
感謝您能讀到這里。
愿不忘初心。
下回見。
總結
以上是生活随笔為你收集整理的从零点五开始用Unity做半个2D战棋小游戏(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从零点五开始用Unity做半个2D战棋小
- 下一篇: 从零点五开始用Unity做半个2D战棋小