一 需求
播放回合制,外加插入式手操![]()
erlang戰鬥系統設計 戰鬥大緻流程如下,
1:戰鬥開始前機關S1與S2 稱之為精靈1,2放完增益/減益技能後退場,戰鬥進入循環
2:每個循環中按照站位順序1-12号機關依次釋放技能
3:每個機關都可以手動釋放技能,釋放的技能插入下一個行動之前,比如1号位行動期間,3号位釋放了一個主動技能,那麼1号位行動後會直接播放3号位釋放的技能
4:當一方全部死亡,或者輪數大于一定回合後戰鬥結束
5:戰鬥需要支援多人線上PVP
草草畫了張流程圖
可以看出,這是一個類似卡牌的經典戰鬥模式,接下來我們将一步步實作它,從架構到具體技能填充,滿足策劃的變态需求,等等。。![]()
erlang戰鬥系統設計
二 主體架構
首先明确一點戰鬥需要支援多人線上戰鬥,那麼戰鬥需要由伺服器驅動,
同時必須開啟一個程序來承載雙方的戰鬥,不能将戰鬥挂在玩家程序
那麼到底是啟動gen_server還是gen_fsm?
gen_fsm不熟悉的可以先看一下解釋
A behaviour module for implementing a finite state machine. A generic finite state machine process (gen_fsm) implemented using this module will have a standard set of interface functions and include functionality for tracing and error reporting.
gen_fsm在狀态較多的時候相對于gen_server易于管理
我們分析一下戰鬥的狀态
![]()
erlang戰鬥系統設計 1:perparing 戰前準備狀态,用于調整站位技能等資訊
2:loading 加載界面狀态,多人線上戰鬥時,由于機器/網絡情況不一樣,需要等待所有人加載完畢才開始戰鬥
3:fight 戰鬥狀态,戰鬥進入正常循環
4:fight_over 戰鬥結束處理
我們會有4個大的狀态,以及2個小狀态,使用gen_server會比較難以管理,是以決定用gen_fsm啟動程序
程序大體如下
![]()
erlang戰鬥系統設計 綠色代表gen_fsm的狀态, 藍色字代表每個狀态的事件
gen_fsm大體結構就是這樣
接下來我們需要想一想一場戰鬥需要的資料
首先看一下最終我使用到的結構
![]()
erlang戰鬥系統設計 1:戰鬥類型
2:參與戰鬥玩家清單
3:戰鬥機關狀态
3.1 站位
3.2 機關行動了幾次
3.3 技能清單
3.4 其他根據遊戲不同擁有不同的屬性
4:準備完成玩家清單 發送準備資料後需要等待所有玩家響應傳回
5:加載完成玩家清單 發送加載資料後需要等待所有玩家響應傳回
6:勝利條件
7:第幾輪
8:總體行動了幾次,用于與前端同步
9:目前輪已行動機關清單
10:目前行動已相應的玩家清單
11:釋放的主動技能清單
至此一個初始的戰鬥程序被拉起來
三 與前端通信
與前端通信的關鍵是如何實作插入式的技能釋放,即将上一次行動中釋放的技能在下一次行動播放
我們使用了,每一次行動通信一次的做法,用戶端每一次的行動都由伺服器通知,
當用戶端播放完成接收到的行動後,通知伺服器,當所有玩家都傳回通知後伺服器再發送下一次行動
![]()
erlang戰鬥系統設計 如圖,伺服器會不斷比較下一次行動的資料,等到所有人相應後推送給前端展示,
發送的行動可能是順序播放的技能,也可能是玩家主動釋放的技能
當多個玩家同時在上一次行動釋放技能,則按順序發出