flash as3控制坐标旋转.docx_第1页
flash as3控制坐标旋转.docx_第2页
flash as3控制坐标旋转.docx_第3页
flash as3控制坐标旋转.docx_第4页
flash as3控制坐标旋转.docx_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

flash as3控制坐标旋转 2010-06-13 14:30第十章 坐标旋转及角度反弹本章介绍了一项特殊技术,著名的坐标旋转。如同其名,它是物体指绕着某点旋转其坐标,在制作一些非常有趣的效果时,坐标旋转是必不可少的。其中就包括在 Flash 界讨论了很多年的问题:“如何在斜面上进行反弹?”,本章我会给大家一一解答。另一个用坐标旋转完成的程序是两物体之间的交互反弹效果。我们会在下一章讨论动量守衡时进行讲解。而本章的坐标旋转,我们之前也已经接触过了。如果大家想跳过这章的话,我劝您还是先坐下来,浏览一遍为好。简单的坐标旋转虽然我们在第三章讲三角学的时候介绍过计算的坐标旋转的方法,但还是先来做一下回顾。假设知道一个中心点,一个物体,一个半径和一个角度。通过不断地增加或减少角度,并运用基本的三角学知识让物体绕着中心点旋转。我们可将变量设为 vr (旋转速度)来控制角度的增加或减少。还有,不要忘记角度应用弧度制来表示。代码的结构如下所示:vr = 0.1;angle = 0;radius = 100;centerX = 250;centerY = 200;/ 在 enterFrame 处理函数中:sprite.x = centerX + cos(angle) * radius;sprite.y = centerY + sin(angle) * radius;angle += vr;根据角度与半径使用简单的三角函数设置物体的 x,y 属性,并在每帧中改变角度。我们用 Flash 动画演示一下。下面是第一个例子,文档类 Rotate1.as:package import flash.display.Sprite;import flash.events.Event;public class Rotate1 extends Sprite private var ball:Ball;private var angle:Number = 0;private var radius:Number = 150;private var vr:Number = .05;public function Rotate1() init();private function init():void ball = new Ball();addChild(ball);addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):void ball.x = stage.stageWidth / 2 + Math.cos(angle) * radius;ball.y = stage.stageHeight / 2 + Math.sin(angle) * radius;angle += vr;这段代码中没有什么新的知识点。大家可以改变一下角度与半径,试验运行结果。但是如果我们只知道物体与中心点的位置又该怎么办呢?用 x,y 坐标计算出当前的角度(angle)与半径(radius)也并非难事。代码如下:var dx:Number = ball.x - centerX;var dy:Number = ball.y - centerY;var angle:Number = Math.atan2(dy, dx);var radius:Number = Math.sqrt(dx * dx + dy * dy);这种基于坐标的旋转只对单个物体的旋转效果比较好,尤其是一次性就可确定角度和半径的情况下。但是在动态的程序中,有时需要旋转多个物体,而它们与中心点的相对位置可能会发生改变。因此,对于每个物体来说,都需要计算距离,角度和半径,还要用 vr 来增加角度,最后才能算出新的 x,y 坐标,每帧都如此。这就显得太麻烦了,并且效率也不会很高。没关系,我们还有更好的办法。高级坐标旋转如果物体要绕着某一点旋转,并且以物体本身的位置作为旋转的起点,那么下面给大家一个公式。这个公式只需要给出物体距离中心点的相对 x,y 坐标和旋转的角度。它就会返回物体相对于中心点的新的坐标位置。基本公式如下:x1 = cos(angle) * x - sin(angle) * y;y1 = cos(angle) * y + sin(angle) * x;公式看上去像是一串相互对称的数字或符号,这是我刚刚接触它时的感觉。虽然使用这个公式很多次了,但依然有这样的感觉。我曾多次用图形来解释这些正弦余弦函数是如何让 x,y 变化的,每一次都会有全新的感觉。研究 30 分钟后,我发现这是两串非常对称的符号。虽然我通常都会给大家解释某项技术完整的概念,但是如果这次我还这样做的话,那我可能就是伪君子了。因为,就我个人而言,也只是将这个公式背下来,以便在做梦时能把它敲出来。如果您掌握的三角学的知道比我丰富的话,那当然最好,这样您也许会对这项技术有更深层的了解;不过,即使您不是制造火箭的科学家,那么只要记住这个公式,可以同样完成出色的效果。让我们看看这个公式都说了些什么,如图 10-1 所示。x,y 当然就是旋转后的坐标了。更准确地说,这是物体绕中心点旋转后的坐标。因此,如果中心点位于 200,100,而物体位于 300,150,那么 x 就是 300 200 = 100,y 就是 150 100 = 50。图10-1 坐标旋转角度(angle)就是某一时刻内旋转物体位置的大小。这并非当前的角度,也不是旋转后的角度,而是这两者之间的差值。换句话讲,如果物体在离中心点 45 度的位置,而这次的角度是 5 度,我们就要在当前角度的基础上再旋转 5 度,到达 50 度这个位置上。这里我们并不关心最初或最终的角度,只关心旋转了多少度。通常来讲,这个角度都是用弧度制表示的。OK,让我们来看例子吧。单物体旋转本例中将一个小球放在随机的位置上,并使用前面介绍的方法对它进行旋转(文档类 Rotate2.as):package import flash.display.Sprite;import flash.events.Event;public class Rotate2 extends Sprite private var ball:Ball;private var vr:Number = .05;private var cos:Number = Math.cos(vr);private var sin:Number = Math.sin(vr);public function Rotate2() init();private function init():void ball = new Ball();addChild(ball);ball.x = Math.random() * stage.stageWidth;ball.y = Math.random() * stage.stageHeight;addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):void var x1:Number = ball.x - stage.stageWidth / 2;var y1:Number = ball.y - stage.stageHeight / 2;var x2:Number = cos * x1 - sin * y1;var y2:Number = cos * y1 + sin * x1;ball.x = stage.stageWidth / 2 + x2;ball.y = stage.stageHeight / 2 + y2;在使用 vr 之前将它设成了 0.05,再计算这个角度的正弦和余弦值。根据小球与舞台中心点的位置计算出 x1 和 y1。然后使用前面讲到的坐标旋转公式,计算出小球的新位置 x2 和 y2。由于这个位置是小球与中心点的相对位置,所以我们还需要把 x2 和 y2 与中心点相加求出最终小球的位置。实验一下,我们发现这个例子与早先那个版本执行的结果是一样的。也许大家会问,既然功能完全一样,为什么还要使用这个看起来很复杂的公式呢?如果处理的内容非常简单,也许您的说法是正确的。下面让我们来看看这个公式在简化问题时的应用。首先,考虑多物体旋转的情况。来源:(/s/blog_3ecb9b1101009m4q.html) - 第十章 坐标旋转及角度反弹FL车在臣_FL车在臣_新浪博客 多物体旋转假设要旋转多个物体,所有的影片都保存在命为 sprites 的数组中。那么 for 循环应该是这样的:for (var i:uint = 0; i numSprites; i+) var sprite:Sprite = spritesi;var dx:Number = sprite.x - centerX;var dy:Number = sprite.y - centerY;var angle:Number = Math.atan2(dy, dx);var dist:Number = Math.sqrt(dx * dx + dy * dy);angle += vr;sprite.x = centerX + Math.cos(angle) * dist;sprite.y = centerY + Math.sin(angle) * dist;然而如果使用高级坐标旋转的方法应该是这样的:var cos:Number = Math.cos(vr);var sin:Number = Math.sin(vr);for (var i:uint = 0; i numSprites; i+) var sprite:Sprite = spritesi;var x1:Number = sprite.x - centerX;var y1:Number = sprite.y - centerY;var x2:Number = cos * x1 - sin * y1;var y2:Number = cos * y1 + sin * x1;sprite.x = centerX + x2;sprite.y = centerY + y2;请注意第一个版本中我们在 for 循环里调用了四次 Math 函数,这意味着每个物体的旋转都要执行四次函数调用。第二个版本中只执行了两次函数调用,而且都是在 for 循环以外面执行的,意味着它们只执行了一次,与物体的数量无关。举个例子,如果我们有 30 个影片,如果使用第一个版本的代码每帧需要调用 120 次 Math 函数。大家可以想想哪个版本的效率最高。在前上一个例子程序中,删去 enterFrame 中的 sin 和 cos 函数。这是因为这段程序中的角度是固定的,因此可以直接给出结果。但是在很多情况下,旋转的角度不是固定不变的,这就需要每次进行重新计算正余弦的值。解释一下最后这个概念。举个例子,用鼠标位置控制多个物体旋转的速度。如果鼠标在屏幕中心,则不产生旋转。如果鼠标向左移动,则物体逆时针旋转,并且越向左速度越快。如果向右移动,则顺时针旋转。除了创建多个 Ball 实例,并以数组存储以外,这个例子与前面那个非常相似。下面是文档类(Rotation3.as):package import flash.display.Sprite;import flash.events.Event;public class Rotate3 extends Sprite private var balls:Array;private var numBalls:uint = 10;private var vr:Number = .05;public function Rotate3() init();private function init():void balls = new Array();for (var i:uint = 0; i numBalls; i+) var ball:Ball = new Ball();balls.push(ball);addChild(ball);ball.x = Math.random() * stage.stageWidth;ball.y = Math.random() * stage.stageHeight;addEventListener(Event.ENTER_FRAME, onEnterFrame);private function onEnterFrame(event:Event):void var angle:Number = (mouseX - stage.stageWidth / 2) * .001;var cos:Number = Math.cos(angle);var sin:Number = Math.sin(angle);for (var i:uint = 0; i -ball.height / 2) y2 = -ball.height / 2;vy1 *= bounce;/ 将一切旋转回去x1 = cos * x2 - sin * y2;y1 = cos * y2 + sin * x2;ball.vx = cos * vx1 - sin * vy1;ball.vy = cos * vy1 + sin * vx1;ball.x = line.x + x1;ball.y = line.y + y1;开始,声明变量 ball,line,gravity,bounce。在 enterFrame 函数中执行基本运动代码。然后,获得 line 的角度并转化为弧度制。有了角度,就可以求出正余弦的值。接下来,用 ball 的位置减去 line 的位置,获得 ball 的 x,y 与 line 的相对位置。下面,准备对物体进行旋转!在看到这两代码时,注意到好像是错的。/ 旋转坐标var x2:Number = cos * x1 + sin * y1;var y2:Number = cos * y1 - sin * x1;这里的加号与减号与最初的坐标旋转公式是相反的,最初我们的公式是:x1 = cos(angle) * x - sin(angle) * y;y1 = cos(angle) * y + sin(angle) * x;这并没

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论