mirror of
https://gitee.com/devil_root/snake.git
synced 2025-10-10 00:56:28 +00:00
the demo
This commit is contained in:
170
assets/Scripts/common/QuadTree.ts
Normal file
170
assets/Scripts/common/QuadTree.ts
Normal file
@@ -0,0 +1,170 @@
|
||||
import { Rect, _decorator } from "cc";
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass("QuadTree")
|
||||
export default class QuadTree {
|
||||
|
||||
nodes = [];
|
||||
objects = []; //該容器的物體集合
|
||||
max_levels: number; // 最大深度
|
||||
max_objects: number; // 該容器最大容量
|
||||
level: number; //當前深度
|
||||
bounds: Rect = null; // 容器範圍(Rect)
|
||||
|
||||
constructor(boundary, level) {
|
||||
this.max_objects = 4;
|
||||
this.max_levels = 4;
|
||||
|
||||
this.level = level || 0;
|
||||
this.bounds = boundary;
|
||||
|
||||
this.objects = [];
|
||||
this.nodes = [];
|
||||
}
|
||||
|
||||
insert(pRect) {
|
||||
var i = 0, indexes;
|
||||
|
||||
//if we have subnodes, call insert on matching subnodes
|
||||
if (this.nodes.length) {
|
||||
indexes = this.getIndex(pRect);
|
||||
|
||||
for (i = 0; i < indexes.length; i++) {
|
||||
this.nodes[indexes[i]].insert(pRect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, store object here
|
||||
this.objects.push(pRect);
|
||||
|
||||
//max_objects reached
|
||||
if (this.objects.length > this.max_objects && this.level < this.max_levels) {
|
||||
|
||||
//split if we don't already have subnodes
|
||||
if (!this.nodes.length) {
|
||||
this.split();
|
||||
}
|
||||
|
||||
//add all objects to their corresponding subnode
|
||||
for (i = 0; i < this.objects.length; i++) {
|
||||
indexes = this.getIndex(this.objects[i]);
|
||||
for (var k = 0; k < indexes.length; k++) {
|
||||
this.nodes[indexes[k]].insert(this.objects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//clean up this node
|
||||
this.objects = [];
|
||||
}
|
||||
}
|
||||
|
||||
split() {
|
||||
var nextLevel = this.level + 1,
|
||||
subWidth = this.bounds.width / 2,
|
||||
subHeight = this.bounds.height / 2,
|
||||
x = this.bounds.x,
|
||||
y = this.bounds.y;
|
||||
|
||||
//top right node
|
||||
this.nodes[0] = new QuadTree({
|
||||
x: x + subWidth,
|
||||
y: y,
|
||||
width: subWidth,
|
||||
height: subHeight
|
||||
}, nextLevel);
|
||||
|
||||
//top left node
|
||||
this.nodes[1] = new QuadTree({
|
||||
x: x,
|
||||
y: y,
|
||||
width: subWidth,
|
||||
height: subHeight
|
||||
}, nextLevel);
|
||||
|
||||
//bottom left node
|
||||
this.nodes[2] = new QuadTree({
|
||||
x: x,
|
||||
y: y + subHeight,
|
||||
width: subWidth,
|
||||
height: subHeight
|
||||
}, nextLevel);
|
||||
|
||||
//bottom right node
|
||||
this.nodes[3] = new QuadTree({
|
||||
x: x + subWidth,
|
||||
y: y + subHeight,
|
||||
width: subWidth,
|
||||
height: subHeight
|
||||
}, nextLevel);
|
||||
}
|
||||
|
||||
|
||||
getIndex(pRect) {
|
||||
var indexes = [],
|
||||
verticalMidpoint = this.bounds.x + (this.bounds.width / 2),
|
||||
horizontalMidpoint = this.bounds.y + (this.bounds.height / 2);
|
||||
|
||||
var startIsNorth = pRect.y < horizontalMidpoint,
|
||||
startIsWest = pRect.x < verticalMidpoint,
|
||||
endIsEast = pRect.x + pRect.width > verticalMidpoint,
|
||||
endIsSouth = pRect.y + pRect.height > horizontalMidpoint;
|
||||
|
||||
//top-right quad
|
||||
if (startIsNorth && endIsEast) {
|
||||
indexes.push(0);
|
||||
}
|
||||
|
||||
//top-left quad
|
||||
if (startIsWest && startIsNorth) {
|
||||
indexes.push(1);
|
||||
}
|
||||
|
||||
//bottom-left quad
|
||||
if (startIsWest && endIsSouth) {
|
||||
indexes.push(2);
|
||||
}
|
||||
|
||||
//bottom-right quad
|
||||
if (endIsEast && endIsSouth) {
|
||||
indexes.push(3);
|
||||
}
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
||||
|
||||
retrieve(pRect) {
|
||||
var indexes = this.getIndex(pRect),
|
||||
returnObjects = this.objects;
|
||||
|
||||
//if we have subnodes, retrieve their objects
|
||||
if (this.nodes.length) {
|
||||
for (var i = 0; i < indexes.length; i++) {
|
||||
returnObjects = returnObjects.concat(this.nodes[indexes[i]].retrieve(pRect));
|
||||
}
|
||||
}
|
||||
|
||||
//remove duplicates
|
||||
returnObjects = returnObjects.filter(function (item, index) {
|
||||
return returnObjects.indexOf(item) >= index;
|
||||
});
|
||||
|
||||
return returnObjects;
|
||||
}
|
||||
|
||||
objLen() {
|
||||
|
||||
if (this.nodes.length > 0) {
|
||||
let len = 0;
|
||||
for (let node of this.nodes) {
|
||||
len += node.objLen();
|
||||
}
|
||||
return len;
|
||||
} else {
|
||||
//console.log('this.objects.length------',this.objects.length)
|
||||
return this.objects.length;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
9
assets/Scripts/common/QuadTree.ts.meta
Normal file
9
assets/Scripts/common/QuadTree.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "469a12f5-f4ff-4458-94aa-0a440aaa114b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
Reference in New Issue
Block a user