1. 程式人生 > >2018騰訊next idea高校遊戲創意賽——《秦徵》開發記錄

2018騰訊next idea高校遊戲創意賽——《秦徵》開發記錄

這篇文章記錄開發《秦徵》demo時踩過的一些坑和設計上的思考。
演示視訊(捂臉請原諒這拙劣的美工23333)
https://www.bilibili.com/video/av28456233

團隊構成

從團隊構成來看這次的確準備不周,原本預計有9個人,後來實習分走一大波,只剩下4個人,然後又有一個回家網不好上不了GitHub而退出,還有一個日常划水天天失聯(等等這劇情是不是有點熟悉)。好在剩下的一位大佬十分認真負責,最後有驚無險地壓線完成任務。

遊戲設計

在構思參賽題目的時候恰好十分喜歡《全面戰爭戰錘2》,加上曾經是《文明》中毒玩家,於是誕生了把戰棋類和即時操作雜糅起來的玩法(後來想想這不就是RTS嗎啊喂喂【強力拍桌】)。深入做了以後發現不然。棋類遊戲的規則有高度抽象

的特點,而RTS即時戰略類往往有高度模擬的特點。棋類遊戲得益於其抽象化的規則,可以使得玩家從全域性戰略的角度來考察局面,然而對戰時間往往夠長,而即時戰略類則一般是拼手速、講操作的戰術層面對抗。全面戰爭給出的解決方案是分為戰略檢視和戰術檢視,只有當開始對戰時才能看到戰術檢視。思路上來說,這個遊戲的設計目標是在短短兩分鐘內,帶來一次完整的戰棋體驗。

玩法

玩法融合了很多圍棋要素和中國象棋要素。主要是操縱我方棋子去攻擊敵方棋子,佔領更多的地盤、摧毀敵方的宮殿。地盤可以帶來諸多buff,還可以在我方地盤上建立新的棋子。

基於兵馬俑的兵種設計

兵種分為步兵、弓兵、車兵
立俑
1. 攻擊範圍:上下左右一格範圍。
2. 可以揮劍進行攻擊
3.攻擊力和防禦力都是中等的基礎兵種

跪射俑
1. 攻擊範圍:以自己為中心的九宮格。
2. 可以射出弓箭進行攻擊,攻擊力高於立俑,但是防禦力比較弱。
3. 一種比較有優勢的兵種配合是步兵在前線扛傷害,弓箭手在側翼進行輸出

戰車俑
1.攻擊範圍:當前朝向的正前方一格
2. 對步兵會造成比非常大量的傷害。
3. 相應的,被步兵攻擊側面也會有很大損失。
4.戰車俑有衝鋒加成的概念:從上一次轉向開始計算,每走一格累計一點衝鋒加成,轉向時清零。衝鋒加成會造成額外的傷害。

勝負條件

勝利條件:攻佔敵人的宮殿或者時間結束時,我方所佔有的格子數比敵方多
失敗條件:自己的宮殿被摧毀,或者場地中我方所佔有的格子數目比敵方少
平局條件:既不滿足勝利條件,也不滿足失敗條件的情況(一般不可能出現,除非雙方都掛機)

操作方式

操作簡潔直觀,主要互動有 放入棋子、讓棋子攻擊敵人、讓棋子移動到指定位置。

  1. 在場地內放入棋子:拖動兵牌到場地內屬於玩家的格子上(藍色區域)
  2. 操縱我方棋子攻擊敵方棋子:點選我方棋子,再點選要攻擊的敵方棋子,我方棋子會移動到合適位置進行攻擊
  3. 操作我方棋子進行移動:點選我方棋子,再點選要移動到的位置,我方棋子會移動到指定的位置。

領土規則

  1. 當週圍領土上屬於我方的格子比較多時,棋子的移動速度會變快、攻擊力會變高
  2. 只能在屬於自己的領土上放置新的棋子。
  3. 某一時刻,只能有一個棋子站在一個格子上。
  4. 有一些格子是不可走的,在demo中標紅(美術資源還沒做)。

硬傷

我們做到最後發現,使得體驗不如預想的竟然源於計算機經典問題——死鎖。死鎖在於我想去可以打到你的地方打你,你想去能達到我的地方打我。然後我到了能達到你的地方,你卻已經不在那個位置了——你已經來打我了。然後迴圈往復,雙方永遠“在路上”。仔細一想解決方案也不是沒有——變非搶佔為搶佔,也就是回合制[手動捂臉]
另外一個設計上不夠優雅的是兵種特色並沒有很好的體現出來

總結

總體來說是一次差強人意的設計嘗試。問題出現了不少,比如說如何處理雙方同時的移動,不僅導致了諸多bug,也暴露出設計上考慮的不周密,不過也還算有意思。

程式設計

這次我負責的主要是地圖管理器、棋子管理器、遊戲互動、AI管理器

遊戲互動

建立棋子:主要是OnDrag的一系列引用。各個PointerEventHandler十分強大,繼承一下介面就可以輕鬆實現拖拽效果。提一個暗坑。一定要記得建立EventSystem……否則可能要花很長時間找不存在的點選失效bug……
操作棋子:細節比較多,各種邊緣情況都要考慮。採用了簡單的有限狀態機的方法。

尋路演算法

這個在上學期unity課的作業時就做過,本來這次打算用估值函式的方法,後來發現是我太天真了,乖乖用回AStar演算法。吸取了上一次經驗,這次把尋路模組從地圖管理器中獨立出一個類,這個類只能被地圖管理器呼叫,保證了模組性。
這個演算法在看似簡單,細節卻不少,在實際使用中有幾個坑點,也是我們卡殼比較久的地方。

  • 尋不到路的情況:如果不存在一條到達目的地的路徑,那麼會導致死迴圈無限呼叫。表現為unity卡死,除錯都找不出來。這個時候返回值需要特別處理,告訴控制器你沒有找到路。這個bug遇到過兩次,有一次表現卡死,另一次則表現為棧溢位。解決時用了冗餘的防錯邏輯,不太優雅。
  • 多個棋子尋路時衝突的情況:這個bug和下面的bug是相輔相成的。不過在某一種情況下不同。那就是如果我方兩個棋子企圖同時到達一個格子,那麼就會有一個先到達,另一個被打斷移動,更換路線。這樣看起來就很不美好,會造成後面一個到達者的重複勞動。結局方案是用了《遊戲人工智慧》中防止多個物體尋路終點接近導致碰撞的機制——每次出發前會告知地圖管理器,這個位置已經被我預定了,切實移動到該位置後解除預定(感覺有點像加鎖解鎖的概念)。
  • 當曾經尋找到的路變為不可走的情況:我們採用了觀察者模式的方法,如果發現下一個路已經無法走(一般是被敵人搶先到達),那麼釋出事件,接收者接收到後返回當前格子位置的正中心。

對戰AI

這一塊是最後兩天衝刺時候的重點。我們的遊戲本質上還是個棋類遊戲,AI必須是基於棋手考慮的而不是棋子。一開始對構造AI的思路一無所知,後來看了《遊戲人工智慧》裡面“功夫圈”模型後頓時茅塞頓開。

功夫圈模型介紹:ACT遊戲中,你會發現如果有多個敵人衝過來,他們會衝到你跟前然後站住。每一時刻發動攻擊的往往只有“被攻擊容量”允許的幾個敵人。比如我被攻擊容量為2,那麼同時只有兩個敵人會來攻擊我,其他人站著看戲。

具體使用:每一個潛在的被攻擊者都有一個“被攻擊容量”的資料結構。這個玩意有點像“訊號量”。當一個攻擊者攻擊被攻擊者時,攻擊者被記錄進“被攻擊容量”中(P操作)。如果“被攻擊容量”已經滿了,AI控制器就判斷這個潛在被攻擊者不值得再投入兵力去打了。但攻擊結束時(根據規則,是一方死亡時)釋放容量(V操作)

選擇攻擊物件的細節:在候選攻擊物件中(還有足夠的“被攻擊容量”的棋子)選擇估值高的物件進行攻擊。估值包括距離、剩餘血量、兵種剋制。

在哪裡放置棋子也需要AI思考。我這樣設計這一部分的邏輯:把戰場劃分成多個區域,根據區域內相對兵力的多寡(多和寡都不傾向放,只有兵力膠著的地方才放)放置棋子。

硬傷

由於死鎖在設計上沒有徹底解決,最後可能會出現我跑到你的位置打你,你跑到我的位置打我的搞笑“跳舞”局面。迫於ddl,最後使得敵人接近我方時強制停止,而後除非再次得到AI控制器的命令攻打我,否則等待我方主動打它並開始回擊。理想狀況下效果其實還不錯,但由於AI控制器採取隨機數指令,可能會導致看戲摸魚的棋子存在。然後後來想想,即時大名鼎鼎的全面戰爭系列也沒能解決士兵摸魚的蠢事發生——那麼就只能採用解決死鎖的最佳方法——裝作死鎖不存在。

另外一個就是沒有放棋子時考慮兵種剋制和相對位置的問題。不過看上去好像影響不大。