103 lines
3.9 KiB
TypeScript
103 lines
3.9 KiB
TypeScript
export default class CollisionGrid {
|
||
private _checks: Array<cc.Node>;//用于保存需要碰撞检测的对象(注:Vector.<T>相当于c#中的泛型数组)
|
||
private _grid: Array<Array<cc.Node>>;//网格(注:这里用“一维数组套一维数组”的方法替代了原来的二维数组)
|
||
private _gridSize: number;
|
||
private _height: number;
|
||
private _numCells: number;
|
||
private _numCols: number;
|
||
private _numRows: number;
|
||
private _width: number;
|
||
private offsetX:number;//坐标问题
|
||
private offsetY:number;//坐标问题
|
||
constructor(width: number, height: number, gridSize: number) {
|
||
this._width = width;
|
||
this._height = height;
|
||
this._gridSize = gridSize;
|
||
|
||
this._numCols = Math.ceil(width / gridSize);//计算总列数
|
||
this._numRows = Math.ceil(height / gridSize);//计算总行数
|
||
this._numCells = this._numCols * this._numRows;//单元格总数
|
||
var size = cc.view.getVisibleSize();
|
||
this.offsetX=size.width*0.5
|
||
this.offsetY=size.height*0.5
|
||
}
|
||
//将需要检测的对象(泛型)数组objects分配到网络
|
||
public assign(objects) {
|
||
var numObjects: number = objects.length;
|
||
this._grid = [];
|
||
this._checks = [];
|
||
for (var i: number = 0; i < numObjects; i++) {
|
||
var obj: cc.Node = objects[i];
|
||
var tx=obj.x+this.offsetX
|
||
var ty=obj.y+this.offsetY
|
||
//注意:这里用“Grid.[索引]”(定位)的方式,替换了原来的“Grid.[列][行]”(单元格的定位)方式--回想一下bitmap位图中的像素索引就更容易理解了
|
||
var index: number = Math.floor(ty / this._gridSize) * this._numCols + Math.floor(tx / this._gridSize);
|
||
//“单元格”--延时实例化"
|
||
if (this._grid[index] == null) {
|
||
this._grid[index] = [];
|
||
}
|
||
//将对象推入"单元格"
|
||
this._grid[index].push(obj);
|
||
}
|
||
|
||
//检测需要碰撞的对象,并保存到_checks数组
|
||
this.checkGrid();
|
||
}
|
||
|
||
//"单元格"检测
|
||
private checkGrid(): void {
|
||
for (var i: number = 0; i < this._numCols; i++) {
|
||
for (var j: number = 0; j < this._numRows; j++) {
|
||
this.checkOneCell(i, j);
|
||
this.checkTwoCells(i, j, i + 1, j);
|
||
this.checkTwoCells(i, j, i - 1, j + 1);
|
||
this.checkTwoCells(i, j, i, j + 1);
|
||
this.checkTwoCells(i, j, i + 1, j + 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
//(自身)单个单元格的检测
|
||
private checkOneCell(x: number, y: number): void {
|
||
var cell: Array<cc.Node> = this._grid[y * this._numCols + x];
|
||
if (cell == null) {
|
||
return;
|
||
}
|
||
var cellLength: number = cell.length;
|
||
|
||
for (var i: number = 0; i < cellLength - 1; i++) {
|
||
var objA: cc.Node = cell[i];
|
||
for (var j: number = i + 1; j < cellLength; j++) {
|
||
var objB: cc.Node = cell[j];
|
||
this._checks.push(objA, objB);
|
||
}
|
||
}
|
||
}
|
||
|
||
//单元格(x1,y1)与单元格(x2,y2)的检测
|
||
private checkTwoCells(x1: number, y1: number, x2: number, y2: number): void {
|
||
if (x2 >= this._numCols || x2 < 0 || y2 >= this._numRows) {
|
||
return;
|
||
}
|
||
var cellA = this._grid[y1 * this._numCols + x1];
|
||
var cellB = this._grid[y2 * this._numCols + x2];
|
||
if (cellA == null || cellB == null) {
|
||
return;
|
||
}
|
||
var cellALength: number = cellA.length;
|
||
var cellBLength: number = cellB.length;
|
||
for (var i: number = 0; i < cellALength; i++) {
|
||
var objA: cc.Node = cellA[i];
|
||
for (var j: number = 0; j < cellBLength; j++) {
|
||
var objB: cc.Node = cellB[j];
|
||
this._checks.push(objA, objB);
|
||
}
|
||
}
|
||
}
|
||
|
||
public get checks() {
|
||
return this._checks;
|
||
}
|
||
// update (dt) {}
|
||
}
|