package { import flash.display.DisplayObject; import flash.display.Graphics; import flash.events.EventDispatcher; public class CollisionGrid extends EventDispatcher { private var _checks:Vector.;//用于保存需要碰撞检测的对象(注:Vector.相当于c#中的泛型数组) private var _grid:Vector.>;//网格(注:这里用“一维数组套一维数组”的方法替代了原来的二维数组) private var _gridSize:Number; private var _height:Number; private var _numCells:int; private var _numCols:int; private var _numRows:int; private var _width:Number; public function CollisionGrid(width:Number, height:Number, gridSize:Number) { _width=width; _height=height; _gridSize=gridSize; _numCols=Math.ceil(_width/_gridSize);//计算总列数 _numRows=Math.ceil(_height/_gridSize);//计算总行数 _numCells=_numCols*_numRows;//单元格总数 } //画格子 public function drawGrid(graphics:Graphics):void { graphics.lineStyle(0, .5); for (var i:int = 0; i <= _width; i += _gridSize) { graphics.moveTo(i, 0); graphics.lineTo(i, _height); } for (i = 0; i <= _height; i += _gridSize) { graphics.moveTo(0, i); graphics.lineTo(_width, i); } } //将需要检测的对象(泛型)数组objects分配到网络 public function assign(objects:Vector.):void { var numObjects:int=objects.length; _grid=new Vector.>(_numCells); _checks = new Vector.(); for (var i:int = 0; i < numObjects; i++) { var obj:DisplayObject=objects[i]; //注意:这里用“Grid.[索引]”(定位)的方式,替换了原来的“Grid.[列][行]”(单元格的定位)方式--回想一下bitmap位图中的像素索引就更容易理解了 var index:int=Math.floor(obj.y/_gridSize)*_numCols+Math.floor(obj.x/_gridSize); //“单元格”--延时实例化" if (_grid[index]==null) { _grid[index]=new Vector. ; } //将对象推入"单元格" _grid[index].push(obj); } //检测需要碰撞的对象,并保存到_checks数组 checkGrid(); } //"单元格"检测 private function checkGrid():void { for (var i:int = 0; i < _numCols; i++) { for (var j:int = 0; j < _numRows; j++) { checkOneCell(i, j); checkTwoCells(i, j, i + 1, j); checkTwoCells(i, j, i - 1, j + 1); checkTwoCells(i, j, i, j + 1); checkTwoCells(i, j, i + 1, j + 1); } } } //(自身)单个单元格的检测 private function checkOneCell(x:int, y:int):void { var cell:Vector.=_grid[y*_numCols+x]; if (cell==null) { return; } var cellLength:int=cell.length; for (var i:int = 0; i < cellLength - 1; i++) { var objA:DisplayObject=cell[i]; for (var j:int = i + 1; j < cellLength; j++) { var objB:DisplayObject=cell[j]; _checks.push(objA, objB); } } } //单元格(x1,y1)与单元格(x2,y2)的检测 private function checkTwoCells(x1:int, y1:int, x2:int, y2:int):void { if (x2>=_numCols||x2<0||y2>=_numRows) { return; } var cellA:Vector.=_grid[y1*_numCols+x1]; var cellB:Vector.=_grid[y2*_numCols+x2]; if (cellA==null||cellB==null) { return; } var cellALength:int=cellA.length; var cellBLength:int=cellB.length; for (var i:int = 0; i < cellALength; i++) { var objA:DisplayObject=cellA[i]; for (var j:int = 0; j < cellBLength; j++) { var objB:DisplayObject=cellB[j]; _checks.push(objA, objB); } } } public function get checks():Vector. { return _checks; } } }