1. 程式人生 > >《爐石傳說》架構設計賞析(3):Gameplay初探

《爐石傳說》架構設計賞析(3):Gameplay初探


經過前面兩篇文章的分析,我們對爐石的程式碼已經不陌生了,接下來我初步嘗試分析其遊戲邏輯程式碼。
歡迎轉載,請註明作者【燕良@遊戲開發】及原文地址:http://blog.csdn.net/neil3d/article/details/39453291

經過前面的分析,我們已經找到了兩個關鍵的類Gameplay和GameState(當然還有我最感興趣的Spell和SpellController,這兩個還要在後面分析)。

首先我們看一下Gameplay這個類的Awake方法,它完成的主要工作是:

  1. 呼叫“ GameState.Initialize()”建立一個新的GameState例項;
  2. 註冊CreateGame事件:在Gameplay.OnCreateGame()中響應,主要是
    • 初始化卡背;(本地玩家和遠端玩家的卡背ID都通過Player類來讀取);
    • 啟動一個Coroutine:NotifyPlayersOfBoardLoad,它做的主要工作是
      • 等待BoardStandardGame物件載入完成;
      • 然後呼叫所有Player的OnBoardLoaded(),它的主要工作是初始化法力水晶相關的管理邏輯;
  3. 使用AssetLoader載入AttackSpellController、SecretSpellController、TurnStartManager等;
    這些類看上去都很重要,我們後續分析遊戲邏輯時肯定用得到。
接下來我們要看一下Gameplay.Start()方法,它主要是註冊了一些自己關心的網路訊息,然後呼叫
  1. Network.StartCountdown()——傳送網路訊息“BeginPlaying”;
  2. Network.GetGameState()——傳送網路訊息“GetGameState”;
我們在看一下Gameplay.Update(),裡面似乎正常情況只是呼叫GameState.Update()。 OK,以上就是從MonoBehavior繼承來的三個被自動呼叫的函式。對於遊戲邏輯來說,還是沒有什麼頭緒。
再往下分析,遇到的一個最大的困難是很多操作應該是通過網路互動完成的,例如【認輸】操作,分析它是從GameMenu.ConcedeButtonPressed()開始的,一直呼叫到ConnectAPI.Concede()向伺服器發了一個GiveUp訊息,但是無法確定它對應的伺服器返回訊息是什麼。

接下來我們先分析一下游戲的回合的流轉,還是先看一下相關的類圖:

回合結束是由玩家點選右側的【End Trun】操作來觸發的,其對應的程式碼為:InputManager.DoEndTurnButton(),這個函式的邏輯有些費解,目前只能是猜測如下:
  • 首先判斷當前是否允許訪問GameState的OptionsPacket,以及EndTurnButton是否可以操作;
  • 然後根據GameState.GetResponseMode()來分兩種情況處理:
    • GameState.ResponseMode.OPTION——初步猜測為遊戲回合中的正常操作:
      從GameState中取出所有的Network.Options,然後遍歷,找到“OptionType.END_TURN”或者OptionType.PASS的物件,然後呼叫GameState.SetSelectedOption(i);GameState.SendOption();
    • GameState.ResponseMode.CHOICE——初步猜測為遊戲回合開始時,選擇初始手牌的相關操作;
伺服器端的行為就比較難以猜測了,只能等到客戶端行為分析比較完整時再說了。 伺服器端相關的返回大致是這樣的,在Gameplay的Start中有這樣一句:
network.RegisterNetHandler(Network.PacketID.ALL_OPTIONS, new Network.NetHandler(this.OnAllOptions));
想象中客戶端使用Gameplay.OnAllOptions()處理網路層接收到的所有玩家操作,此函式主要是將Network.GetOptions()取出的資料傳送到GameState.OnAllOptions()去處理,後者主要會觸發事件GameState.FireOptionsReceivedEvent()。 我們通過對應的GameState.RegisterOptionsReceivedListener()成員函式,可以分析一下哪些物件會響應此事件。找到EndTurnButton.OnOptionsReceived()。
這階段的分析難度越來越大了,這次分析算是有小小的收穫,但是整個回合流轉的流程還沒有清晰。總結如下:
  • 玩家的操作是在InputManager中處理的,重點的成員函式包括DoNetworkResponse()、DoEndTurnButton();
  • 玩家的操作和網路傳送來的操作都儲存在GameState.m_options中;
  • 其中有另外一個Entity類體系也需要進一步分析。