搜索优化之四叉树算法(三)
上节内容讲解了如何使用递归方式创建四叉树,并附上了具体的实现代码,递归式一种很优美的编码方式,自然,简洁,方便理解
本节内容我们会将显示对象绑定到节点上,并实现动态四叉树更新显示对象的节点位置,何为动态四叉树显示对象节点更新,比如游戏中怪物移动,从一个区域移动到另一个区域,每当怪物的坐标发生变化,我们都需要去更新他是否还隶属于当前的节点范围内,如果不在当前节点范围了,就要去更新他所隶属的节点了,好了,下面我们一步一步实现这些步骤
标题:动态四叉树中显示对象的绑定与更新
上节内容我们创建了几个很重要的类,如果你不记得也没关系,我在下面简单的罗列一下
NodeTree.as 四叉树
NodeRect.as 四叉树矩形节点类
NodeTreeManager.as 四叉树管理器
通过上面3个类,我们完成了一个四叉树的创建,下面我们来创建一个显示对象类,继承Sprite精灵类,实现INodeDisplay节点显示对象接口
//节点矩形范围接口
public interface INodeRect
{function get rect():Rectangle;function refree():void;
}
//可现实节点接口
public interface INodeDisplay extends INoder{function get node():INodeRect;}public class NodeSprite extends Sprite implements INodeDisplay
{private var _tid:String; //该显示对象隶属的树的idprivate var _isActive:Boolean;private var _initialized:Boolean;private var _node:NodeRect;//该显示对象隶属的节点private var _tree:NodeTree;//该显示对象隶属的树
public function NodeSprite(){super();this.id = (Math.random() * int.MAX_VALUE).toString();//唯一IDthis.mouseChildren=this.mouseEnabled=false;//禁止鼠标事件this.tabChildren=this.tabEnabled=false;}
}
首先,一个想要实现四叉树节点可交互对象必须要继承NodeSprite才可以,这里我们不做子类声明和实现,如果有需求可以自行添加,可交互的对象实例化之后,需要注册进来,以便标记这个对象是隶属于那个四叉树的 ,所以我们需要一个注册方法
/*** 所有NodeSprite对象初始化都要执行这个方法。 * @param tid* */ public function registNodeTree(tid:String):void{this._tree= TreeManager.instance.take(tid) as NodeTree;this._tid = tid;this._initialized=true;}
注册完以后,_initialized=true初始化标记为真,后续的步骤就可以进行了,为了将显示对象添加到对应的节点上,我们会花费很大的代价
首先,我们要根据当前显示对象的坐标位置,获取到他隶属于那个子节点,然后,才能名正言顺的添加到这个节点上,或者从这个节点移除,上文讲过,每个节点都有个一唯一
id = node.x + ”_” + node.y
好了,知道了id的格式,我们就可以根据显示对象的坐标(x,y)来计算出他的唯一id 或者我叫他nodekey
/*** 根据当前显示对象位置获取当前节点 * @return * */ private function get nodekey():String{//算出鼠标点所在的节点 起始坐标var nodex:int = int(this._pos_x/NodeTree.MIN_SIZE)*NodeTree.MIN_SIZE;var nodey:int = int(this._pos_y/NodeTree.MIN_SIZE)*NodeTree.MIN_SIZE;//参考NodeSprite.asreturn nodex + '_' + nodey;}
NodeTree.MIN_SIZE是四叉树最小的子节点尺寸
得到了nodekey 就可以获取到 显示对象所隶属的四叉树节点了
_tree.getNode(nodekey ) as NodeRect;
到了这一步基本里成功很近了,我们只需要在节点NodeRect中创建2个方法就可以将显示对象 添加或者移除 到节点上了
public function addChild(id:String,noder:INoder):void{if(this._nodes[id] == null){this._nodes[id] = noder;_length++;}}public function removeChild(id:String):void{if(this._nodes[id] != null){this._nodes[id] =null;delete this._nodes[id];_length --;}}
实现了显示对象在节点上的添加和移除,我们就可以继续实现四叉树节点的动态更新了,当显示对象的坐标发生改变时,这就要求我们需要重写显示对象的x,y方法
private var _pos_x:int;private var _pos_y:int;override public function set x(value:int):void{if(value==super.x)return;super.x = int(value);update(x,y,nodekey);}override public function set y(value:int):void{if( value==super.y)return;super.y = int(value);update(x,y,nodekey);}public function setXY(x:int,y:int):void{super.x = int(x);super.y = int(y);this._pos_x = int(x);this._pos_y = int(y);update(x,y,nodekey);}
当显示对象从一个节点范围移动到另一个节点范围,我们需要update方法来实现他的具体操作
/*** 动态四叉树核心方法 * @param x* @param y* @param nodekey 该点所在的节点id 通过这个id查找到对应的noderect* */ private function update(x:int, y:int, key:String):void{if(this._initialized==false)return;if(this._isActive==false)return;if(!this._tree.initialized)return;if(this._node==null){_node = _tree.getNode(key) as NodeRect; }if(!_node.rect.contains(_pos_x,_pos_y)){//如果当前对象坐标不在所隶属的节点区间,就需要重新var nodeNew:NodeRect = _tree.getNode(key) as NodeRect;resetNode(nodeNew,_node);if(nodeNew!=null)_node = nodeNew;}}
更新节点 resetNode() 是个递归过程,从旧节点上移出去,添加到新节点上,子节点更新后还要更新父节点,直至遍历到新旧节点是同一个为止,实现过程如下
/*** 更新节点* @param nodeNew* @param nodeOld* */ private function resetNode(nodeNew:NodeRect, nodeOld:NodeRect):void{if(nodeNew &&nodeOld){if(nodeNew!=nodeOld){nodeOld.removeChild(this.id);nodeNew.addChild(this.id,this);this._node = nodeNew;resetNode(nodeNew.parent,nodeOld.parent);}}}
好了,经过上述一系列令人窒息的操作,终于实现了四叉树节点上可视对象的添加移除,并实现了动态更新,这一步是意义重大的一步,为下节的搜索遍历提供了铺垫,由于时间关系今天就写到这里了
搜索优化之四叉树算法(三)相关推荐
- 搜索优化之四叉树算法(一)
最近闲来无事,打算写点东西,最为一名从事游戏开发行业多年的程序,温故而知新,多做总结整理,用最通俗易懂的文字,阐述晦涩难懂的原理,于人于己,都是一件有意义的事情,很多程序同学写了很多年的逻辑代码,没有 ...
- mysql 四叉树的应用_游戏算法(2):查找优化之四叉树的应用
/** * 四叉树(基于2D平面空间分割)数据结构 * 四叉树或四元树也被称为Q树(Q-Tree). * 四叉树广泛应用于图像处理.空间数据索引.2D中的快速碰撞检测.存储稀疏数据等 * 为提升性能 ...
- 【优化求解】基于水母搜索优化器JS算法求解最优目标matlab源码
1 简介 1.1 人工水母算法原理背景 水母生活在世界上不同深度和温度的水中.它们酷似钟状,一些水母的直径小于1cm,然有些水母直径则非常大.它们有各种各样的颜色.大小和形状.大多数水母偏好海洋环境 ...
- 【优化求解】基于水母搜索优化器JS算法求解多目标优化问题matlab源码
1 简介 1.1 人工水母算法原理背景 水母生活在世界上不同深度和温度的水中.它们酷似钟状,一些水母的直径小于1cm,然有些水母直径则非常大.它们有各种各样的颜色.大小和形状.大多数水母偏好海洋环境 ...
- 【杂谈】有三AI秋季划火热进行中,如何深入学习模型优化,人脸算法,图像质量等研究方向...
文/编辑 | 言有三 这是我们最后一次CV季划,关于春季划和夏季划的说明,大家可以阅读往期文章. 这个春天,有三最后一月的学习"季划"招生 最后24小时,有三AI夏季划报名即将截止 ...
- 多目标优化算法:多目标黄金搜索优化算法MOGSO(提供MATLAB代码)
一.算法简介 黄金搜索优化算法(Golden Search Optimization Algorithm,GSO)由MOHAMMAD NOROOZI等人于2022年提出,该算法原理简单,快捷高效. 二 ...
- 融合改进天牛须和正余弦的双重搜索优化算法
文章目录 一.理论基础 1.正余弦优化算法 2.天牛须搜索算法 3.融合改进天牛须和正余弦的优化算法 (1)引入自适应权重 (2)递减参数r1r_1r1的改变 (3)变步长搜索机制 (4)算法流程图 ...
- 基于回溯搜索优化算法的WSN覆盖优化
文章目录 一.理论基础 1.回溯搜索优化算法 (1)种群初始化 (2)选择Ⅰ (3)变异 (4)交叉 (5)选择Ⅱ 2.BSA算法伪代码 二.仿真实验与结果分析 三.参考文献 一.理论基础 1.回溯搜 ...
- 自适应变异麻雀搜索优化算法
文章目录 一.理论基础 1.麻雀搜索算法 2.改进麻雀搜索算法 2.1 猫映射混沌初始化种群 2.2 Tent混沌和柯西变异扰动策略 2.2.1 Tent混沌扰动 2.2.2 柯西变异 2.3 改进探 ...
- 混沌麻雀搜索优化算法
文章目录 一.理论基础 1.麻雀搜索算法 2.Tent混沌及高斯变异 2.1 Tent混沌 2.1.1 Tent混沌序列 2.1.2 Tent混沌扰动 2.2 高斯变异 3.改进麻雀搜索算法 二.仿真 ...
最新文章
- java pdf插件下载_免费java pdf控件
- SQL判断是否“存在“,还在用 count 操作?
- 「 每日一练,快乐水题 」504. 七进制数
- ExcelJS —— Node 的 Excel 读写扩展模块2
- 服务端负载均衡和客户端负载均衡
- Windows 如何通过命令启动和关闭 Tomcat
- 太长的sql怎么分析_因为ESR, 我一定要推荐你这款 SQL 神器
- docker 安装MySQL远程连接
- bt5 mysql字典,backtrack5下载
- bootstrap布局设计在线工具
- CAD命令输入、结束、重复与撤销
- linux 搜狗输入法使用技巧,在Deepin 20系统中使用官方搜狗输入法的技巧
- 网络对抗技术——实验四:恶意代码技术
- 保护你的眼睛——设置电脑屏幕颜色和ClearType字体
- 港科夜闻|香港科技大学国际管理理学硕士(MIMT)课程连续第二年跻身全球管理教育联盟 (CEMS) 2021年度最佳学院前三甲...
- microsoft store 安装包_Microsoft 办公软件免费了?
- 华为立体运维-第四课(APM探针部署)
- SAP ABAP Odata
- 120年奥运会数据分析
- Linux ps 命令使用介绍