关于tink的碰撞检测类【3】

个人认为这个类存在错误,这些错误又集中出现在最后一个方法getDrawMatrix()里,因此把源码copy下来直接注释:

               protected static functiongetDrawMatrix( target:DisplayObject, hitRectangle:Rectangle,accurracy:Number ):Matrix
               {
                       var localToGlobal:Point;;
                       var matrix:Matrix;
                      
                       var rootConcatenatedMatrix:Matrix =target.root.transform.concatenatedMatrix;
                       //虽然下面这句隐含错误,但很喜欢它的妙处。这句让我来写,肯定是
                       //
localToGlobal =target.parent.localToGlobal( new Point( target.x,target.y));
                       localToGlobal = target.localToGlobal( new Point( ) );
                       matrix = target.transform.concatenatedMatrix;
                  //整个类是以root为标准参考坐标系的,下面的localToGloba显然使用stage坐标系,
                  //hitRectangle使用root坐标系,当root相对stage原点没有偏移时,这个错误体现不出来,
                   //只需在文档类加一句"this.root.x+=50;",就会发现碰撞检测的结果不准确。
                       matrix.tx = localToGlobal.x - hitRectangle.x;
                       matrix.ty = localToGlobal.y - hitRectangle.y;
                       //下面两句的目的是,将target的concatenatedMatrix剔除掉root缩放变换的影响,以
                   //此得到target相对于root的记录矩阵。但直接设置a,d值来实现scale功能是危险的,
                  // 当matrix的b,c值不为0(即发生旋转变换时),这个操作并不等效与scale操作.
                  // 很多人都反应他们测试旋转的对象依然准确,为什么呢?因为rootConcatenatedMatrix的
                  // a,d值通常为1,下面两条语句等于什么都没做,错误便被隐藏.
                  // 只需在文档类加一句"this.scaleX=2",就会发现对旋转物体的碰撞检测不准确.
                       matrix.a = matrix.a / rootConcatenatedMatrix.a;
                       matrix.d = matrix.d / rootConcatenatedMatrix.d;
                       if ( accurracy != 1 ) matrix.scale( accurracy, accurracy );
                  //不知道tink为什么要以root为统一参考坐标系,用stage的话,整个类会简洁很多,能节省
                  //繁琐的坐标转换操作,并且我也看不到root比stage具备哪些优势(只是我看不到,相信
                  //应该是有的,不然,使用root完全是自找苦吃了)。
                       return matrix;
               }

仍旧以root为坐标系,我把这个方法修改一下,思路是在target的concatenatedMatrix矩阵左边乘上root的逆矩阵,以此将target转换到root参考坐标系。代码如下:

 protected static function getDrawMatrix(target:DisplayObject, hitRectangle:Rectangle, accurracy:Number):Matrix
               {
                       var rootConcatenatedMatrix:Matrix =target.root.transform.matrix.clone();
                       var matrix:Matrix =target.transform.concatenatedMatrix.clone();
                  rootConcatenatedMatrix.invert();
                  
                  matrix.concat(rootConcatenatedMatrix);
                   matrix.tx =matrix.tx- hitRectangle.x;
                   matrix.ty =matrix.ty - hitRectangle.y;
                   if( accurracy != 1 ) matrix.scale( accurracy,accurracy );
                       return matrix;
               }
经过测试,这种方法能够适应root的旋转,缩放,平移操作。
另外在测试时发现,碰撞检测时不能够用鼠标拉伸或缩小窗口,否则检测结果不准确。我猜测原因是影响到target的concatenatedMatrix的取值了吧。

posted on 2012-08-16 16:00  weiweishuo  阅读(144)  评论(0)    收藏  举报

导航