资源预览内容
第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
第9页 / 共10页
第10页 / 共10页
亲,该文档总共10页全部预览完了,如果喜欢就下载吧!
资源描述
flashflash as3as3 控制坐标旋转控制坐标旋转 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-110-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; privateprivate varvar cos:Numbercos:Number = = Math.cos(vr);Math.cos(vr); privateprivate varvar sin:Numbersin:Number = = Math.sin(vr);Math.sin(vr); public function Rotate2() init(); private function init():void ball = new Ball(); addChild(ball); ball.xball.x = = Math.random()Math.random() * * stage.stageWidth;stage.stageWidth; ball.yball.y = = Math.random()Math.random() * * stage.stageHeight;stage.stageHeight; addEventListener(Event.ENTER_FRAME, onEnterFrame); private function onEnterFrame(event:Event):void varvar x1:Numberx1:Number = = ball.xball.x - - stage.stageWidthstage.stageWidth / / 2;2; varvar y1:Numbery1:Number = = ball.yball.y - - stage.stageHeightstage.stageHeight / / 2;2; varvar x2:Numberx2:Number = = coscos * * x1x1 - - sinsin * * y1;y1;varvar y2:Numbery2:Number = = coscos * * y1y1 + + sinsin * * x1;x1; ball.xball.x = = stage.stageWidthstage.stageWidth / / 2 2 + + x2;x2; ball.yball.y = = stage.stageHeightstage.stageHeight / / 2 2 + + y2;y2; 在使用 vr 之前将它设成了 0.05,再计算这个角度的正弦和余弦值。根据小球与舞台中心 点的位置计算出 x1 和 y1。然后使用前面讲到的坐标旋转公式,计算出小球的新位置 x2 和 y2。由于这个位置是小球与中心点的相对位置,所以我们还需要把 x2 和 y2 与中心点 相加求出最终小球的位置。 实验一下,我们发现这个例子与早先那个版本执行的结果是一样的。也许大家会问,既然 功能完全一样,为什么还要使用这个看起来很复杂的公式呢?如果处理的内容非常简单, 也许您的说法是正确的。下面让我们来看看这个公式在简化问题时的应用。首先,考虑多 物体旋转的情况。来源:(http:/blog.sina.com.cn/s/blog_3ecb9b1101009m4q.html) - 第十章 坐标旋转 及角度反弹FL 车在臣_FL 车在臣_新浪博客 多物体旋转多物体旋转假设要旋转多个物体,所有的影片都保存在命为 sprites 的数组中。那么 for 循环应该 是这样的:for (var i:uint = 0; i -ball.height-ball.height / / 2)2) y2y2 = = -ball.height-ball.height / / 2;2; vy1vy1 *=*= bounce;bounce; / 将一切旋转回去将一切旋转回去x1x1 = = coscos * * x2x2 - - sinsin * * y2;y2; y1y1 = = coscos * * y2y2 + + sinsin * * x2;x2; ball.vxball.vx = = coscos * * vx1vx1 - - sinsin * * vy1;vy1; ball.vyball.vy = = coscos * * vy1vy1 + + sinsin * * vx1;vx1; ball.xball.x = = line.xline.x + + x1;x1; ball.yball.y = = line.yline.y + + y1;y1; 开始,声明变量 ball,line,gravity,bounce。在 enterFrame 函数中执行基本运动代码。 然后,获得 line 的角度并转化为弧度制。有了角度,就可以求出正余弦的值。 接下来,用 ball 的位置减去 line 的位置,获得 ball 的 x,y 与 line 的相对位置。下面,准备对物体进行旋转!在看到这两代码时,注意到好像是错的。 / 旋转坐标var x2:Number = cos
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号