首页 > 代码库 > ActionScript3游戏中的图像编程(连载六十七)

ActionScript3游戏中的图像编程(连载六十七)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477

4.2.3 使用Matrix类实现图形变换


      我们在ActionScript里new一个Matrix,它将是一个单位矩阵,a和d=1,其余4个属性都为0:

 

     
 
      如果将这样的matrix应用到显示对象上,显示对象将不发生任何变化。


      下面我们开始写实例来做测试。


      新建一个ActionScript项目,名为MatrixTransformTest,代码如下:


 

package{ import flash.display.*; import flash.geom.Matrix;  public class MatrixTransformTest extends Sprite{    //矩形形状  private var _shape:Shape;    public function MatrixTransformTest() {   init();  }    private function init():void{      stage.scaleMode = StageScaleMode.NO_SCALE;   stage.align = StageAlign.TOP_LEFT;      _shape = new Shape();   //绘制了一个矩形   _shape.graphics.beginFill(0, 1);   _shape.graphics.drawRect(0, 0, 100, 50);   _shape.graphics.endFill();//画两条对角线   _shape.graphics.lineStyle(1, 0x00CC00);   _shape.graphics.moveTo(0, 0);   _shape.graphics.lineTo(100, 50);   _shape.graphics.moveTo(100, 0);   _shape.graphics.lineTo(0, 50);   var mt:Matrix = new Matrix();   //应用变换矩阵   _shape.transform.matrix = mt;   addChild(_shape);  } }}


        为了更清楚地观察矩阵的变换,我这里就不用圆形了,而以矩形代之。同时绘制了两条对角线以便准确查看中心点的位置。


        运行以后,舞台左上角将显示出一个100*50的黑色矩形(图 4.4),它没有发生任何变换。


 

图 4.4 应用单位矩阵,矩形的形状没有发生变化


        我们做最简单的平移变换看看:


 

mt.tx = 30;mt.ty = 60;


 

      将这两行代码置于_shape.transform.matrix = mt;一句的前面,将得到如图 4.5的效果。
 

图 4.5 设置tx和ty的效果


      可见,所有点都同时向右和向下偏移了30个像素,每个点之间的相对位置并没有发生变化,所以形状不变。


      在这一过程中,每个点都做了如下的运算:

 

     
 
      下面把tx和ty的变换去掉,我们尝试一下旋转30度:
      30度的弧度值是Math.PI/6,代入到旋转矩阵:


       ——a=cosθ,b=sinθ,c=-sinθ,d=cosθ


      得到

mt.a = Math.cos(Math.PI / 6);mt.b = Math.sin(Math.PI / 6);mt.c = -Math.sin(Math.PI / 6);mt.d = Math.cos(Math.PI / 6);



      替换掉代码里的tx,ty,得到如图 4.6的结果。

 

图 4.6 应用30度旋转矩阵的结果


      旋转是旋转了,但这往往不是我们想要的,因为它没有绕矩形的中心点旋转。在Matrix中,旋转,缩放的参考点都是(0,0),在舞台的坐标系里就相当于左上角了。


      至于如何修改参考点的位置,我一直苦寻未果(不过fl包中的MatrixTransformer类实现了这种算法,有兴趣的读者可以自行研究),既然无法改变,那么我们就尝试着去适应,把矩形的中心点对齐到参考点怎样?嗯,试试。


 

mt.tx = -100;mt.ty = -50;mt.a = Math.cos(Math.PI / 6);mt.b = Math.sin(Math.PI / 6);mt.c = -Math.sin(Math.PI / 6);mt.d = Math.cos(Math.PI / 6);



      并没有达到预期的效果(图 4.6),我们知道,如果先旋转再平移,是一定得不到正确结果的,因为旋转后的中心点已经不再是(-50,-25)了。

 

图 4.7 tx和ty移向中心后再旋转


      那么我们把tx和ty放到后面:

mt.a = Math.cos(Math.PI / 6);mt.b = Math.sin(Math.PI / 6);mt.c = -Math.sin(Math.PI / 6);mt.d = Math.cos(Math.PI / 6);mt.tx = -100;mt.ty = -50;



      很显然,尽管顺序调换了,但从设置属性的角度上看,这样的对调实际上没有任何意义,它的运行结果跟调换前完全一致。


      怎么办呢?难道要自己手动计算转换后中心点的位置?如果真要这样做,矩阵的存在便形同虚设了。


      矩阵变换的精髓就在于多个变换的合并以及乘法的不可逆性,我们应该把它的优势给发挥出来。

 

 

ActionScript3游戏中的图像编程(连载六十七)