zoukankan      html  css  js  c++  java
  • 游戏服务端之数据加载

    软件要运转,都会涉及到数据,而使用数据都会涉及到数据加载到内存的过程。 在游戏中也同样存在数据加载的逻辑。

    数据分类

    我们把游戏中数据按照类型分为了4种:
    1.基本数据:游戏依赖的基本数据,由数值配置,在游戏运行过程中不会改变其数据
    2.动态数据:主要是活动等数据,由运营在gm后台配置并且刷新到游戏内使生效,在游戏过程中,代码不会改变其数据
    3.全局数据:游戏内的全局数据(比如排行榜),由程序自动生成相关数据,游戏过程会改变数据
    4.玩家数据:游戏内玩家自身相关的数据(依附于玩家自身),由程序自动生成相关数据,游戏过程会改变数据
    参考下图:


    数据加载顺序

    根据上面的数据分类,我们可以推断出数据的依赖关系(箭头指向代表依赖关系):


    所以在游戏启动过程中,我们加载数据的顺序是:基本数据 > 动态数据 > 全局数据 > 玩家数据

    数据的加载实现

    (今天的文章不涉及玩家的数据加载,因为我们玩家数据做了懒加载的)

    在游戏中,每种数据类型都有很多配置表(可以是excel,mysql中的表,或者其他形式的),为了简化加载方法,也为了框架统一处理,我们为每种数据类型定义了自己的接口,只要对应的模块实现对应的接口,框架就能自动发现和加载,下面就以基本数据为例分享下我们的实现方式。

    1.定义基本数据的接口,比如叫:IModel

    /// <summary>
    /// 模型数据接口
    /// </summary>
    public interface IModels
    {
        /// <summary>
        /// 初始化模型数据
        /// </summary>
        void Init();
    }

    2.定义实现了该接口的数据类

    public class SystemConfigBLL : IModels
    {
        private static SystemConfig config = null;
    
        public void Init()
        {
            //演示加载,具体实现的时候可以按照具体的加载
            config = new SystemConfig();
            config.FightUrl = "http://www.baidu.com";
    
            //其他处理
    
            Console.WriteLine("加载了SystemConfig相关配置");
        }
    
        /// <summary>
        /// 获取相关信息
        /// </summary>
        public static SystemConfig GetData()
        {
            return config;
        }
    }
    
    public class SystemConfig
    {
        public string FightUrl { get; set; }
    }

    3.游戏初始化的时候自动触发init方法,这里我们使用反射来触发(因为只在初始化的时候调用一次,所以性能上可以接受)

    /// <summary>
    /// 初始化Model数据
    /// </summary>
    public static void InitModel()
    {
        // 初始化其它配置,获取实现了IModels接口的类
        List<Type> typeList = GetTypeListOfImplementedInterface(typeof(IModels));
        foreach (Type type in typeList)
        {
            // 使用接口来生成对象
            IModels model = type.Assembly.CreateInstance(type.FullName) as IModels;
            model.Init();
        }
    }
    
    /// <summary>
    /// 获取实现了接口的类型列表
    /// </summary>
    /// <param name="interfaceTypes">接口类型集合</param>
    /// <returns></returns>
    public static List<Type> GetTypeListOfImplementedInterface(params Type[] interfaceTypes)
    {
        List<Type> typeList = new List<Type>();
    
        //获取整个应用程序集的类型数组
        Type[] types = Assembly.GetExecutingAssembly().GetTypes();
        if (types == null || types.Length == 0) return typeList;
    
        //遍历每一个类型,看看是否实现了指定的接口
        foreach (Type type in types)
        {
            //获得此类型所实现的所有接口列表
            Type[] allInterfaces = type.GetInterfaces();
    
            //判断给出的接口类型列表是否存在于实现的所有接口列表中
            if (interfaceTypes.All(item => allInterfaces.Contains(item)))
            {
                typeList.Add(type);
            }
        }
    
        return typeList;
    }
    
    static void Main(string[] args)
    {
        InitModel();
    
        Console.WriteLine("FightUrl:" + SystemConfigBLL.GetData().FightUrl);
        Console.ReadKey();
    }

    运行后的效果如下:


    以上我们完成了一个简单的基本数据的加载,同样的方式实现其他基本数据的加载即可

    同理可以推断到动态数据,全局数据,希望以上思路可以给大家起到一定的抛砖引玉的作用。有任何问题欢迎留言讨论,感谢~请轻拍

    作者:守望
    QQ:497886344    微信: yellowgiutou
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    golang并发
    golang接口
    golang方法
    golang函数
    微信小程序请求封装
    使用vue实现打印功能时出现多余空白页的问题
    mybatis 基本配置
    sql调优
    触发器 索引
    收藏 故事形式讲解javaScript中创建对象和Java创建对象的区别
  • 原文地址:https://www.cnblogs.com/yellowgiutou/p/12891711.html
Copyright © 2011-2022 走看看