• 基于网格的碰撞检测


    1)碰撞检测有两种常用方法:将所有物件两两测试,当物件数量少的时候,用这种方式既简单又快速; 基于网格检测,先将整个区域划分成格子,再基于格子检测,遍历所有格式,先检查本格中的所有物件,再将本格和相邻格中的物件一一检测,当物件数量多时,需要用这种方式进行检测,将大大减少检测数量;

    2)划分格式时,应确保格子的尺寸比“最大的物件”尺寸还要大,必须能保证格式一定能将物件包住;

    3)每个格子在检测时,只用检测“右边”、”左下边“、”下边“、”右下边“这四个格子就行,不用检测周边的八个格子;

    4) 用一维数组来保存格子,通过在索引上做文章来识别它以属于第几行,这样能提高性能。

    ==========================================

    private function checkGrid(): void

    {

    for(var i: int=0; i < _grid.length; i++)

    {

    for(var j: int=0; j < _grid[ i ].length; 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:Array = _grid[ x ][ y ] as Array;

    for(var i: int=0; i < cell.length-1; i++)

    {

    var ballA: Ball = cell[ i ] as Ball;

    for(var j: int=i+1; j < cell.length; j++)

    {

    var ballB: Ball = cell[ j ] as Ball;

    checkCollision(ballA, ballB);

    }

    }

    }



    private function checkTwoCells(x1: int, y1: int, x2: int, y2: int): void

    {

    // 确保要检测的格子存在

    if(x2 < 0) return;

    if(x2 >= _grid.length) return;

    if(y2 >= _grid[ x2 ].length) return;

    var cell0:Array = _grid[ x1 ][ y1 ] as Array;

    var cell1:Array = _grid[ x2 ][ y2 ] as Array;

    // 检测当前格子和邻接格子内所有的对象

    for(var i: int=0; i < cell0.length; i++)

    {

    var ballA: Ball = cell0[ i ] as Ball;

    for(var j: int=0; j < cell1.length; j++)

    {

    var ballB: Ball = cell1[ j ] as Ball;

    checkCollision(ballA, ballB);

    }

    }

    }


    private function checkCollision(ballA: Ball, ballB: Ball):void

    {

    // 判断距离的碰撞检测

    _numChecks++;

    var dx: Number = ballB.x - ballA.x;

    var dy: Number = ballB.y - ballA.y;

    var dist: Number = Math.sqrt(dx * dx + dy * dy);

    if(dist < ballA.radius + ballB.radius)

    {

    ballA.color = 0xff0000;

    ballB.color = 0xff0000;

    }

    }

  • 相关阅读:
    (转) Linux下Setuid命令!
    Linux SWAP 交换分区配置说明(转)
    linux中ctime,mtime,atime的区别
    无法访问win8默认共享(如C$)解决办法
    Daemon进程
    autofs文件自动挂载系统
    Selinux相关
    解读linux中用户密码规则及忘记root口令的破解(思路)
    windows共享连接显示无法打开
    DOS口令启用停用的管理员密码
  • 原文地址:https://www.cnblogs.com/cly84920/p/4426544.html
Copyright © 2020-2023  润新知