games/Legend-of-the-Water-Cup/assets/scripts/CollisionGrid.ts

103 lines
3.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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) {}
}