zoukankan      html  css  js  c++  java
  • MMORPG大型游戏设计与开发(服务器 游戏场景 核心详述)

    核心这个词来的是多么的高深,可能我们也因为这个字眼望而却步,也就很难去掌握这部分的知识。之所以将核心放在最前面讲解,也可以看出它真的很重要,希望朋友们不会错过这个一直以来让大家不熟悉的知识,同我一起进步。同时在讲解这方面的知识时候,博主也在学习好算法相关的知识,每天进行两个实例的讲解,有兴趣的朋友们不妨了解一下,大家千万不好死记硬背。

     一张截图

    描述

      核心作为重要的地位,就是因为它掌握了最核心的东西:数据,也就是说核心就是数据的处理中心。

    析构方法(construct)

      主要是创建核心对象、基础数据初始化。

      1、网络连接管理器(scene connction manager)

        处理当前场景的玩家连接。

      2、网络连接回收管理器(recycle connction manager)

        玩家网络连接回收,如果玩家连接断开则释放用于空闲连接。

      3、地图(map)

        地图数据,如格子上的数据等。

      4、同步网络包队列(async packet)

        队列让网络数据能够尽量安全、快速。

      5、对象管理器(object manager)

        场景中各种对象,如玩家、怪物、生长的资源等等。

      6、对象初始化管理器(object init manager)

        对象加入场景的时候,对象数据需要初始化,而用于初始化这些数据的管理器就是这个。

      7、人物管理器(human manager)

        主要处理玩家的相关数据。

      8、怪物管理器(monster manager)

        用于处理怪物相关的数据。

      9、宠物管理器(pet manager)

        宠物相关数据的处理。

      10、物品盒管理器(item box manager)

        游戏中的宝箱、掉落包等。

      11、物品对象管理器(item object manager)

        物品对象,一切物品对象数据管理。

      12、操作平台管理器(platform manager)

        特殊的平台数据处理,如物品的制作平台等等。

      13、特殊对象管理器(special manager)

        特殊的对象,如一个特效、陷阱等的管理。

      14、交通工具管理器(bus manager)

        举几个例子:马车、大雕等。

      15、lua脚本接口(lua interface)

        挂接脚本是为了可以频繁的改动的数据。

      16、场景定时器(scene timer)

        场景中的定时处理,如场景公告,特定的场景事件等。

      17、脚本数据管理器(script file data manager)

        脚本的文件数据的管理,一般将所有需要执行的脚本数据加入到内存中,避免再次读取耗费时间。

      18、摊位数据管理器(stall info manager)

        许多游戏都会有摆摊的功能,武侠世界/天龙八部中也有该功能,主要是处理摊位收费的数据。

      19、储存管理器(store manager)

        数据存储,场景的一些特殊数据处理,如城市的数据就需要保存一样。

      20、区域管理器(area manager)

        游戏场景分为若干个区域,区域分开是为了处理特殊的事件。

      21、定时操作管理器(timer doing manager)

        定时操作的一些处理。

      22、坐骑管理器(horse manager)

        坐骑也相当于一个特殊的对象存在场景中。

      23、场景掉落位置管理器(scene drop position manager)

        怪物的死亡往往带有物品的掉落,物品掉落的位置上一般存在相关的数据。

      24、聊天管道(chat pipe)

        场景的聊天专用处理器。

      25、巡逻路径管理器(patrol path manager)

        巡逻,一般用于怪物AI巡逻路径的管理。

      26、网络数据包(packets)

        1. 新的玩家(new player)

        2. 新的玩家移动(new player move)

        3. 新的玩家死亡(new player death)

        4. 新的怪物(new monster)

        5. 新的怪物移动(new monster move)

        6. 新的怪物死亡(new monster death)

        7. 新的宠物(new pet)

        8. 新的宠物移动(new pet move)

        9. 新的宠物死亡(new pet death)

        10. 新的操作平台(new platform)

        11. 新的特殊对象(new special)

        12. 新的物品盒(new item box)

        13. 新的物品对象(new item object)

        14. 删除对象(delete object)

        15. 新的交通工具移动(new bus move)

        16. 新的交通工具(new bus)

        17. 任务数据(mission data)

     数据加载(load)

      地图数据(map)、怪物数据(monster)、操作平台(platform)、生长点数据(grow point)、生长点步骤数据(grow point step)、区域数据(area)、摊位数据(stall info)、交通工具数据(bus)。

    循环逻辑(tick)

      主要负责场景网络数据处理。

    心跳(heart beat)

      1、 场景关闭逻辑

      2、场景定时逻辑

        网络连接管理器心跳、怪物管理器心跳、宠物管理器心跳、交通工具管理器心跳、物品盒管理器心跳、物品对象管理器心跳、特殊对象管理器心跳、聊天通道心跳、定时操作心跳、场景定时器逻辑、网络连接回收心跳。

    消息处理(message handler)

      缓存(cache)、发送(send)、移除(move)、接收(receive)。

    场景关闭(close)

      场景的关闭除了释放创建时的对象以外,还有后来加入的对象,所有的玩家将被移除、所有的数据将被保存。

    算法(排序)

      1、折半插入排序

        折半插入算法与直接插入排序算法一样,通常也用于排序的元素个数较少的情况,果待排序的元素基本有序最好采用直接插入排序算法。与直接插入排序不同的是,折半插入减少了比较次数,但移动元素的复杂度还是没有改变。)

        

    #include <stdio.h>
    #include <stdint.h>
    #include <inttypes.h>
    
    /**
     * 折半插入算法与直接插入排序算法一样,通常也用于排序的元素个数较少的情况,
     * 如果待排序的元素基本有序最好采用直接插入排序算法。
     * (与直接插入排序不同的是,折半插入减少了比较次数,但移动元素的复杂度还是没有改变。)
     */ 
    
    void aprint(int32_t array[], int32_t count);
    
    int32_t main(int32_t argc, char** argv) {
      int32_t array[] = {33, 23, 15, 78, 88, 99, 198, 188, 133, 33};
      int32_t temp;
      int32_t i, j;
      int32_t high, middle, low, count;
      count = sizeof(array) / sizeof(array[0]);
      for (i = 1; i < count; ++i) {
        temp = array[i];
        for (low = 0, high = i - 1; high >= low;) {
          middle = (low + high) / 2;
          temp < array[middle] ? high = middle - 1 : low = middle + 1;
        }
        for (j = i - 1; j >= low; --j) array[j + 1] = array[j];
        array[low] = temp;
        aprint(array, count);
      }
      return 0;
    }
    
    void aprint(int32_t array[], int32_t count) {
      int32_t i;
      for (i = 0; i < count; ++i)
        printf("%4d", array[i]);
      printf("
    ");
    }

      

      2、希尔排序

        希尔排序算法可以使较小的元素很快向前移动,当待排序元素基本有序时,再使用直接插入排序处理,时间效率会高很多。希尔排序主要用在数据量在5000以下并且速度要求不太高的场景。

    #include <stdlib.h>
    #include <inttypes.h>
    #include <stdio.h>
    
    /**
     * 希尔排序算法可以使较小的元素很快向前移动,当待排序元素基本有序时,再使用直接插入排序处理,
     * 时间效率会高很多。希尔排序主要用在数据量在5000以下并且速度要求不太高的场景。
     */
    
    //排序函数,每次调用shellinsert,delta是存放增量的数组
    void shellsort(int32_t array[], int32_t length, int32_t delta[], int32_t m);
    //对数组中的元素进行一趟希尔排序,inc是增量
    void shellinsert(int32_t array[], int32_t length, int32_t inc);
    //数组打印函数
    void displayarray(int32_t array[], int32_t length);
    
    int32_t main(int32_t argc, char *argv[]) {
      //int32_t array[] = {22, 33, 55, 3, 6, 77, 18, 89, 32};
      int32_t array[] = {33, 23, 15, 78, 88, 99, 198, 188, 133, 33};
      int32_t delta[] = {4, 2, 1};
      int32_t m = 3;
      int32_t length = sizeof(array) / sizeof(array[0]);
      shellsort(array, length, delta, m);
      printf("result: ");
      displayarray(array, length);
      return 0;
    }
    
    void shellsort(int32_t array[], int32_t length, int32_t delta[], int32_t m) {
      int32_t i;
      for (i = 0; i < m; ++i) { //进行m次希尔插入排序
        shellinsert(array, length, delta[i]);
        printf("the %d times sort: ", i + 1);
        displayarray(array, length);
      }
    }
    
    void shellinsert(int32_t array[], int32_t length, int32_t inc) {
      int32_t i, j, temp;
      for (i = inc; i < length; ++i) { //将距离为inc的元素作为一个子序进行排序
        if (array[i] < array[i - inc]) { //如果前者小于后者,则需要移动元素
          temp = array[i];
          for (j = i - inc; j >= 0 && temp < array[j]; j = j - inc) 
            array[j + inc] = array[j];
          array[j + inc] = temp;
        }
      }
    }
    
    void displayarray(int32_t array[], int32_t length) {
      int32_t i;
      for (i = 0; i < length; ++i)
        printf("%4d", array[i]);
      printf("
    ");
    }

    总结

      本次讲解的场景只是以理论和武侠世界/天龙八部为原型的一个基础概念,其中有许多不足的地方还需不断的纠正,而且对于最新的大型游戏中有些已经做了较大的改变,我会适当结合最新的大型游戏进行一定的解析。算法作为程序比较重要的部分,我们应该了解一下,但不应该死记硬背。

  • 相关阅读:
    每天一个linux命令(8):scp使用
    C++11 列表初始化
    国外程序员整理的C++资源大全
    fiddler4 使用教程
    C++11 右值引用和转移语义
    数据库炸了——是谁动了我的wait_timeout
    Go组件学习——gorm四步带你搞定DB增删改查
    Go组件学习——cron定时器
    Go语言学习——channel的死锁其实没那么复杂
    Go语言学习——彻底弄懂return和defer的微妙关系
  • 原文地址:https://www.cnblogs.com/lianyue/p/4077967.html
Copyright © 2011-2022 走看看