MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

时间:2021-07-10 10:18:19

地图的数据以及区域的信息是场景的重要组成部分,这些数据同时存在客户端和服务器,而且都是由编辑器生成的。那么保存的文件数据结构是怎样的?一张3D的场景地图又是怎样处理这些数据的?同时告诉大家这里同样只是讲的理论与设计,理论和设计往往都很空洞,但是却很灵活,需要靠每个人怎么运用。

一些图片

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

区域和格子

从上面的截图可以看出游戏场景其实是由格子来区分的,不管是矩形的格子还是其他形状的格子也好,一张地图不可能只有一个点(即多点组成一张地图)。在3D场景中似乎格子的位置总伴随着高度信息,所以让人感觉有些迷茫,其实我们可以将这些格子平铺成一张图。

如上面的最后一张图,是地形的剖面图,不过是横切面,如果我们看一下纵切面的话,就可以将3D的地图进行2D的转换。其实地图还是由一张平面图组成,只是多了Y轴的数据,也就是我们常说的地表高度。

地图数据

由指定格式的数据组成,在服务器和客户端的主要作用是用来寻路(点击地图走路,以及自动寻路)。

地图区域

一个场景一般情况下会有区域的划分,因为这些区域会有自己特殊的事件,如一个玩家加入该区域会产生某个事件,就像我们玩游戏的时候忽然触发了剧情一样,这都是区域的事件。

数据结构

有了指定的数据结构后,文件才能被正常的读取,而地图的数据一般是由编辑器生成,所以也必须规定文件的数据结构。

1、地图

1. 文件数据

武侠世界/天龙八部的场景地图数据格式为:[文件头][单元数据][单元数据]…… 单元数据的数量为地图横长* 地图纵长。

code.
typedef struct map_header_struct {
int16_t flag; //文件标记,用来区分是不是地图数据文件
int32_t xsize; //X方向大小 横长
int32_t zsize; //Y方向大小 纵长
} map_header_t; //文件头信息 typedef struct map_unit_struct {
int16_t flag; //标识信息
//00000000|00000000
// ||_ WalkDisable -是否禁止地面上行走的OBJ穿越 [0 可穿越 1不可穿越]
// |__ FlyDisable -是否禁止空中飞行的OBJ穿越 [0 可穿越 1不可穿越]
int8_t height; //高度
int8_t reserved; //预留字段
} map_unit_t; //单元数据信息

2. 对象数据

整个对象也就是整张地图的数据,在武侠世界/天龙八部中采用的是左手坐标系,而在服务器其实用不着空间的坐标也就是Y轴的数据,将地图切割后就是一张平面的图,这张平面的图一般都是矩形。

X坐标 左为0、右为最大(也可以说是地图横长)

Y坐标 上为0、下为最大(也可以说是地图纵长)

code.
/* 完整的地图示意图 */
// (0, z) (x, z)
// ___________
// y z | |
// | / | |
// |/ | |
// +-------x |_________|
//
// (0, 0) (x, 0)

2、区域

地图划分成一个个格子,而组成区域的也是格子,以下为一个区域的基本数据。

1. RECT(矩形格子)

left 左、top 高度、right 右、bottom 底部。

2. 区域ID

3. 脚本ID

算法(选择排序)

1、简单选择排序

简单选择排序基本思想是将最小的数据移动到第一个位置并交换数据,比如有N个元素,一次将最小的元素移动到第一个位置并交换数据,那么剩下的就只剩下N-1个数据,将剩下的N-1的序列的数据最小的数据移动到该剩下序列的第一个位置,这样移动N次之后,序列便成了有序的序列。

code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 简单选择排序基本思想是将最小的数据移动到第一个位置并交换数据,比如有N个元素,
* 第一次将最小的元素移动到第一个位置并交换数据,那么剩下的就只剩下N-1个数据
* 再将剩下的N-1的序列的数据最小的数据移动到该剩下序列的第一个位置,这样移动N次
* 之后,序列便成了有序的序列。
*/ //简单选择排序
void selectsort(int32_t array[], int32_t length);
//数组打印
void displayarray(int32_t array[], int32_t length); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
selectsort(array, length);
printf("sort result: ");
displayarray(array, length);
return ;
} void selectsort(int32_t array[], int32_t length) {
int32_t i, j, k;
int32_t temp;
//将第i个元素与第i+1...length个元素比较,将最小的元素放在第i个位置
for (i = ; i < length - ; ++i) {
j = i;
for (k = i + ; k < length; ++k) { //最小元素的序号为j
if (array[k] < array[j])
j = k;
}
if (j != i) { //如果序号i不等于j,则需要加序号i和序号j的元素交换
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
printf("the %d times sort result: ", i + );
displayarray(array, length);
}
} void displayarray(int32_t array[], int32_t length) {
int32_t i;
for (i = ; i < length; ++i)
printf("%4d", array[i]);
printf("\n");
}

result.

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

2、堆排序

堆排序算法实现比较复杂,它主要适用于大规模的数据排序,比如在10万个数据元素中找出前10个最小或是最大的元素,使用该算法效率最高。

code.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 堆排序算法实现比较复杂,它主要适用于大规模的数据排序,比如在10万个数据元素
* 中找出前10个最小或是最大的元素,使用该算法效率最高。
*/ //数组打印
void displayarray(int32_t array[], int32_t length);
//调整array[pos1...pos2],使其成为一个大顶堆
void adjustheap(int32_t array[], int32_t pos1, int32_t pos2);
//创建大顶堆
void createheap(int32_t array[], int32_t length);
//利用堆排序算法对数组进行排序
void heapsort(int32_t array[], int32_t length); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
printf("before sort: ");
displayarray(array, length);
heapsort(array, length);
printf("after sort: ");
displayarray(array, length);
return ;
} void displayarray(int32_t array[], int32_t length) {
int32_t i;
for (i = ; i < length; ++i)
printf("%4d", array[i]);
printf("\n");
} void adjustheap(int32_t array[], int32_t pos1, int32_t pos2) {
int32_t i;
int32_t temp;
temp = array[pos1]; //临时存放根节点
for (i = * pos1 + ; i <= pos2; i *= + ) {
if (i < pos2 && array[i] < array[i + ]) //从关键字较大的子节点向下筛选
++i; //i为关键字较大的节点的下标
if (temp > array[i]) break; //如果子节点的值小于根节点的值,则不进行交换
array[pos1] = array[i];
pos1 = i;
}
array[pos1] = temp; //将根节点插入到正确的位置
} void createheap(int32_t array[], int32_t length) {
int32_t i;
for (i = length / - ; i >= ; --i) //从序号length / 2 - 1开始建立大顶堆
adjustheap(array, i, length - );
} void heapsort(int32_t array[], int32_t length) {
int32_t i;
int32_t temp;
createheap(array, length); //创建堆
for (i = length - ; i > ; --i) { //将堆顶元素与最后一个元素交换,重新调整堆
temp = array[];
array[] = array[i];
array[i] = temp;
printf("the %d sort times: ", length - i);
displayarray(array, length);
adjustheap(array, , i - ); //将array[0...i-1]调整为大顶堆
}
}

result.

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)

MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)的更多相关文章

  1. MMORPG大型游戏设计与开发(游戏服务器 游戏场景 概述 updated)

    我们在玩游戏的时候,我们进入游戏后第一眼往往都是看到游戏世界中的场景,当然除了个别例外,因为那些游戏将游戏场景隐藏了起来,如文字游戏中的地点一样.既然我们接触了游戏世界的核心,那么作为核心的场景又包括 ...

  2. MMORPG大型游戏设计与开发(服务器 AI 概述)

    游戏世界中我们拥有许多对象,常见的就是角色自身以及怪物和NPC,我们可以见到怪物和NPC拥有许多的行为,比如说怪物常常见到敌对的玩家就会攻击一样,又如一些NPC来游戏世界中走来走去,又有些怪物和NPC ...

  3. MMORPG大型游戏设计与开发(服务器 游戏场景 动态场景与副本)

    场景的内容讲解到今天算是暂时划上一个句号了,接下来为大家讲解的是AI部分(大型AI),如果有兴趣的朋友不妨持续关注这些文章,大家一起学习和进步.动态场景和副本是场景中特殊的类型,副本在这里想必已经是无 ...

  4. MMORPG大型游戏设计与开发(概述)updated

    1.定义 MMORPG,是英文Massive(或Massively)Multiplayer Online Role-PlayingGame的缩写,即大型多人在线角色扮演游戏. 2.技术与知识 在这系列 ...

  5. MMORPG大型游戏设计与开发(客户端架构 part8 of vegine)

    脚本模块是游戏设计中争论比较多的话题,那是因为作为脚本本身所带来的利弊.其实这都无关紧要,取舍是人必须学会的一项技能,如果你不会取舍那么就让趋势给你一个满意的答复.自从魔兽世界以及传奇(世界)问世以来 ...

  6. MMORPG大型游戏设计与开发(服务器 游戏场景 多线程)

    多线程在随着cpu发展应用的是越来越多,游戏场景因为其在服务器所占的数据量与逻辑复杂度的原因必须依赖于它.为什么场景要采用多线程?场景的线程是怎样的?场景的线程又是如何创建的?场景的线程又是怎样管理的 ...

  7. MMORPG大型游戏设计与开发(服务器 游戏场景 核心详述)

    核心这个词来的是多么的高深,可能我们也因为这个字眼望而却步,也就很难去掌握这部分的知识.之所以将核心放在最前面讲解,也可以看出它真的很重要,希望朋友们不会错过这个一直以来让大家不熟悉的知识,同我一起进 ...

  8. MMORPG大型游戏设计与开发(服务器 AI 事件)

    AI中的事件与场景中的事件大致相同,都是由特定的条件触发的.只不过AI的事件与其他事件不同的是,对于AI的事件往往是根据不同的AI类型,和动态的触发条件下才产生的.其实不管AI多么智能,它对应的触发条 ...

  9. MMORPG大型游戏设计与开发(服务器 AI 基础接口)

    一个模块都往往需要统一的接口支持,特别是对于非常大型的模块,基础结构的统一性非常重要,它往往决定了其扩展对象的通用性.昨天说了AI的基本概述以及组成,作为与场景模块中核心一样重要的地位,基础部分的设计 ...

随机推荐

  1. Android SDK路径不能含有空格

    错误, android sdk location shoud not contain whitespace,as this can cause problems with thte ndk tools

  2. CentOS系统配置redis

      1.切换到/usr/sr cd /usr/src wget http://download.redis.io/releases/redis-3.2.0.tar.gz   2.解压,安装 tar x ...

  3. &lbrack;Everyday Mathematics&rsqb;20150203

    设 $f$ 在 $\bbR$ 上连续可导, 且 $\dps{f'\sex{\frac{1}{2}}=0}$. 试证: $$\bex \exists\ \xi\in \sex{0,\frac{1}{2} ...

  4. Hive UDAF介绍与开发

    UDAF简介 UDAF是用户自定义聚合函数.Hive支持其用户自行开发聚合函数完成业务逻辑. 通俗点说,就是你可能需要做一些特殊的甚至是非常扭曲的逻辑聚合,但是Hive自带的聚合函数不够玩,同时也还找 ...

  5. HDOJ&sol;HDU 2087 剪花布条&lpar;indexOf&lpar;&rpar;应用~~&rpar;

    Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入 ...

  6. 几个Uboot命令

    1 nand scrub 这个命令会擦除坏块信息,将坏块标识成好的,但此时这个坏块有潜在有危险,在特定条件下仍会造成数据的丢失,所以应该谨慎使用. Run U-boot and then use th ...

  7. mysql文件导入到数据库load data infile into table 的使用例子

    load data infile "C:/Users/Administrator/Desktop/1.txt"into table 要一个已经存的表名 字段默认用制表符隔开 文件 ...

  8. trove 开发者阅读翻译

    介绍 Trove为OpenStack提供数据库的服务.它的设计运行完全符合OpenStack,目标是让用户能快速.轻松地利用关系数据库的特点,没有负担的处理复杂的管理任务.云用户和数据库管理员可以根据 ...

  9. ajax 原理----初级篇

    一.贴dome,ajax三大步 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  10. Redis学习-Set

    在Redis中,Set类型是没有排序的字符集合,和List类型一样,可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复杂度为O(1),即常量时间内完成次操 ...