MMORPG大型游戏设计与开发(服务器 游戏场景 多线程)
多线程在随着cpu发展应用的是越来越多,游戏场景因为其在服务器所占的数据量与逻辑复杂度的原因必须依赖于它。为什么场景要采用多线程?场景的线程是怎样的?场景的线程又是如何创建的?场景的线程又是怎样管理的?在这里同时对可以指正错误的朋友们说声谢谢,虽然是小错误,也希望大家能够勇于纠正这些错误。
游戏截图
采用理由
上面的两张截图分别在不同的场景,试想一下如果一个线程只能先处理其中一张图的数据,后果会怎么样?
单线程往往需要等待,就好像我们到银行窗口办理业务的时候,以前的时候很多网点只有一个窗口,所以我们不得不排队等候,然而随着时代的进步银行的窗口随着业务的开展越来越多,更多的业务员使得我们省去了排队的烦恼。而游戏场景在游戏中处理的逻辑是最为复杂的,特别是一些大场景的数据那更是多不胜数,程序处理逻辑数据需要时间,在单线程里面对复杂的逻辑就需要等待不少的时间,数据和逻辑越复杂其等待的时间就会越长,你想如果我们在玩游戏的时候在A场景的时候,B场景因为要等待A场景的逻辑处理完成后才能够处理其场景的数据,也就是说A场景的人先走动完成后,B场景的玩家才能走动。
为了让所有场景的数据都能在较短的时间内处理,我们就需要更多的处理者来帮忙,也就是我们拥有更多的线程来处理,如果只有一个线程处理N个场景当然很慢,如果有M个场景同时处理N个场景速度则会大大提高,这就是我们之所以选择多线程的原因。而且一个线程所能承受的场景数量,往往是跟场景的数据量大小以及复杂度有关。
场景多线程
1、线程管理器(manager)
用于添加场景线程并初始化线程数据。
2、线程池(pool)
多个线程数据的集合管理。
3、线程分配(thread)
这个世界上最理想的是有足够的资源,就像这里一样每个线程负责一个场景就是最理想的,因为这样效率是最高的。线程越多消耗的CPU自然成正比例的增加,就好像地球上的资源一样,没有办法完全的满足需求一样,这样我们就必须想办法进行资源共享,一个线程负责多个场景。记得小时候的劳动课一样,有时候工具不够的情况下,老师往往会将同学们分成几组,每组共享那些工具,但是有的时候一个工具分了很多人使用,超过了负荷的时候就达不到老师的要求(比如老师要求规定时间内每个人都要使用工具多少次,因为人数太多甚至有的人工具都碰不到)。
线程的负载主要表现在程序执行的快慢和效率上,如果效率明显很低影响到了正常的工作,我们就不得不想办法提升效率。最直接影响场景线程的负载的便是负责场景数量,所以场景线程有规定的场景上限。
一般流程
场景管理器创建所有场景(scene manager)->线程池对象初始化(thread pool)->线程管理器分配场景线程(thread manager)->场景线程管理器运行所有线程(thread manager)
算法(交换排序)
1、冒泡排序(bubble sort)
交换相邻的两个元素,将最大的元素逐渐移动到最后,如果数组大小为N,则N次之后数组则变为有序的数组。泡排序算法主要用于排序元素较少且时间要求不太高的场合。这里进行了算法改进:增加一个标记,如果已经没有需要交换的元素则后面不需再排序。
code.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 交换相邻的两个元素,将最大的元素逐渐移动到最后,如果数组大小为N,则N次之后数组则变为有序的数组
* 冒泡排序算法主要用于排序元素较少且时间要求不太高的场合
* 算法改进:增加一个标记,如果已经没有需要交换的元素则后面不需再排序
*/ void printarray(int32_t array[], int32_t length);
void bubblesort(int32_t array[], int32_t length); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
bubblesort(array, length);
return ;
} void printarray(int32_t array[], int32_t length) {
int32_t i;
for (i = ; i < length; ++i)
printf("%4d", array[i]);
printf("\n");
} void bubblesort(int32_t array[], int32_t length) {
int32_t i, j;
int32_t temp;
uint8_t flag = ;
for (i = ; i < length && == flag; ++i) {
flag = ;
for (j = ; j < length - i; ++j) {
if (array[j] > array[j + ]) {
temp = array[j];
array[j] = array[j + ];
array[j + ] = temp;
flag = ;
}
}
printf("the %d times result: ", i);
printarray(array, length);
}
}
result.
2、快速排序(quick sort)
快速排序算法是冒泡排序算法的改进,但是实现却比冒泡复杂很多,它主要针对大数据排序,果对时间要求不是很高可以使用直接插入排序或者冒泡排序。其特点是排序的时间效率比较高,并且在特别大的数据量时十分明显。同希尔算法一样,快速排序是一种不太稳定的算法,和其实现的原理有关。
code.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h> /**
* 快速排序算法是冒泡排序算法的改进,但是实现却比冒泡复杂很多,它主要针对大数据排序,
* 如果对时间要求不是很高可以使用直接插入排序或者冒泡排序
* 其特点是排序的时间效率比较高,并且在特别大的数据量时十分明显。
* 同希尔算法一样,快速排序是一种不太稳定的算法,和其实现的原理有关。
*/ //数组打印
void displayarray(int32_t array[], int32_t length);
//输出每次划分的结果
void _displayarray(int32_t array[], int32_t length, int32_t pivot, int32_t count);
//快速排序核心实现
void _quicksort(int32_t array[], int32_t length, int32_t low, int32_t high);
//快速排序函数,对数组的元素进行排序
void quicksort(int32_t array[], int32_t length);
//对素组array[low...high]的元素进行一趟排序,使枢轴前面的元素小于枢轴元素,
//枢轴后面的元素大于等于枢轴元素,并返回枢轴元素
int32_t partition(int32_t array[], int32_t low, int32_t high); int32_t main(int32_t argc, char *argv[]) {
int32_t array[] = {, , , , , , , , , , };
int32_t length = sizeof(array) / sizeof(array[]);
printf("before sort: ");
displayarray(array, length);
quicksort(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 _displayarray(int32_t array[],
int32_t length,
int32_t pivot,
int32_t count) {
int32_t i;
printf("the %d times result: [", count);
for (i = ; i < pivot; ++i)
printf("%-4d", array[i]);
printf("]");
printf("%3d ", array[pivot]);
printf("[");
for (i = pivot + ; i < length; ++i)
printf("%-4d", array[i]);
printf("]");
printf("\n");
} void _quicksort(int32_t array[], int32_t length, int32_t low, int32_t high) {
int32_t pivot;
static int32_t count = ;
if (low < high) { //如果元素序列的长度大于1
pivot = partition(array, low, high); //将待排序序列array[low...high]划分为两部分
_displayarray(array, length, pivot, count); //输出每次划分的结果
++count;
_quicksort(array, length, low, pivot - ); //对左边的子表进行递归排序,pivot是枢轴位置
_quicksort(array, length, pivot + , high); //对右边的子表进行递归排序
}
} void quicksort(int32_t array[], int32_t length) {
_quicksort(array, length, , length - );
} int32_t partition(int32_t array[], int32_t low, int32_t high) {
int32_t temp, pivot;
pivot = array[low]; //将第一个元素作为枢轴元素
temp = array[low];
while (low < high) { //从表的两端交替的向中间扫描
while (low < high && array[high] >= pivot) //从表的末端向前扫描
--high;
if (low < high) { //将当前high指向的元素保存在low位置
array[low] = array[high];
++low;
}
while (low < high && array[low] <= pivot) //从表的开始向后扫描
++low;
if (low < high) { //将当前low指向的元素保存在high位置
array[high] = array[low];
--high;
}
array[low] = temp;
}
return low;
}
result.
MMORPG大型游戏设计与开发(服务器 游戏场景 多线程)的更多相关文章
- MMORPG大型游戏设计与开发(游戏服务器 游戏场景 概述 updated)
我们在玩游戏的时候,我们进入游戏后第一眼往往都是看到游戏世界中的场景,当然除了个别例外,因为那些游戏将游戏场景隐藏了起来,如文字游戏中的地点一样.既然我们接触了游戏世界的核心,那么作为核心的场景又包括 ...
- MMORPG大型游戏设计与开发(服务器 AI 概述)
游戏世界中我们拥有许多对象,常见的就是角色自身以及怪物和NPC,我们可以见到怪物和NPC拥有许多的行为,比如说怪物常常见到敌对的玩家就会攻击一样,又如一些NPC来游戏世界中走来走去,又有些怪物和NPC ...
- MMORPG大型游戏设计与开发(服务器 游戏场景 动态场景与副本)
场景的内容讲解到今天算是暂时划上一个句号了,接下来为大家讲解的是AI部分(大型AI),如果有兴趣的朋友不妨持续关注这些文章,大家一起学习和进步.动态场景和副本是场景中特殊的类型,副本在这里想必已经是无 ...
- MMORPG大型游戏设计与开发(概述)updated
1.定义 MMORPG,是英文Massive(或Massively)Multiplayer Online Role-PlayingGame的缩写,即大型多人在线角色扮演游戏. 2.技术与知识 在这系列 ...
- MMORPG大型游戏设计与开发(客户端架构 part8 of vegine)
脚本模块是游戏设计中争论比较多的话题,那是因为作为脚本本身所带来的利弊.其实这都无关紧要,取舍是人必须学会的一项技能,如果你不会取舍那么就让趋势给你一个满意的答复.自从魔兽世界以及传奇(世界)问世以来 ...
- MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)
地图的数据以及区域的信息是场景的重要组成部分,这些数据同时存在客户端和服务器,而且都是由编辑器生成的.那么保存的文件数据结构是怎样的?一张3D的场景地图又是怎样处理这些数据的?同时告诉大家这里同样只是 ...
- MMORPG大型游戏设计与开发(服务器 游戏场景 核心详述)
核心这个词来的是多么的高深,可能我们也因为这个字眼望而却步,也就很难去掌握这部分的知识.之所以将核心放在最前面讲解,也可以看出它真的很重要,希望朋友们不会错过这个一直以来让大家不熟悉的知识,同我一起进 ...
- MMORPG大型游戏设计与开发(服务器 AI 事件)
AI中的事件与场景中的事件大致相同,都是由特定的条件触发的.只不过AI的事件与其他事件不同的是,对于AI的事件往往是根据不同的AI类型,和动态的触发条件下才产生的.其实不管AI多么智能,它对应的触发条 ...
- MMORPG大型游戏设计与开发(服务器 AI 基础接口)
一个模块都往往需要统一的接口支持,特别是对于非常大型的模块,基础结构的统一性非常重要,它往往决定了其扩展对象的通用性.昨天说了AI的基本概述以及组成,作为与场景模块中核心一样重要的地位,基础部分的设计 ...
随机推荐
- Win10 UWP 开发系列:支持异步的SQLite
上篇文章已经实现了在UWP中使用SQLite作为本地存储,作为移动端的程序,及时响应用户的操作是提高用户体验的重要途径,因此UWP的很多api都是异步的.那么如何使SQLite支持异步呢? 参考SQL ...
- Web 组合查询加 分页
使用ADO.NET 数据访问技术制作web端组合查询加分页的功能关键在于查询SQL语句的拼接 以Car 表为例 每页显示3条数据 数据访问类使用查询方法,tsql 查询的连接字符串,查询的参数放到Ha ...
- customErrors与错误页面
本配置节相对简单而且常用 <customErrors defaultRedirect="url" mode="On|Off|RemoteOnly"> ...
- 纯css3手机页面图标样式代码
全部图标:http://hovertree.com/texiao/css/19/ 先看效果: 或者点这里:http://hovertree.com/texiao/css/19/hoverkico.ht ...
- Unity3D 5.x 交互功能 - 光线投射、碰撞设置
1,光线投射碰撞:第一人称视线在预置范围内(如3米)和看到的物体发生碰撞 ① 检测光线投射碰撞的脚本添加在第一人称FPSController上 #pragma strict private var c ...
- php导入excel表格
我们做网站的时候经常要用到excel导入和导出的功能,我们通常的做法是用phpexcel工具包来完成,具体方法如下: html代码: <form action="{:U('Mall/u ...
- 《疯狂Java讲义》学习笔记——第2章 理解面向对象
面向对象的三种基本特征:继承,封装,多态 UML(统一建模语言) 2.1 面向对象 2.1.1 结构化程序设计简介 图2.1 结构化软件的逻辑结构示意图 从图2.1可以看出,结构化设计需要采用自顶向 ...
- java代码实现队列的优化
package com.voole.queun; /** * @Decription 队列 * @author TMAC-J * */ public class Queun { /** * 初始化队列 ...
- OO方式下,ALV TREE和ALV GRID的不同之处
作为大部分报表程序的基础,ALV GRID差不多是每个ABAP开发者必须了解和掌握的内容,因此网上也不乏相关资料,而ALV TREE的应用相对较少,中文资料也就比较少见了.实际上,ALV TREE和A ...
- SharePoint 2013 新建网站集图解
前言:接触SharePoint的人可能是越来越多,但是很多人一接触就很迷茫,在技术群里问如何新建网站集,这样一篇图解,帮助新手学习在搭建好SharePoint环境之后,如何创建一个网站集,做一个基本的 ...