《地下9層》開發總結


3樓貓 發佈時間:2024-10-15 21:34:55 作者:失途鳥 Language

這是我獨立開發的第三款遊戲,也是我用pico-8開發的第二款遊戲。

《地下9層》

遊戲地址

動機

上次開發完Bullet Jam後,我對於用pico-8這種提供基礎功能庫的引擎開發遊戲起了非常濃厚的興趣,於是打算立刻用它開發一款自己一直以來都想做的遊戲——橫版格鬥。
因為我第一次學習遊戲開發的書是那本《Flash mx 2004 遊戲設計與製作》,裡面教了一款名為《閃客快打》的遊戲,我後來又玩到了它的續作《閃客快打2》,一下子對這種遊戲印象深刻,一直想自己做一款類似玩法的遊戲。
1 / 2
另外這次我也想要提高遊戲的規模和完成度,做一個有有限流程的遊戲。
以及因為pico-8是一個只提供基礎接口的引擎,所以我很想在這個基礎上編寫一套2d格鬥遊戲的遊戲框架,這相當於重複造一遍很多遊戲引擎的輪子,雖然對遊戲開發而言不是一個高效的選擇,但卻是我個人的興趣所在。
還有一個動機,我這次打算試著在社交網絡上同步自己的開發日誌,試著體驗一下游戲的網絡宣傳。

設計

當時做的玩法規劃

當時做的玩法規劃

比起前兩個項目,我這次花了不少時間來做前期規劃,包括渲染邏輯的初步搭建,玩法和一些關鍵的畫面訴求,現在回頭看,發現有些規劃準確地實現了,有些則完全拋棄了(比如對話系統),還有一些則是做的過程中的意外收穫。
另外還做了遊戲的主循環的邏輯和一些數據規劃,因為格鬥遊戲裡,對於2d角色動畫的控制是核心,很多設計打擊感的前搖、硬直以及攻擊判定和被擊時間窗口都需要對動畫幀信息做處理,所以我專門花了不少心思來設計幀動畫的數據結構和狀態機的邏輯(但其實後面狀態機的邏輯是重構了的)
1 / 2

製作

從8月25日開始正式進入實際製作。
首先就是狀態機和動畫系統,在做了一些測試後,我初步搭建了player角色的狀態機,繪製了它的站立動畫,從而也初步搭建了動畫系統。
對了,pico-8用的是lua語言,這是一個本身不面向對象的腳本語言,但可以通過一些方式來實現面向對象的編碼。於是我在寫動畫系統和狀態機時,在網上找了一些lua實現面向對象的資料,卻意外地發現lua非面向對象的特性反而導致它在實現面向對象編碼時可以整一些歪招,反而可以提高類繼承的自由度(其實只是節省了一些代碼量,但這對於有代碼量限制的pico-8來說卻很關鍵)
初步實現了player的站立和奔跑之後,我繼續繪製了player的三段攻擊動畫,並且實裝進了遊戲裡。然後發佈了第一個開發日誌。(pico-8自帶的錄製gif功能真的很適合輸出社交媒體素材)
然後是player的翻滾動作,這裡我第一次收到了社交媒體上網友的反饋,為這個動作加上了煙霧效果。
1 / 2
製作煙霧效果時我第一次遇到了需要判斷在哪一幀出現煙霧的問題,這個問題很關鍵,因為之後當我需要調試手感和製作敵人的各種動作時間點時都會需要能快速地查找動畫的信息,於是我在圖二中加入了一個debug系統,這就是我在規劃外意外搭建了第一個系統,這個系統結合pico8的錄屏功能,可以準確地逐幀回看遊戲記錄。
再然後,我開始繼續繪製第一個敵人,而此時,我原來寫的動畫系統就開始出現問題。
情況是這樣的,我原本寫的動畫系統是把動畫裡的序列幀信息、幀長度、速度等信息都保存成一個lua腳本,在遊戲加載時讀取這個腳本,把所有的動畫信息都存進內存裡,播放的時候調用,這當然是個簡陋且低效的系統,但對於這個小遊戲來說也夠用了,我當時是這麼認為的,但有一個問題卻擺在了我的面前,那就是pico-8對於遊戲代碼文件的大小限制:
pico-8對於遊戲的代碼限制除了文件本身大小外,還有一個lua腳本的token數量,也就是最小語義單元,在一個遊戲文件裡最多隻能試用8192個token(最小語義單元,比如 if 語句中,一個 if then end),而我把動畫信息存進lua腳本的做法會大大增加腳本文件的token數量,所以我必須對動畫數據做壓縮,把空間留給更重要的遊戲邏輯代碼。
一個簡單的 if 語句的token數量

一個簡單的 if 語句的token數量


pico-8的token限制

pico-8的token限制

於是我想了個歪招(後來我才知道那其實是pico-8圈子裡的慣用套路了),就是把原本佔用大量token的一串代碼,轉成只被識別為一個token的字符串,用某個特定字符來分割信息,然後再寫代碼來批量讀取信息,再在運行時存入內存裡。這樣動畫數據的token數量就被大大壓縮了。
把動畫幀的座標數據存成字符串,事實上如果需要也可以把其他數據也寫進字符串裡,但當時做到這個程度就夠了

把動畫幀的座標數據存成字符串,事實上如果需要也可以把其他數據也寫進字符串裡,但當時做到這個程度就夠了

另一個我費了很大功夫實現的功能是關於Aseprite的,Aseprite這個軟件相信做像素風格遊戲的人肯定不陌生,它可以在做完像素動畫之後把圖片信息批量導出,而對於我這個遊戲來說,極限壓縮數據肯定是剛需,所以我選擇了最大程度壓縮圖片的邊界,讓它們緊密貼合的導出格式,而這導致的一個問題就是每次導出時,我只要對序列幀內容稍作修改,Aseprite自動拼接的圖片位置就會改變,因此就需要重寫序列幀的座標信息,手動修改的話工作量會非常恐怖,於是我又臨時複習了一下python,編寫了兩個自動處理Aseprite導出的JSON文件,並轉化成lua腳本文件的腳本,這也是我第一次體會到用底層框架做遊戲時,開發這種便攜工具的重要性。
當時寫的python自動化腳本

當時寫的python自動化腳本

之後,我繼續遊戲開發,這裡出現了又一個之前沒有想到的問題:體積碰撞
我之前確實沒想到一個格鬥遊戲會涉及體積碰撞,但現在想來其實是很關鍵的,因為絕大多數的格鬥遊戲裡,角色的傷害是靠攻擊動畫的Hitbox產生的,角色碰撞本身不會產生傷害,也就無法處理當兩個角色座標接近時,角色貼圖重疊在一起的情況,這種情況下游戲畫面會顯得很不可信,而且也會導致玩家可以疊怪後一次性擊殺多個敵人或被多個重疊的敵人打中產生暴擊的問題。
一些格鬥遊戲的處理方法是增加一個貼身投技,即當玩家和敵人考得太近時會把敵人抓起來,但我個人不太喜歡這個做法,因為我自己玩這類遊戲的時候總覺的這個機制會讓我的角色在抓起敵人的時候機動性大大降低。所以我決定還是自己寫一個簡單的體積碰撞系統,讓所有角色都有一個體積屬性,可以在座標重疊時把彼此推開。
當時為體積系統寫的測試

當時為體積系統寫的測試

寫完體積系統後,我又遇到了token數量限制的問題(這個問題在後期一直困擾著我)體積碰撞系統消耗了大約三百多的token,這在整個系統裡佔據的空間超出了我的預期,我感覺到如果繼續下去我會沒法制作想要的敵人種類(當時動畫幀的壓縮也還沒做,整個項目的token數量非常不樂觀),於是我盯上了另一個可以壓縮token數量的部分——狀態機。
我原本寫的狀態機是比較簡陋的,是根據對象的當前狀態,判斷可能的下一個狀態,這樣寫雖然很直觀,但代價是重複的代碼量會很多,比如從站立狀態可以切換到移動或者攻擊狀態,而從攻擊狀態則可以切換到移動或是站立狀態,這其中就出現了重複的移動狀態,而一旦這種狀態的重複疊加上後續要加入的不同種類的敵人,它的代碼量會非常巨大,所以簡化這部分的代碼就很有必要了。
一番嘗試後,我選擇了根據一個角色在一次循環裡的可能獲取的信息,來判斷它的下一個信息,這樣以來,一個角色有多少種狀態,基本就會獲取多少種信息,而獲取下一個狀態機的代碼還可以封裝成函數在不同單位裡複用,因此狀態機可以寫得很簡略,只是構思狀態機時就需要多花些心思了,因為要整理清楚一個角色同時用到的所有必要信息和不同狀態之間的優先級。
一個敵人的狀態機函數

一個敵人的狀態機函數

最終,做完了狀態機的重構後,我的遊戲終於可以推進實際的內容了。
於是我開始編寫遊戲的主流程,包括一個玩家和敵人的血量、關卡完成的流程、玩家死亡流程。並且開始為後面的敵人做草稿設計。
當時設計的各種敵人,但最終並沒有全做出來

當時設計的各種敵人,但最終並沒有全做出來

然後,具體制作各種敵人就順利很多了,我基本是一天畫動畫幀,一天寫狀態機腳本,很快就寫好了token限制下能寫的最多種敵人。
在這段時間裡我也在積極更新社交媒體,同步我的開發狀態,我開始意識到社交媒體的同步是一件很鍛鍊心態的事情,很多時候隨著開發的進行,某個我自以為的巨大開發進展實際獲得的反饋卻很少,雖然我知道影響這些反饋的因素很可能和我自己沒關係,但剛開始仍然影響到了我的心態,慢慢的,當我堅持發佈開發日誌後,我對這種波動變得更耐受了。
1 / 6
再之後是BOSS關卡的製作,由於BOSS的狀態機和動畫幀數量顯然不可能放進當時的項目文件裡了,所以我採取了pico-8遊戲裡最常用的辦法:換卡帶,讓文件加載另一個遊戲卡帶,存放單獨的BOSS關文件。
做好BOSS關卡後,遊戲的主要部分基本就完成了,此時的遊戲token一度逼近了極限。我為了給音效部分騰出空間,把之前寫的debug代碼全部註釋掉了。
寫音效前的token數量

寫音效前的token數量

用剩下來的大約三百多token空間,我完成了最後的音效和標題畫面以及操作提示。
遊戲完成時主場景關卡的token數量

遊戲完成時主場景關卡的token數量

發佈

至此,遊戲開發完成,我開始準備遊戲發佈。
我將這款遊戲發佈在了三個平臺:機核網、itch.io 以及pico8的開發論壇。
同時我也在推特、微博、機核網和pico8論壇做了遊戲的宣傳。
現在從結果上看,機核網、微博和推特都得到了很多人的關注和回覆,itch.io上的數據也顯示有相當多的點擊自於微博的引流,而pico8的論壇卻反饋不大,這讓我很意外,我現在推測可能和pico8論壇本身的熱度以及它作為開發者論壇,對於這類玩法上並不創新,技術上突破也不大的遊戲興趣不大有關。
發佈四天後itch.io後臺的訪問數據

發佈四天後itch.io後臺的訪問數據

後續

這次的開發我學到了超級多了東西。其中最重要的幾點:
  • 我仍然很喜歡這種從基礎接口做起,再造輪子的開發方式,因為它可以讓我對自己的遊戲有更深層次的控制,我可以很好地掌控自己遊戲的規模和玩法。
  • 在以後的項目裡也不要疏於為遊戲的項目素材開發一些便捷工具,這對於提高開發效率很有意義。
  • 在社交媒體上同步開發狀態很重要,對於遊戲的曝光和引流都有幫助,同時準備一些有意思的圖片和媒體內容也能讓你獲得更大的關注度,畢竟遊戲的玩法是一回事,社交媒體的玩法則是另一回事。但無論如何,保證自身有條不紊的開發仍是最重要的。

未來

上一個項目讓我對pico-8充滿興趣並且開啟了這次的開發,而在這次項目之後,我對於pico-8的熱情也燃燒殆盡了……其實也不算是燃燒殆盡,只是我確實想要嘗試更大規模的遊戲開發了,我沒想到自己在這一個項目裡就摸到了pico-8的規模極限(當然事實上如果進一步壓縮也還是可以再精簡的,但這樣一來就更像是鑽研技術而不是開發遊戲了)。
因此之後我想試著尋找一些更大的基礎庫或是遊戲開發框架,當然眼下還是先休息一陣子。

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