`

[转] 高效的格子碰撞检测算法

 
阅读更多

  1. package{ 
  2.         import flash.display.DisplayObject; 
  3.         import flash.display.Graphics; 
  4.         import flash.events.EventDispatcher; 
  5.          
  6.         public class CollisionGrid extends EventDispatcher 
  7.         { 
  8.         private var _checks:Vector.<DisplayObject>; 
  9.         private var _grid:Vector.<Vector.<DisplayObject>>; 
  10.         private var _gridSize:Number; 
  11.         private var _height:Number; 
  12.         private var _numCells:int; 
  13.         private var _numCols:int; 
  14.         private var _numRows:int; 
  15.         private var _width:Number; 
  16.                          
  17.         public function CollisionGrid(width:Number, height:Number, gridSize:Number) 
  18.         { 
  19.                 _width = width; 
  20.                 _height = height; 
  21.                 _gridSize = gridSize; 
  22.                 _numCols = Math.ceil(_width / _gridSize); 
  23.                 _numRows = Math.ceil(_height / _gridSize); 
  24.                 _numCells = _numCols * _numRows; 
  25.         }        
  26.         public function drawGrid(graphics:Graphics):void 
  27.         { 
  28.         graphics.lineStyle(0, .5); 
  29.         for(var i:int = 0; i <= _width; i += _gridSize) 
  30.         { 
  31.           graphics.moveTo(i, 0); 
  32.           graphics.lineTo(i, _height); 
  33.         } 
  34.         for(i = 0; i <= _height; i += _gridSize) 
  35.         { 
  36.           graphics.moveTo(0, i); 
  37.           graphics.lineTo(_width, i); 
  38.         }                        
  39.         } 
  40.         public function check(objects:Vector.<DisplayObject>):void 
  41.         { 
  42.           var numObjects:int = objects.length; 
  43.           _grid = new Vector.<Vector.<DisplayObject>>(_numCells); 
  44.           _checks = new Vector.<DisplayObject>(); 
  45.         for(var i:int = 0; i < numObjects; i++) 
  46.         { 
  47.           var obj:DisplayObject = objects[i]; 
  48. var index:int=Math.floor(obj.y / _gridSize)*_numCols+Math.floor(obj.x /_gridSize); 
  49.           if(_grid[index] == null) _grid[index] = new Vector.<DisplayObject>;
  50.           _grid[index].push(obj); 
  51.         } 
  52.                            checkGrid(); 
  53.         } 
  54.         private function checkGrid():void 
  55.         { 
  56.         for(var i:int = 0; i < _numCols; i++) 
  57.         { 
  58.                 for(var j:int = 0; j < _numRows; j++) 
  59.                 { 
  60.                         checkOneCell(i, j); 
  61.                         checkTwoCells(i, j, i + 1, j); 
  62.                         checkTwoCells(i, j, i - 1, j + 1); 
  63.                         checkTwoCells(i, j, i,     j + 1); 
  64.                         checkTwoCells(i, j, i + 1, j + 1); 
  65.                 } 
  66.         } 
  67.         } 
  68.         private function checkOneCell(x:int, y:int):void 
  69.         { 
  70.                 var cell:Vector.<DisplayObject> = _grid[y * _numCols + x]; 
  71.                 if(cell == null) return; 
  72.                  
  73.                 var cellLength:int = cell.length; 
  74.                 for(var i:int = 0; i < cellLength - 1; i++) 
  75.                 { 
  76.                         var objA:DisplayObject = cell[i]; 
  77.                         for(var j:int = i + 1; j < cellLength; j++) 
  78.                         { 
  79.                                 var objB:DisplayObject = cell[j]; 
  80.                                 _checks.push(objA, objB); 
  81.                         } 
  82.                 } 
  83.         } 
  84.         private function checkTwoCells(x1:int, y1:int, x2:int, y2:int):void 
  85.         { 
  86.                 if(x2 >= _numCols || x2 < 0 || y2 >= _numRows) return; 
  87.                 var cellA:Vector.<DisplayObject> = _grid[y1 * _numCols + x1];
  88.                 var cellB:Vector.<DisplayObject> = _grid[y2 * _numCols + x2];
  89.                 if(cellA == null || cellB == null) return; 
  90.                  
  91.                 var cellALength:int = cellA.length; 
  92.                 var cellBLength:int = cellB.length; 
  93.                 for(var i:int = 0; i < cellALength; i++) 
  94.                 { 
  95.                         var objA:DisplayObject = cellA[i]; 
  96.                         for(var j:int = 0; j < cellBLength; j++) 
  97.                         { 
  98.                                 var objB:DisplayObject = cellB[j]; 
  99.                                 _checks.push(objA, objB); 
  100.                         } 
  101.                 } 
  102.         } 
  103.         public function get checks():Vector.<DisplayObject> 
  104.         { 
  105.                 return _checks; 
  106.         } 
  107.         } 
  108. }
复制代码
Vector 的使用。Vector是 Flash10 的新内容,相当于一个具有类型的数组。由于编译器知道 vector 中的每个元素都是同样的类型,所以就能为之创建出更有效的字节码,从而提高执行效率。 
以这段程序为例,从数组改为 vector 差不多使运行效率翻了一倍。 
drawGrid 函数一点没变,它依旧用来画出网格。 
check 函数是这个类对外交互的主要函数。其接收参数的类型是元素类型为 DisplayObject
的 vector。 
选择 Displayobject 的原因是因为碰撞检测通常用于 Sprite,MovieClip,Shape 和Bitmap
而这些类都继承自 Displayobject。Displayobject 也有x和y 两个位置属性。 
所以要用自定义的对象时,请确保继承自 Displayobject。 
函数一开始定义了一个名为_grid 的 vector,还有一个名为_checks 的 vector。 
_grid 应该不陌生,但在实现上有点不同,这里用一维 vector 加索引技巧取代了二维数组。 
因为这么做,可以使访问元素速度更快并减少了循环。等下会有详细介绍。 
_checks 用来保存需要进行碰撞检测的对象。注意 CollisionGrid 类不处理具体的碰撞检测,它只
用来创建网格,分配对象,以及生成一组需要被检测的对象。具体的碰撞检测算法由你而定。 
接着,check 函数对给定的 vector 进行遍历,把其中每个 Displayobject 都分配进网格。

分享到:
评论

相关推荐

    矩阵碰撞算法

    通过高效地处理大量物体间的碰撞检测,该算法可以提升游戏性能并保证交互的精确性。本文将深入探讨矩阵碰撞算法的基本原理、实现方法及其在实际应用中的优化策略。 一、矩阵碰撞算法简介 矩阵碰撞算法的核心思想是...

    3D游戏碰撞检测解决方案

    总的来说,3D游戏的碰撞检测是一个涉及多种算法和技术的复杂领域,包括但不限于格子系统、BSP树、BVTree、离散点检测和连续碰撞检测。在实际应用中,开发者需要根据游戏需求和性能要求选择合适的碰撞检测方案,并...

    JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解

    地图格子算法是一种常用的碰撞检测方法,尤其适用于RPG、SLG和PUZ类游戏。这种算法通过将地图划分为小的格子,简化了复杂的碰撞判断,提高了效率。 在早期的游戏设计中,地图通常由一系列编号的格子组成,这些格子...

    Java实现小球碰撞检测

    在计算机图形学中,模拟物体间的...通过理解向量运算、碰撞检测算法以及冲量守恒,我们可以构建出一个准确且高效的碰撞检测系统。在实际应用中,还需要考虑到各种边界条件和优化策略,以适应更复杂的游戏或模拟环境。

    android 两球或多球碰撞检测实例

    在2D环境中,通常使用矩形或圆形作为简化物体的边界模型,因为这两种形状的碰撞检测相对简单且高效。 1. **两球碰撞检测**:两球碰撞检测主要基于几何原理。若球A的中心坐标为(x1, y1),半径为r1,球B的中心坐标为...

    as3算法大全

    在页游中,碰撞检测、路径规划等图形与几何算法非常常见。A*寻路算法是寻找游戏对象最短路径的有效方法,而基于矩形、圆形或多边形的碰撞检测则能保证游戏逻辑的准确性。 五、动态规划与贪心算法 这两种算法在解决...

    两个实体之间的碰撞

    3. **碰撞检测算法**:选择适合的碰撞检测算法,如轴对齐边界框(AABB,Axis-Aligned Bounding Box)检测,用于矩形;或最小包围球(Minimum Enclosing Sphere)检测,用于圆形。 - AABB检测:比较两个矩形的边界...

    检测圆球碰撞

    文件"aotoball"可能是游戏源代码的一部分,可能包含了实现这些碰撞检测算法的具体Java代码。分析和理解这段代码可以帮助开发者更好地掌握在J2ME平台上实现圆球碰撞检测的方法。 总的来说,"检测圆球碰撞"是J2ME游戏...

    常用算法 python 棋盘 TSP 多边形游戏

    处理多边形的游戏算法可能包括碰撞检测、图形渲染和物理模拟等。Python虽然不是游戏开发的首选语言,但通过Pygame等库,可以创建简单的2D游戏,理解多边形的相关概念。 在Python中实现这些算法,我们需要了解基本的...

    基于GPU加速的空间哈希算法实现-附项目源码-优质项目实战.zip

    空间哈希算法是一种在计算机图形学和计算几何领域广泛应用的数据结构和算法,它主要用于高效地进行碰撞检测、近邻查找等任务。在这个基于GPU加速的空间哈希算法实现的项目中,我们将深入探讨如何利用现代GPU的强大...

    Unity-DOTS-RTS-Collision-System:基本的RTS碰撞系统

    - 在RTS游戏中,可能有大量单位同时移动和碰撞,因此需要高效的碰撞检测算法。常见的有广义相交测试(GJK)、分离轴定理(SAT)和包围盒检测(AABB)等。DOTS下的碰撞检测可能采用多线程处理,以充分利用现代多核...

    安卓Android源码——(圆形碰撞).zip

    通过分析解压后的"4-14-2(圆形碰撞)"文件,我们可以学习到如何将上述理论知识应用到实际的Android项目中,包括数据结构的设计、碰撞检测算法的实现以及与UI的交互。这个示例代码对于初学者和有经验的开发者来说都是...

    Algorithm-constellations.zip

    在这个项目中,开发者可能采用了某种碰撞检测算法,比如基于距离场的碰撞检测或者使用格子数据结构进行近似碰撞查询,以实现粒子间的精确碰撞并保持系统的流畅运行。 接下来,我们要关注的是四叉树这一数据结构。四...

    Cocos2d-x 地图行走的实现3:A*算法

    - **定义可达性**:为每个节点定义是否可以行走,这可以通过遍历地图数据或使用特定的碰撞检测来实现。 - **计算G值和H值**:为每个节点分配初始G值为0,H值根据启发式函数计算。 - **循环寻找路径**:执行A*算法...

    基于c++MFC实现的小球碰撞

    为了实现碰撞检测,程序可能使用了某种形式的空间分区算法,如格子法或者四叉树,以便高效地找出可能相撞的小球对。一旦找到可能的碰撞,就需要用到碰撞响应算法来计算碰撞后的速度。这个过程可能涉及到复杂的数学,...

    45度角地图人物行走寻路

    最后,还会涉及到人物在地图上的移动逻辑,比如碰撞检测和动画更新。 工具方面,开发者可能使用了各种编程语言(如C++、C#、JavaScript)和游戏开发框架(如Unity、Unreal Engine、Godot等)来实现这一功能。这些...

    基于matlab实现的粒子群优化算法,通过栅格法实现移动机器人路径规划.rar

    - 编写自定义函数计算适应度值,这可能涉及距离计算、碰撞检测等。 - 结合MATLAB的可视化功能,可以绘制出粒子群的动态搜索过程和最终的最优路径。 4. **优化与改进**: - 惯性权重调整:为了平衡全局探索和局部...

    PseudoAJAssign3

    《Java实现2D碰撞检测:PseudoAJAssign3解析》 在计算机图形学和游戏开发领域,2D碰撞检测是一项核心技术,它涉及到物体...通过学习和分析这个程序,我们可以更好地理解和应用2D碰撞检测算法,提升我们的编程技能。

    格子网格上的公共域线性时间距离场和Voronoi图_C_.zip

    在线性时间距离场上,计算这些距离的过程可以在O(n)的时间复杂度内完成,这使得LTDFs非常适用于实时渲染和碰撞检测等对性能要求高的应用。在3D环境中,LTDFs通常存储在格子网格上,因为这种数据结构可以有效地支持...

    C语言写的推箱子游戏

    这就需要实现碰撞检测算法,判断每次移动是否合法。 4. **推箱子逻辑**:玩家只能推动相邻且非墙的箱子,且推后的格子必须为空。这一部分的算法较为复杂,需要检查玩家与箱子之间的相对位置以及目标格子的状态。 5...

Global site tag (gtag.js) - Google Analytics