搜索优化之四叉树算法(一)

最近闲来无事,打算写点东西,最为一名从事游戏开发行业多年的程序,温故而知新,多做总结整理,用最通俗易懂的文字,阐述晦涩难懂的原理,于人于己,都是一件有意义的事情,很多程序同学写了很多年的逻辑代码,没有太多的机会去实现底层的需求,因为大部分项目的核心框架在项目初期都已经搭建完毕了,这部分代码,不应该是思想(有的底层写的也不是太完美)都是主程来维护和整理,程序工作者如果不在实践中去理解知识点的作用和用途是很难有所突破的,就好像我每天都想成为武林高手,天天在家打桩不出去找人干架是没有什么卵用的,废话不多说了,这个系列的内容不会很多,在时间上也没有要求,不知道什么时候完结,但我会尽快,每个部分的内容可能会很多,也可能会很少,但都是自己所悟所想,如果你能从中有所收获,荣幸之至!

四叉树是一种搜索优化算法,何为搜索优化,先说下搜索,要搜什么?

在大型ARPG游戏中,众所周知,你会看到很多怪物,玩家,NPC,场景特效,等等,在承受住同屏渲染压力后,就要在交互层面进行设计了,何为交互?

交互很好理解,就是相互沟通交流,我无聊的时候无找个NPC美眉聊天,我把鼠标放在MM的身上她会高开心的对我笑,当我点击她的时候,她会弹出一个面板跟我问好等等,再比如,我获得了一把武器,想要去感受一下新装备的威力,跑到南郊打死几只野兔,当我点击野兔的时候,它会被我选中,并试图逃跑,然而并没有那么容易,我会试图去接近它,快速把它杀掉,有了这种交互的游戏体验就会很好了,但是有些交互并非这么简单,有些复杂交互式什么样子的呢?

如果你玩过传奇类游戏或者MMO类的就会很容易发现,当你进入游戏站在主城中发现人山人海,擦肩接踵,你会发现曾经的NPC美眉已经被埋没在人群之中无法找到,但是你把鼠标移动过去点击的时候你会惊奇的发现,虽然看似没点到她,却弹出了跟你问好的对话框,这是一种复杂的交互情况了,这跟搜索优化有什么关系呢?

如果你从一个设计者的角度去分析思考,你会发现,如果我想知道当前鼠标点击的是不是NPC美眉,要怎么实现呢?
从程序层面出发最简单的思路就是遍历视野内所有显示对象实例,根据实例类型和实例的矩形范围是否包含鼠标点,这样看似是可以实现的,但如果视野内的玩家很多,多到你在遍历的过程中因为代码运行时间过长导致游戏掉帧而出现卡顿,那么这个时候搜索优化就派上用场了。

搜索优化在2D游戏中普遍采用四叉树算法,他能很好的解决上面所产生的性能问题,以为我们无需去考虑对象数量的多少,只需要遍历鼠标点周围一定范围下面的四叉树节点的所有显示对象即可,这样说可能有点不好理解,后续我会慢慢解释清楚,为了更好的解释清楚如何完成搜索的优化,我们先来尝试着创建一个基于一定尺寸地图范围和最小矩形范围的四叉树。

现在我们准备了一张15000*15000像素的地图,里面布满了很多的怪物还有花花草草,和NPC美眉还有一些宝箱,我们把四叉树节点的最小矩形宽高默认设置为250像素(默认宽高大小一致的矩形),下面我们来计算一个值,树的深度(depth)

树的深度即这个树有多少层节点,也可以简单理解为树的层数

这个算起来很简单,首先我们假设有n层,那么第n层的节点数量m 和最小矩形的宽度相乘的值 一定要大于等于 地图的宽度
或者说第n层的节点数量m和最小矩形的高度相乘的值要大于等于地图的高度,很好理解,但是要有取舍,取地图宽高的最大值来作为比较对象,这样才能覆盖整个地图区域,不会出现漏掉的区域,好了,下面就是用代码去实现了

理解了上面内容,代码实现起来就很简单了

//参数:地图宽,地图高,最小矩形宽或高
function getDepth(mapW,mapH,minR):int
{
var value:int;
var mapSize:int = Math.max(mapW,mapH);
var n:int =1;
while(1){
value = Math.round(mapSize/Math.pow(2,n));
if(value<=minR)return n;
n++;
}
return -1;
}

如何理解呢?
很简单,就是用15000除以250,每除一次n加一,当除完的值小于等于250所得到的n就是我们要的深度了 ,最后算的n=6
很好,后面我们就来创建一个深度为6的四叉树

note:ARPG类游戏都是基于格子 的,所以创建四叉树的时候,最小矩形范围参考在200-400像素最好,建树深度根据地图大小一般选择在3~7层

由于时间关系,今天就写到这里了,预知后事如何,敬请期待!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值