首页 > 代码库 > 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游戏中的图像编程(连载六十七)