AlayaElla

新ip才换了一天就被墙了。。再次换新的。。

笔记:游戏事件管理器的实现

前言:

之前自己的游戏中需要有一些完成特定条件然后触发剧情的设计在里面,所以做了一个事件管理器来实现这个功能。
因为我是第一次做这种功能所以在这里记录一下实现思路。

这种游戏全局的事件判断肯定以后在很多地方都会用,比如:成就系统、任务系统(之后马上就要着手做这个功能..)等等。

需求:

首先整理下思路,说下需求吧。
1、使用配置表。
2、有事件道具的概念,即必须拿到特定道具才能触发事件。
3、各种事件触发的条件。。总之就是后面好添加。
4、事件没有完成时,可以下次继续。

实现思路:

好吧,基本需求就是上面那些了。
然后开始整理一下思路。
首先我需要一个读取配置表的方法,这个可以和以前读取配置表的方法放在一起。
然后,读取配置表后需要一个事件管理器来判断是否触发事件,这个事件管理器可以在任何时候调用判断方法。
同时还需要储存事件的条件数据,来给事件管理器判断。即触发事件的各种数据需要记录,用于给事件管理判断是否触发。
最后每一个事件还需要一个状态来表示是否完成,如果没有完成,则在下次进入游戏时会自动播放。(这个同样说明了事件管理器需要可以在任何时候调用。)

大致思路思路大概是这样,不过单是文字描述还是不太直观。所以可以参考下下面的图。
evnet

之后记录下每个脚本的基本内容和功能。

EventManger(事件管理器):

单例模式,可以全局调用。
1、事件类型结构体:
用来声明事件的类型,事件的状态,还有时间的参数和配置表中的参数对应。
可以触发事件为:
pic2

public struct ChatEvent
    {
        public int ID;
                //事件的类型,可以任意添加
        public enum EventTypeList {
            PutGoods=0,         //上架物品
            SellGoods,          //售出物品
            ComposeGoods,       //合成物品
            CollectGoods,       //采集物品
            ComposeProperty,    //合成属性
            InShop,             //进入商店界面
            InMap,              //进入地图界面
            Arrive,         //到达路点
            Mines,              //挖掘次数
            Golds               //金币数
        };
        public EventTypeList EventType; 
        public int Num;                  //触发条件1:事件触发所需的次数
        public int[] Parameter;       //触发条件2:可任意填写,现在表示物品类型和物品ID。
        public int[] EventItem;       //触发条件3:所需要的关键道具
        public string StoryName;  //触发事件后,执行对应的剧情名称。
    }

        //另外位置定义事件的状态:未完成、进行中、已完成三个状态

2、触发事件列表:

ArrayList StoryList;

触发事件后,吧触发的事件存进这个列表,之后故事管理器就根据这个列表来播放对应的故事。
StoryList主要是用来对应同时触发多个事件时,可以依次播放的而加的。
同时有些时候可能触发事件但是不会马上播放剧情,所以StoryList还是必要的。
不过如果没有这些需求的话也可以不要StroyList就是了。

3、事件判断方法

public bool CheckEventList(ChatEvent.EventTypeList EventType,bool ClearStoryList)

事件管理器的主要方法。
使用Switch语句还区分不同的事件类型,这样也方便后续添加更多。遍历事件列表来对比角色事件数据来判断事件是否触发。(遍历是需要排除已经完成的事件)
触发事件后返回一个布尔值。如果触发了事件则返回TRUE,然后调用的地方可以根据返回值来决定是否直接播放剧情。
当然也可以先暂时不触发。

PS:我在遍历之前先筛选了下必要的列表,所以多了一个EventType的参数。

4、读取角色数据方法
直接获取从PlayerInfo中获取即可。

5、读取事件配置表
先由XmlLoader读取配置表,然后从XmlLoader中获取即可。

PlayerInfo(角色数据)

这是个记录角色数据的脚本。
包含了保存角色数据、读取角色数据以及更新角色数据。
角色数据为以下几个:
1、进入特定地点次数:
记录每个地点的进去次数。
2、累计金币获得数。
就是一个值,一直累计,放置溢出做一个最大限制即可。
3、累计采集数。
同上。
4、物品信息:
记录每一个物品的,合成、采集、上架还有贩卖次数。
5、物品属性信息:
记录每个物品属性的合成次数。
6、进入界面次数:
记录每个游戏界面的进去次数。

为了能够使事件判断的方法起作用,在游戏最开始需要初始化游戏数据。
这个脚本本身并没有什么说的,只要保证和事件判断的方法匹配即可。
同时记录的数据可以很多其他用途,比如图鉴什么的。

XmlLoader(配置表读取工具)

Xml读取的方法可以不用说了。
这里只是说明下Xml的格式。其实正常来说什么格式都可以,选择一个自己感觉方便的就行。
我使用的Xml格式如下:

<ChatEventList>
    <ChatEvent ID="1" EventType="PutGoods" Num="3" Parameter="0,1" StoryName="start"/>
    <ChatEvent ID="2" EventType="SellGoods" Num="3" Parameter="0,3" StoryName="shop1_1"/>
    <ChatEvent ID="3" EventType="ComposeGoods" Num="4" StoryName="shop1_1"/>
    <ChatEvent ID="4" EventType="CollectGoods" Num="5" Parameter="0,3" StoryName="shop1_2"/>
    <ChatEvent ID="5" EventType="ComposeProperty" Num="2" Parameter="1" StoryName="start"/>
    <ChatEvent ID="6" EventType="InShop" Num="4" StoryName="shop1_2"/>
    <ChatEvent ID="7" EventType="InMap" Num="10" StoryName="shop1_1"/>
    <ChatEvent ID="8" EventType="Arrive" Num="5" Parameter="7" EventItem="2,2" StoryName="shop1_1"/>
    <ChatEvent ID="9" EventType="Mines" Num="10" StoryName="start"/>
    <ChatEvent ID="10" EventType="Golds" Num="100" StoryName="gold1_1"/>
</ChatEventList>

每个配置字段和事件管理器中得参数对应,同时也可以不用填写,按照事件类型所需的参数匹配即可。

调用:

首先获取到事件管理器的单例,然后在需要判断事件的脚本位置调用事件管理器的判断方法就可以实现事件判断了。
最后根据事件的返回值播放执行播放剧情的方法。

            //检测触发事件
            if (eventmanager.CheckEventList(ChatEventManager.ChatEvent.EventTypeList.Arrive, true))
            {
                            //开始播放剧情
                eventmanager.StartStory();
            }

当然也可以不用播放剧情,反正在需要播放的剧情字段一直保存在StoryList中,之后再需要播放的时候执行播放剧情的也是可以的。

以上是现在实现的事件管理器的所有思路。
因为是第一次做这个功能,可能有不太好的地方,欢迎指正。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注