《炉石传说》架构设计赏析(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类体系也需要进一步分析。
时间: 2024-10-04 09:17:21

《炉石传说》架构设计赏析(3):Gameplay初探的相关文章

炉石传说 C# 设计文档(序)

经过3个月的开发,有很多感触. 以前一直以为技术是开发成败的第一因素,现在发现,等到你代码写的时间够长,经验够丰富,什么功能都能随手完成,对于业务的分析能力变成了第一位. 炉石山寨版的BS版本用到的HTML5的SVG,我看了一个下午的教程,借鉴以前GUI+和HTML的经验,很快就能写点东西出来了. WebSocket,Github上找了一个开源的C#项目,通讯这块也是几个小时就搞定了.Javascript不是很熟悉,当时闭包这样的一些概念也算听说过,Js也是无障碍就写成了. 整个项目的技术壁垒其

《炉石传说》架构设计赏析(4):Asset管理

欢迎转载,请注明作者[燕良@游戏开发]及原文地址:http://blog.csdn.net/neil3d/article/details/39580197 另外,欢迎大家来我的QQ群交流各种游戏引擎相关的技术:游戏引擎能吃吗(264656505) 话说,经过这段时间的学习和摸索,对于Unity3D的开发思路已经基本清晰了.唯独还剩下一个AssetBundle机制还没有搞透,这个涉及到前期项目的资源规划.资源管理代码的写法,以及自动更新机制的实现. 所以,还是想先把游戏逻辑的进一步分析押后,先来看

《炉石传说》架构设计赏析(1):游戏启动流程

前些天看新闻,Unity Awards两项大奖颁给了暴雪的<炉石传说>,这真是对Unity一个再好不过的宣传了--你看,暴雪都开始用Unity了.大家都知道,目前Unity发布的游戏大多都没有对程序集进行混淆.加密,所以作为一个炉石的玩家&Unity的初学者,自然不能错过这个机会.让我们好好看一下暴雪的代码吧. 炉石传说的游戏内容的非常丰富多彩,所以我花了一些时间分析了其程序集,将一些设计思路记录下来,与大家分析.欢迎各路高手拍砖,欢迎转载,请注明出处:燕良@游戏开发,http://b

《炉石传说》架构设计赏析(6):卡牌&amp;技能数据的运行时组织

前一篇文章我们看到了<炉石传说>的核心卡牌数据的存储,今天我们继续探索卡牌&技能. 主要的类 通过之前的分析,卡牌&技能涉及到几个类体系:Entity,Actor,Card,Spell,令人十分困惑,特别是前两者.在这里先略带武断的说一下这几个类的基本定位: Entity主要用来做网络数据同步用的: Actor主要处理客户端的渲染对象的控制,作为Component挂载在资源对象上: Spell是技能Prefab挂载的脚本: Card是卡牌Prefab挂载的脚本,在运行时处于中心

《炉石传说》架构设计赏析(2):Scene管理

上篇文章我们分析到SceneMgr处理了Scene的加载工作,今天我们主要分析一下炉石这款游戏中一共有哪些Scene,他们各自负责什么,以及它内部的逻辑.UI的处理方式. 在正式开始之前,我来对前文中提到的Scene切换再做一些补充分析.前文中我们看到SceneMgr是调用了" Application.LoadLevelAdditiveAsync(this.sceneName);",那内存中的东西岂不是越搞越多吗?我们再仔细看一下SceneMgr:SwitchMode()函数,它是一个

《炉石传说》架构设计赏析(7):使用Google.ProtocolBuffers处理网络消息

这段时间琢磨了一下Unity3D网络游戏开发中的网络消息处理.网络游戏的服务端一般都是自主开发的,所以对应的网络消息处理也要自己开发.客户端/服务端之间的消息传到目前使用JSON和Google.ProtocolBuffers是两种常见的做法.打开炉石的代码看了看它的处理方式,感觉代码写的还是很好的,把它的思路分析一下,与大家分享. 整体机制描述 我们想要达到的目标大概是这样的: 有N个网络消息,每个消息对应一个Proto中的message描述: 每个消息对应一个数字ID: 底层在收到消息是,将其

《炉石传说》架构设计赏析(5):卡牌&amp;技能的静态数据组织

经过前面几次的尝试,我们对炉石的代码已经不陌生了.除了网络机制还没有了解以外,本机的逻辑已经比较熟悉了. 接下来继续向暴雪最NB的技能系统进发,我们的目标是: 分析技能的静态数据描述: 分析技能的运行时数据.逻辑组织: 这篇笔记主要记录对其分析静态数据. 静态数据组织 卡牌数据 卡牌的基本数据对于的AssetFamily为:AssetFamily.CardXML: 数据对于的资源包为"cardxml0.unity3d": 资源包中的资源类型为:TextAsset: 资源加载使用的接口为

大型网站架构设计方向初探

一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构.性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对于大型网站来说,所采用的技术更是涉及面非常广,从硬件到软件.编程语言.数据库.WebServer.防火墙等各个领域都有了很高的要求,已经不是原来简单的html静态网站所能比拟的. 大型网站,比如门户网站.在面对大量用户访问.高并发请求方面,

炉石传说 C# 开发笔记(6月底小结)

炉石传说的开发,已经有30个工作日了. 关于法术的定义方法,有过一次重大的变更:法术效果是整个炉石的核心,正是因为丰富的法术效果,才造就了炉石的可玩性. 原来构思的时候,对于法术效果没有充分的理解,所以只将效果数据做成了常数,例如 造成5点伤害. 随着更加深入的解除,发现还有 毁掉你的武器,对所有随从造成武器攻击力的伤害,这样的话,效果是一个 表达式. 然后考虑到,有些追加效果,例如,对某个随从造成2点伤害,如果这个随从没有死,则抽一张牌, 这里就牵涉到了根据条件追加效果的处理. 同时,德鲁伊的