《獸人倖存者》:程序猿單刷Boom之旅


3樓貓 發佈時間:2024-09-02 14:32:25 作者:凍爪爪 Language

大家好,這裡是凍爪,第二次參加BOOM。這次是單人參賽,想挑戰下自己的極限!
《獸人》是一個看上去很大的遊戲:場景很大,敵人很多,裝備很多。
這是我製造的假象,《獸人》的內容量和我的實際工作量是有出入的。我寫了一個能支持一系列基本的指令的數據結構。然後只要將這些基本指令,排列組合,就可以生成大量的內容。就像搭積木一樣。
《獸人倖存者》機核鏈接 最新版網盤地址

"I have a plan"

Change your ___, not your ___.
這次Boom的題目看不懂。這個黑色字體填空題,我唯一能想到的就是耐克,因為耐克廣告也是黑色字體。
既然沒思路,那就從自己的優缺點開始分析。確定了遊戲的類型,再決定題目。策劃、劇本、美術、程序四個方面,單走的我該如何取捨呢?
  • 首先我沒做過策劃。我一個月前嘗試寫過策劃案,只憋出來兩頁。作為比較,上一次Boom我們組的策劃寫了幾十頁,還有Excel和ppt。我的策劃能力顯然是地下室級別的。所以,我這次的遊戲必須足夠直白,不能有關卡,絕對不能有解密。
  • 我會寫作,但不多。寫劇本要佔用很多遊戲開發的時間,與其寫一個半吊子劇本,不如多花時間寫幾行代碼。所以不要劇情了,砍掉砍掉。
  • 我會畫畫,但速度很慢。速度慢,那最後肯定得加入素材圖,一旦素材和自己的美術風格不統一,就會吃力不討好。乾脆全用像素素材包。不同像素素材包之間差別小,改起來也簡單。
  • 我會編程...而且還挺強。所以我要強化自己的優勢,挑戰更難的代碼:
開放世界,程序生成地形,做!
隨機裝備技能,肉鴿刷刷刷,做!
大場面戰鬥,屏幕裡一百個敵人追殺主角,做!
我來用隨機函數狠狠堆料!我要煮一鍋亂燉,獻祭給混..(劃掉)隨機女神!
大就是好,多就是美。
確定遊戲方向後,我拍了拍腦袋有了主題。
獸人小賊,在無邊無際人類地盤上不停的奔跑!一邊偷盔甲,一邊被追殺。不斷升級詞條,直到盔甲升級到能無視所有人的攻擊!免傷100%。
我命名為《盾之勇(劃掉)...《獸人倖存者》。
Change your armor, not your sword.

具體靈感來源移步我的雞脖

查看詳情


完美的計劃,what can go wrong?

以為有素材包就萬事大吉?

美術方面我決定使用2.5D像素風格。世界基地是3D的,是由類似MC的方塊組成的,我只需要畫幾個方塊,然後通過程序生成地形。世界裡的小人兒和景物都是2D像素素材。
遊戲最終效果:地塊是3D的,人和景物是2D的

遊戲最終效果:地塊是3D的,人和景物是2D的

我在早先時候購入過兩個像素素材整合包,一個是環境素材,另一個是像素小人各種動作的三視圖。我天真的以為這就夠了。但是...
一個2D角色,想在3D環境中自由轉身,前左右三面是不夠的......必須補全背面,前左,前右,後左,後右,八張圖!
素材包裡的 VS 我補全的

素材包裡的 VS 我補全的

跑、跳、待機、攻擊,每個動作8個方向,考慮左右、上下是鏡像,我需要畫5個方向。同時每個動作4幀動畫,加起來就是4x5x4=80張圖。扣掉素材包裡有的,我還得補全大約50張圖。
所有角色

所有角色

畫主角小獸人畫了5個小時,繃不住了,握鼠標的手都麻了。我決定所有敵人都不能跳躍,這樣可以少畫一個跳躍動作,每個角色起碼省掉15張圖。
在畫了6個角色後還是受不了。於是我把魔法師敵人設定為固定炮臺,省掉跑的動作。最後狗狗更是偷懶了,沒畫正面和背面。
畫完敵人後,用以前項目寫的狀態機給敵人們加了AI,近戰、遠程、狗,一共三種行為模式。
弓手狀態機

弓手狀態機

此時,Boom過去了將近一半。

開放世界不是這麼簡單的

摳像素圖嚴重擾亂了我的計劃,於是我向公司請了一週假搞開發。
在網上學習了下如何用Unity柏松函數生成等高圖,進而生成地形。我可以通過調節參數改變地形的崎嶇程度,每套參數搭配一個獨特的地塊,就成了一種新環境。所以實際上的美術只需要一個方塊的貼圖,輔以像素圖包裡現成的2D景物圖,就能實現好看的場景。我成功把美術問題轉化成了程序問題。
多種地貌

多種地貌

地塊生成會卡頓一下,然後地圖突然加載出來。我不喜歡這樣,我希望玩家能看到地圖生成的過程,於是我把過程拆分成了十幾幀,玩家就能看到地圖從光禿禿的地面,慢慢填滿景物和敵人的過程。遊戲的開始界面就是世界生成過程。
要做開放世界的話,還要考慮性能表現。我開發使用的是2021年的macbook pro,已經很過時了,所以如果遊戲能在我的電腦上流暢運行的話,大部分玩家都不會遇到問題。
如下圖,我準備要根據主角的位置時時更新周圍的場景。即根據和玩家的距離,決定是否顯示。為了減少卡頓,這些刷新會拆分成4幀完成:第一幀刷新敵人和投擲物,第二幀刷新寶箱和警戒值,第三幀刷新景物,第四幀刷新地塊。實際測試效果很不錯。
然後我遇到了問題——敵人的尋路AI沒辦法跟著生成的地圖動態變化。敵人沒法識別新生成的地形,只會蠢蠢地目送玩家逃跑。
尋路AI需要預先掃描所有地形來計算AI的路徑,但我的地圖是實時生成的,這就導致我必須在遊戲中,每隔幾幀刷新下尋路的範圍,不然AI就會撞上空氣牆。這會給程序帶來很大負荷,玩家可能遭遇卡頓。
權衡之後,我決定拋棄開放世界,採用關卡式設計,每一關使用一個200*200的隨機生成地圖,玩家在到達地圖邊緣後往下跳,就會進入下一個關卡。

難度曲線

採取關卡的設計,除了保障運行順暢,還有一個額外的好處——我可以更輕鬆地控制難度曲線。如果玩家在上一關玩的太輕鬆,我就可以在下一關增加難度。
遊戲裡使用瞭如下難度調節:
  • 玩的時間越久,敵人傷害/攻速越高,攻擊冷卻越短
  • 玩的關卡越多,地圖上的寶箱越多,寶箱裡的裝備越好
  • 上一關開的寶箱越多(遊戲中用通緝度表示),意味著上一關難度過低,下一關就會提高遠程敵人的數量
我有點沉迷做編輯器,花了不少時間做了難度調節界面,卻只用了一次。純純浪費時間了屬於是。其它Solo的同學引以為戒,給自己用的玩意,不需要弄UI。
敵人傷害修正,寶箱密度,通緝度,敵人種類密度

敵人傷害修正,寶箱密度,通緝度,敵人種類密度

既然提到了難度控制單元,我給大家看看其他控制單元吧。我這次所有控件全都用可編程對象(ScriptableObject)寫成,也就是說所有的遊戲邏輯是和場景解耦合的,控件間的交流是發生在場景之外的。
這比單例模式(Singleton)好的地方是,即便場景內缺少某個控件也不會報錯,我可以單獨測試一個或幾個控件。單例是場景內唯一,可編程對象是整個遊戲內唯一,每次改動控件參數,它們就會在所有場景生效。
相機控件,寶箱控件,難度控件,敵人控件,輸入控件,揹包控件,子彈時間控件,世界生成控件

相機控件,寶箱控件,難度控件,敵人控件,輸入控件,揹包控件,子彈時間控件,世界生成控件

技能和裝備詞條

在最後三天的時候,我終於開始做技能了,一個刷裝備的遊戲直到最後才開始做核心機制(捂臉)。
我放棄了許多設想的很酷很帥的技能,現在只要能把遊戲做完我就謝天謝地了。
我的思路是把主角的所有屬性劃歸為數值,然後所有裝備的詞條就是在圍繞這些數值做文章。我避免一些獨特的機制,比如與敵人有交互的機制,撞開敵人,吹飛敵人之類的。
我設計的技能就只是圍繞主角本身的。比如加速技能,就是主角速度*2,在3秒後速度變為正常。無敵技能,就是把受到傷害鎖定為0。多段跳,就是允許玩家在空中多按幾次跳躍鍵。它們的實現只需要一兩行代碼。
我唯二專門做的技能是閃現和子彈時間。因為《獸人》是一個跑酷躲避敵人的遊戲,玩家的移動性能必須足夠高,閃現和子彈時間是快節奏遊戲裡必備的技能。
遊戲中一共有4種閃現詞條:往前閃現/短距離隨機閃現/長距離隨機閃現/閃現到下一關。他們搭配不同觸發條件:受擊觸發/破甲觸發/主動觸發,有12種變種。子彈時間則是根據時長分了4個檔次,同樣搭配3個觸發條件,12種詞條。
為了填充數據方便,我給每種屬性變化設了代碼。最後好巧不巧,一共99種詞條。這些詞條按照強度,分成低、中、高3個池子。不同等級的裝備會有概率從不同的池子裡抽選詞條。池子裡有些技能的出現概率會高於別的技能,保證玩家不會突然爆發。
截止前12小時我還在填表。經過測試,最後的最後,在截止前6小時,遊戲完成!!

感想

這次Boom我時間管理出了些問題,幸好我是一個人做,迅速調整了計劃。這個題材我是拍腦瓜子決定的,沒什麼深度,真要給我再多時間,恐怕提升也有限。之前按照反饋更新了一次,提升了一些用戶體驗。但我之後也不會繼續開發下去了。
這次Boom我可以算是莽過關了。能做完我很開心。自己缺乏的東西真的很多,下次希望和別人合作完成吧,一個人的力量確實是有限的。兄弟們下次約!
(覺得好玩的給我投個票






© 2022 3樓貓 下載APP 站點地圖 廣告合作:asmrly666@gmail.com