3.1 游戏登录模块的开发
游戏启动后,显示的第一个界面就是登录界面。它主要实现两大功能:
□ 通过“换区”按钮切换到服务区界面,显示服务区列表。
□ 通过“开始游戏”按钮切换到组队界面进行队伍匹配。由于本书讲解的是简易版的游戏流程的搭建,所以去掉了游戏大厅的过程,直接通过开始游戏后进行队伍匹配。如图3-1所示,是游戏主场景需要完成的功能逻辑。在这一部分中主要介绍如何通过按钮执行事件、如何更新界面,以及网络的概念。
图3-1
组队界面可以切换到匹配界面,同样可以从匹配界面返回组队界面,其切换过程涉及网络通信,是通过服务器来控制的。流程如下:客户端通过开始匹配向服务器端发送消息,服务器端处理之后返回结果,客户端根据返回的结果来进行切换。目的就是通知服务器端,此时客户端的状态。取消匹配流程如下:当匹配满员后,服务器端通知客户端切换到选择界面,并将选择界面中所有的数据返回客户端,等待处理。在此部分中介绍文本的更新、简单的消息处理过程以及监听器的使用。
队伍满员后,切换到选择界面。选择界面负责玩家英雄的选择。需要显示可选的英雄列表。因每个玩家所拥有的英雄不同,所以英雄列表的加载不是简单地将所有的资源加载出来,而是通过读取服务器端返回的消息数据选择性地加载。当玩家选择某一英雄后,可通过“确定”按钮进入战斗场景。至此战斗开始。
在主场景逻辑开发时,会利用部分框架中的内容,为了使读者的学习更轻松,首先来介绍一些相关的知识点,并通过一个范例来演示。
事件机制,顾名思义就是传递事件的机制。软件开发中常用消息通知、接收的处理方式来驱动逻辑运行,可以大大降低模块之间的耦合度,使软件设计和代码实现的过程更加灵活、独立和简单。同时也不需要关注太多模块外的关联性。在游戏中通常会有大量的事件产生,因此需要注册相应的事件处理器。那么事件又是如何注册与执行的呢?这些都需要消息管理中心来处理。消息机制的原理很简单:事件由事件源达到某触发条件时发出,事件管理中心接收并广播给注册了该事件的所有接收者。具体实现的内部原理可以参考框架部分源代码,下面只介绍框架中提供功能的使用方法。
3.1.1 事件定义
想要执行某一个函数,需要给这个函数一个标识符,这样可以通过标识符找到这个函数。标识符就是接下来要介绍的事件ID。注册时,利用事件ID与事件对应的处理方法进行绑定;广播时根据事件ID来寻找与之绑定的方法。游戏中有很多事件,作为每个事件的标识符,可以把游戏中所有的事件集中在一起。
新建一个脚本,命名为UserEventEnum,双击打开。将UserEventEnum改为枚举,并创建第一个枚举类型UserEvent_NotifyBase。为了防止与框架中枚举值冲突,第一个枚举类型的值可以衔接框架中的最后一个值,代码如下所示。
在添加事件时,事件名称可以类似于UserEvent_NotifyBase样式,以逗号结尾。命名时要有意义,使开发者很容易辨别此事件的目的。这样就添加了一个消息ID。
小知识
快速定位到某个函数或者类的位置:鼠标定位在相应单词上,按F12键可以快速切换到对应的函数或者类中。
3.1.2 事件注册
事件ID作为标识符用来表示不同事件类型。EventCenter提供了绑定事件的处理函数AddListener。AddListener的作用是在EventCenter中将事件ID与处理函数绑定在一起,类似字典中的键值对,对应的值是处理函数列表。事件处理函数在注册时,被添加到处理列表中,最终会和对应的事件形成一对一、一对多的映射关系,代码如下所示(当事件被触发时,可以直接通过这个事件映射到对应的函数列表,顺序调用列表中的函数。AddListener中的模板参数是根据事件函数的参数类型而确定的)。
那么在哪里注册消息呢?有一点是肯定的,那就是在广播消息之前。接下来介绍事件广播。
3.1.3 事件广播
事件注册完成之后,如果想要调用此事件该如何做呢?可以通过EventCenter中的BroadCast调用来完成,此函数的实质就是去执行方法。为消息ID注册了事件后,根据具体逻辑调用对应函数。使用方式如下所示。
3.1.4 使用范例
上面已经了解了事件机制的实现原理,游戏中可以利用框架中的事件机制来实现驱动逻辑,进一步巩固学习的内容。下面来做一个测试程序。
Step 01 打开UserEventEnum脚本。在此脚本的末尾定义两个消息,代码如下所示。
Step 02 重新创建一个脚本MainTest,在Start初始函数中添加两个监听器,代码如下所示(这两个监听器一个是带参数的,一个是不带参数的。此处以无参数的监听器为例,另外一个可以给读者参考。在为消息添加监听器时,消息直接通过UserEventEnum找到自己定义的消息。Test1表示事件函数)。
Step 03 定义事件处理函数Test1和Test2,每个函数中输出一句话或者变量。代码如下所示。
Step 04 在Update函数中进行广播,这里利用了一个计时器,代码如下所示(当游戏运行后,每5秒就会广播事件。事件的参数是第一步所定义的事件ID)。
Step 05 将MainTest脚本挂载到场景中的Camera对象上,单击运行。5秒钟后,如图3-2所示,控制台中输出了执行函数中打印的内容。由此证明该事件在消息广播时被调用。
图3-2