上节内容讲解了如何使用递归方式创建四叉树,并附上了具体的实现代码,递归式一种很优美的编码方式,自然,简洁,方便理解

本节内容我们会将显示对象绑定到节点上,并实现动态四叉树更新显示对象的节点位置,何为动态四叉树显示对象节点更新,比如游戏中怪物移动,从一个区域移动到另一个区域,每当怪物的坐标发生变化,我们都需要去更新他是否还隶属于当前的节点范围内,如果不在当前节点范围了,就要去更新他所隶属的节点了,好了,下面我们一步一步实现这些步骤

标题:动态四叉树中显示对象的绑定与更新

上节内容我们创建了几个很重要的类,如果你不记得也没关系,我在下面简单的罗列一下
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);}}}

好了,经过上述一系列令人窒息的操作,终于实现了四叉树节点上可视对象的添加移除,并实现了动态更新,这一步是意义重大的一步,为下节的搜索遍历提供了铺垫,由于时间关系今天就写到这里了

搜索优化之四叉树算法(三)相关推荐

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

    最近闲来无事,打算写点东西,最为一名从事游戏开发行业多年的程序,温故而知新,多做总结整理,用最通俗易懂的文字,阐述晦涩难懂的原理,于人于己,都是一件有意义的事情,很多程序同学写了很多年的逻辑代码,没有 ...

  2. mysql 四叉树的应用_游戏算法(2):查找优化之四叉树的应用

    /** * 四叉树(基于2D平面空间分割)数据结构 * 四叉树或四元树也被称为Q树(Q-Tree). * 四叉树广泛应用于图像处理.空间数据索引.2D中的快速碰撞检测.存储稀疏数据等 * 为提升性能 ...

  3. 【优化求解】基于水母搜索优化器JS算法求解最优目标matlab源码

    1 简介 1.1  人工水母算法原理背景 水母生活在世界上不同深度和温度的水中.它们酷似钟状,一些水母的直径小于1cm,然有些水母直径则非常大.它们有各种各样的颜色.大小和形状.大多数水母偏好海洋环境 ...

  4. 【优化求解】基于水母搜索优化器JS算法求解多目标优化问题matlab源码

    1 简介 1.1  人工水母算法原理背景 水母生活在世界上不同深度和温度的水中.它们酷似钟状,一些水母的直径小于1cm,然有些水母直径则非常大.它们有各种各样的颜色.大小和形状.大多数水母偏好海洋环境 ...

  5. 【杂谈】有三AI秋季划火热进行中,如何深入学习模型优化,人脸算法,图像质量等研究方向...

    文/编辑 | 言有三 这是我们最后一次CV季划,关于春季划和夏季划的说明,大家可以阅读往期文章. 这个春天,有三最后一月的学习"季划"招生 最后24小时,有三AI夏季划报名即将截止 ...

  6. 多目标优化算法:多目标黄金搜索优化算法MOGSO(提供MATLAB代码)

    一.算法简介 黄金搜索优化算法(Golden Search Optimization Algorithm,GSO)由MOHAMMAD NOROOZI等人于2022年提出,该算法原理简单,快捷高效. 二 ...

  7. 融合改进天牛须和正余弦的双重搜索优化算法

    文章目录 一.理论基础 1.正余弦优化算法 2.天牛须搜索算法 3.融合改进天牛须和正余弦的优化算法 (1)引入自适应权重 (2)递减参数r1r_1r1​的改变 (3)变步长搜索机制 (4)算法流程图 ...

  8. 基于回溯搜索优化算法的WSN覆盖优化

    文章目录 一.理论基础 1.回溯搜索优化算法 (1)种群初始化 (2)选择Ⅰ (3)变异 (4)交叉 (5)选择Ⅱ 2.BSA算法伪代码 二.仿真实验与结果分析 三.参考文献 一.理论基础 1.回溯搜 ...

  9. 自适应变异麻雀搜索优化算法

    文章目录 一.理论基础 1.麻雀搜索算法 2.改进麻雀搜索算法 2.1 猫映射混沌初始化种群 2.2 Tent混沌和柯西变异扰动策略 2.2.1 Tent混沌扰动 2.2.2 柯西变异 2.3 改进探 ...

  10. 混沌麻雀搜索优化算法

    文章目录 一.理论基础 1.麻雀搜索算法 2.Tent混沌及高斯变异 2.1 Tent混沌 2.1.1 Tent混沌序列 2.1.2 Tent混沌扰动 2.2 高斯变异 3.改进麻雀搜索算法 二.仿真 ...

最新文章

  1. java pdf插件下载_免费java pdf控件
  2. SQL判断是否“存在“,还在用 count 操作?
  3. 「 每日一练,快乐水题 」504. 七进制数
  4. ExcelJS —— Node 的 Excel 读写扩展模块2
  5. 服务端负载均衡和客户端负载均衡
  6. Windows 如何通过命令启动和关闭 Tomcat
  7. 太长的sql怎么分析_因为ESR, 我一定要推荐你这款 SQL 神器
  8. docker 安装MySQL远程连接
  9. bt5 mysql字典,backtrack5下载
  10. bootstrap布局设计在线工具
  11. CAD命令输入、结束、重复与撤销
  12. linux 搜狗输入法使用技巧,在Deepin 20系统中使用官方搜狗输入法的技巧
  13. 网络对抗技术——实验四:恶意代码技术
  14. 保护你的眼睛——设置电脑屏幕颜色和ClearType字体
  15. 港科夜闻|香港科技大学国际管理理学硕士(MIMT)课程连续第二年跻身全球管理教育联盟 (CEMS) 2021年度最佳学院前三甲...
  16. microsoft store 安装包_Microsoft 办公软件免费了?
  17. 华为立体运维-第四课(APM探针部署)
  18. SAP ABAP Odata
  19. 120年奥运会数据分析
  20. Linux ps 命令使用介绍

热门文章

  1. 腾讯云cdn怎样接入域名
  2. vhdl变量除法_在VHDL中实现高精度快速除法
  3. Arduino相关语法和函数
  4. 数据库——数据字典是什么?
  5. 初学者宝典:C语言入门基础知识大全
  6. 社交网络算法在金融反欺诈中的应用
  7. python制作电子签名
  8. 制作淘宝客微信公众号(一)
  9. 文件导入工具类--利用反射自动转换为list对象
  10. 大数据产品推荐:Stratifyd大数据智能分析平台