MMORPG大型遊戲設計與開發(服務器 遊戲場景 聊天管道和尋路器)

 

又快到雙十一,又是很多同仁們出血的日子,首先但願你們玩的開心。我曾經想要仔細的剖析場景的的每一個組件,就像這裏的聊天管道與尋路器,可是仔細閱讀別人代碼的時候才發現元件雖小可是實現並不簡單,由於有些東西尚未徹底想明白我就暫時不說其具體的實現過程,可是我會保證這些文章在後面會不斷更新,同時也但願對這方面有興趣和經驗的朋友們可以指正。聊天這個咱們都知道,由於它幾乎成了遊戲或是生活中不可或缺的一部分,那麼什麼是尋路器?我想未必你們都知道什麼是尋路器,不過我能夠告訴你們的是你在遊戲中自動尋路這個功能就是由該組件實現的。算法

一張截圖

聊天管道

  一、聊天數據

typedef struct chatitem_struct {
  packet::Base *packet; //網絡包指針
  int32_t sourceid; //發起者ID
  int32_t destid; //目標ID,隊聊、場景聊、私聊、系統、自建聊天頻道時目的對象ID。
} chatitem_t; //聊天單個數據

  二、對象組成

    1. 初始化(init)

      初始化場景指針,分配聊天數據數組。數組

    2. 心跳(heart beat)

      心跳主要處理不一樣類型的聊天數據的分發。網絡

    3. 消息發送(send packet)

      發送聊天數據包數據,並設置源ID和目標ID。函數

    4. 消息接收(recv packet)

      對應消息發送,讀取網絡數據包數據,讀取源ID和目標ID。spa

尋路器

  一、尋路數據

    1. 地圖數據

      地圖點的數據。3d

    2. 導航圖數據

      大地圖的數據,通常是地圖尋路時須要打開的地圖,須要提供其長寬的數據,如遊戲截圖中最上層的面板。指針

    3. 格子的數據

      場景中對象的存在通常是以格子做爲單位,玩家角色也不例外。code

    4. 尋路點的數據

      起始位置的X和Z座標數據,目的位置的X和Z座標數據。節點數據、尋路步奏數據等等。對象

  二、對象實現

    1. 析構函數(construct)

      初始化當前的地圖數據,以當前位置讀取正確的座標信息,並初始化尋路器數據對象。blog

    2. 數據重置(reset)

      重置開始的位置信息和結束的位置信息。

    3. 路徑查找(find path)

      根據開始和結束位置信息,以及場景全部節點位置數據,並將所需尋路的節點數量保存到指定的指針中。

    4. 路由打包(route pack)

      打包AI所需通過的位置數據(注意玩家自身也有AI概念)。

    5. 是否可到達(is can go)

      該方法傳入一個位置信息,返回是否能夠到達該點,用在尋路時的判斷,如不可達則不會去查詢和生成尋路的數據。

算法(線性查找)

  一、順序查找

    序查找實現簡單,可是效率低,主要用在數據量不大以及效率要求不高的狀況。

    序查找能夠利用順序結構實現也能夠利用鏈式結構實現。

    code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

/**
 * 順序查找實現簡單,可是效率低,主要用在數據量不大以及效率要求不高的狀況。
 * 順序查找能夠利用順序結構實現也能夠利用鏈式結構實現。
 */

#define SIZEMAX 100

typedef struct table_struct {
  int32_t list[SIZEMAX];
  int32_t length;
} table_t;

//順序查找,在順序表中查找x,若是找到則返回元素在該表中的位置,不然返回0
int32_t seqsearch(table_t table, int32_t x);
//數組打印
int32_t displayarray(int32_t array[], int32_t length);

int32_t main(int32_t argc, char *argv[]) {
  table_t table = {{35, 33, 23, 67, 88, 99, 123, 232, 111}, 9};
  int32_t i, position, x;
  printf("array members: ");
  displayarray(table.list, table.length);
  printf("please enter you want search member: ");
  scanf("%d", &x);
  position = seqsearch(table, x);
  if (position) {
    printf("member %d in array position is %d\n", x, position);
  } else {
    printf("member %d not find in array\n", x);
  }
  return 0;
}

int32_t seqsearch(table_t table, int32_t x) {
  int32_t i = 0;
  while (i < table.length && table.list[i] != x) ++i;
  if (table.list[i] == x) {
    return i + 1;
  }
  return 0;
}

int32_t displayarray(int32_t array[], int32_t length) {
  int32_t i;
  for (i = 0; i < length; ++i)
    printf("%4d", array[i]);
  printf("\n");
}

    result.

  二、折半查找(二分查找)

    折半查找又能夠稱做二分查找(原理和前面的折半插入排序同樣)。

    的效率雖然高於順序查找的效率,可是它查找的序列必須是一個有序序列。

    code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

/**
 * 折半查找又能夠稱做二分查找
 * 它的效率雖然高於順序查找的效率,可是它查找的序列必須是一個有序序列。
 */
#define SIZEMAX 100

typedef struct table_struct {
  int32_t list[SIZEMAX];
  int32_t length;
} table_t;

//在表中查找x,若是元素存在則返回元素所在位置,不然返回0
int32_t binarysearch(table_t table, int32_t x);
//數組打印
void displayarray(int32_t array[], int32_t length);

int32_t main(int32_t argc, char *argv[]) {
  table_t table = {{12, 23, 35, 36, 56, 78, 86, 89, 91}, 9};
  int32_t i, position, x;
  printf("table list: ");
  displayarray(table.list, table.length);
  printf("please input a member you want search: ");
  scanf("%d", &x);
  position = binarysearch(table, x);
  if (position) {
    printf("member %d is in array position: %d\n", x, position);
  } else {
    printf("%d is not find in array\n", x);
  }
  return 0;
}

int32_t binarysearch(table_t table, int32_t x) {
  int32_t low, high, middle;
  low = 0, high = table.length - 1; //設置待查找元素的下界和上界
  while (low <= high) {
    middle = (low + high) / 2;
    if (table.list[middle] == x) //若是找到元素,則返回該元素所在位置
      return middle + 1;
    else if (table.list[middle] < x) //若是middle所在元素小於查找元素則向右移動low的位置
      low = middle + 1;
    else if (table.list[middle] > x) //若是middle所在元素大於查找元素則向左移動high的位置
      high = middle - 1;
  }
  return 0;
}

void displayarray(int32_t array[], int32_t length) {
  int32_t i;
  for (i = 0; i < length; ++i)
    printf("%4d", array[i]);
  printf("\n");
}

    result.

  三、分塊查找

    分塊查找的索引表由主表和索引表構成,主表中的元素不必定有序,索引表中的元素必定有序。待查的元素序列比較多時,利用該算法能夠快速肯定待查找元素的大致位置,減小了比較次數。

    code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

/**
 * 分塊查找的索引表由主表和索引表構成,主表中的元素不必定有序,索引表中的元素必定
 * 有序。
 * 當待查的元素序列比較多時,利用該算法能夠快速肯定待查找元素的大致位置,減小了比較次數。
 */
#define SIZEMAX 100
#define INDEXSIZE_MAX 20

typedef struct table_struct {
  int32_t list[SIZEMAX];
  int32_t length;
} table_t; //順序表

typedef struct indextable_struct {
  int32_t maxvalue;
  int32_t index;
} indextable_t[INDEXSIZE_MAX]; //索引表

//在主表table中查找x元素,indextable爲索引表,若是找到則返回位置不然返回0
int32_t seqindex_search(table_t table, 
                        indextable_t indextable, 
                        int32_t m, 
                        int32_t x);
//數組打印
void displayarray(int32_t array[], int32_t length);

int32_t main(int32_t argc, char *argv[]) {
  table_t table = {{8, 13, 25, 19, 22, 29, 46, 38, 30, 35, 
                    50, 60, 49, 57, 55, 65, 70, 89, 92, 70}, 20};
  indextable_t indextable = {{25, 0}, {46, 5}, {60, 10}, {92, 15}};
  int32_t x, position, i;
  printf("index table max value: \n");
  for (i = 0; i < 4; ++i)
    printf("%3d", indextable[i].maxvalue);
  printf("\nlist array members: \n");
  displayarray(table.list, table.length);
  printf("input a number you want search: ");
  scanf("%d", &x);
  position = seqindex_search(table, indextable, 4, x);
  if (position) {
    printf("%d is a member of array, position: %d\n", x, position);
  } else {
    printf("%d is not a member of array\n");
  }
  return 0;
}

int32_t seqindex_search(table_t table, 
                        indextable_t indextable, 
                        int32_t m, 
                        int32_t x) {
  int32_t i, j;
  int32_t b1;
  for (i = 0; i < m; ++i) { //經過索引表肯定要查找元素在主表中的單元
    if (indextable[i].maxvalue >= x) break;
  }
  if (i >= m) return 0; //若是查找元素再也不表table中,返回
  j = indextable[i].index; //從第i個單元序號j開始查找元素x
  if (i < m - 1) { //b1爲第j單元的長度
    b1 = indextable[i + 1].index - indextable[i].index;
  } else {
    b1 = table.length - indextable[i].index;
  }
  while (j < indextable[i].index + b1) {
    if (table.list[j] == x) { //找到
      return j + 1;
    }
    ++j;
  }
  return 0;
}

void displayarray(int32_t array[], int32_t length) {
  int32_t i;
  for (i = 0; i < length; ++i)
    printf("%4d", array[i]);
  printf("\n");
}

    result.

相關文章
相關標籤/搜索