Making Things Move 第四章

创建日期:2008年5月17日 来自:蓝色理想 浏览:912次 作者:匿名

创建多条曲线

下面我们将目光转向创建多条曲线,而不仅是一条曲线,创建一条平滑的向各个方向弯曲的线。首先,来看一个错误的做法,是我原先尝试过的一种方法。从随便一个点位出发,经过第一个点到第二个点再到第三个点,经过第四个到达第五个,经过第六个到达第七个等等绘制一条曲线。这里是代码(文档类 MultiCurve1.as):

package {
 import flash.display.Sprite;
 public class MultiCurves1 extends Sprite {
  private var numPoints:uint = 9;
  public function MultiCurves1() {
   init();
  }
  private function init():void {
   // first set up an array of random points
   var points:Array = new Array();
   for (var i:int = 0; i < numPoints; i++) {
    points[i] = new Object();
    points[i].x = Math.random() * stage.stageHeight;
    points[i].y = Math.random() * stage.stageHeight;
   }
   graphics.lineStyle(1);
   // now move to the first point
   graphics.moveTo(points[0].x, points[0].y);
   // and loop through each next successive pair
   for (i = 1; i < numPoints; i += 2) {
    graphics.curveTo(points[i].x, points[i].y,

    points[i + 1].x, points[i + 1].y);
   }
  }
 }
}

第一次循环在 init 方法中,建立一个数组存储九个点。每个点都是一个 object 拥有 x,y 属性,它们的值都是舞台尺寸的随机数。当然,在一个真正的程序中,点位也许不是随机的,只是用这种方法进行快速设置。

随后设置线条样式,将笔移动到第一个点位。下一个循环从1开始每次递增2,所以线条是经过第一点到达第二点,然后从第三点到第四点,再从第五点到第六点,最后从第七点到第八点。至此,循环停止,因为第八点是最后一个点。大家也许注意到了,这里至少要有三个点,而且点的数量必需为奇数个。

程序看起来还不错,测试一下试试。如图4-1所示,看起来不是非常平滑,有棱有角的,这是因为曲线之间没有进行协调,它们之间共用了一个点。

图4-1 多条曲线,错误的方法。我们可以清楚地看到曲线的结束和开始的位置。

我们也许不得不去加入更多的点才能使解决这个问题。这里有个策略:在每两对点之间,加入一个新点(中间点)放在这两点的正中间。然后使用这些中间点作为起点和终点,而把最初的那些点(原始点)作为控制点。

图4-2 说明了解决办法。在图中,白点为原始点,黑点为中间点。这里使用了三条 curveTo 方法,图中的点使用了不同的颜色,这样就能分辨出起点与终点了。(图4-2 是 multicurvedemo.fla 文件的一张截图,可以在 www.friendsofted.com 的 books 页面下载)


图4-2 带有中间点的多线条

注意,图4-2中第一个中间点和最后一个中间点都没有被使用,第一个和最后一个原始点留作曲线的两个端点,只需在第二个点和倒数第二个点之间进行连接。这里是前一个例子的升级版,文档类 MultiCurve2.as:

package {
 import flash.display.Sprite;
 public class MultiCurves2 extends Sprite {
  private var numPoints:uint = 9;
  public function MultiCurves2() {
   init();
  }
  private function init():void {
   // first set up an array of random points
   var points:Array = new Array();
   for (var i:int = 0; i < numPoints; i++) {
    points[i] = new Object();
    points[i].x = Math.random() * stage.stageHeight;
    points[i].y = Math.random() * stage.stageHeight;
   }
   graphics.lineStyle(1);
   // now move to the first point
   graphics.moveTo(points[0].x, points[0].y);
   // curve through the rest, stopping at each midpoint
   for (i = 1; i < numPoints - 2; i ++) {
    var xc:Number = (points[i].x + points[i + 1].x) / 2;
    var yc:Number = (points[i].y + points[i + 1].y) / 2;
    graphics.curveTo(points[i].x, points[i].y, xc, yc);
   }
   // curve through the last two points
   graphics.curveTo(points[i].x, points[i].y, points[i+1].x,
   points[i+1].y);
  }
 }
}

请注意,在新代码中, for 循环从1开始到 points.length -2 结束,也就避开了第一个点和最后一个点。程序要做的是,创建新的 x,y 点,这个点是数组中后面两个点位的平均值。然后从数组下一个点位开始画一条曲线到新的平均点(中间点)。当循环结束时, i 变量指向倒数第二个元素,因此,可以穿过这里向最后一个点画条曲线。

这时,就得到一个非常平滑的图形,见图4-3。注意,这时原始点的数量不再受奇数个的限制。

再加一点小小的变化,使用同样的技术创建一条封闭的曲线。首先,计算一个初始的中间点,并移动到这里。然后,进行循环,获得每一个中间点,最后,将最后一条曲线画回初始中间点。图4-4 为显示结果


图4-3 多条平滑曲线

package {
 import flash.display.Sprite;
 public class MultiCurves3 extends Sprite {
  private var numPoints:uint = 9;
  public function MultiCurves3() {
   init();
  }
  private function init():void {
   var points:Array = new Array();
   for (var i:int = 0; i < numPoints; i++) {
    points[i] = new Object();
    points[i].x = Math.random() * stage.stageHeight;
    points[i].y = Math.random() * stage.stageHeight;
   }
   // find the first midpoint and move to it
   var xc1:Number = (points[0].x + points[numPoints - 1].x) / 2;
   var yc1:Number = (points[0].y + points[numPoints - 1].y) / 2;
   graphics.lineStyle(1);
   graphics.moveTo(xc1, yc1);
   // curve through the rest, stopping at midpoints
   for (i = 0; i < numPoints - 1; i ++) {
    var xc:Number = (points[i].x + points[i + 1].x) / 2;
    var yc:Number = (points[i].y + points[i + 1].y) / 2;
    graphics.curveTo(points[i].x, points[i].y, xc, yc);
   }
   // curve through the last point, back to the first midpoint
   graphics.curveTo(points[i].x, points[i].y, xc1, yc1);
  }
 }
}


图4-4 多条封闭曲线

使用 beginFill 和 endFill 创建图形
beginFill(color, alpha) 方法非常简单,没有太多可说的。有一点值得注意,同 lineStyle 一样, alpha 的取值范围也变为了 0.0 到 1.0,而不是 0 到 100,这项也是可选的,默认为1.0。无论何时执行该帧的绘图代码 Flash 都会开始进行计算,无论何时遇到 endFill 指令 Flash 都会停止计算。总结一下,过程如下:

  • moveTo
  • lineStyle (如果有参数可以填入)
  • beginFill
  • 在一系列的 lineTo 和 curveTo 方法后,要在最初的点位结束
  • endFill

事实上,使用前三个方法的顺序不会影响到绘图。我们不是必需要指定线条样式,请记住如果不指定线条样式就会得到一条看不见的线条,非常适合绘制填充色,当然两者同时绘制也不错。如果所绘制的线条没有回到最初开始的点位,一但调用了 endFill, Flash 将会自动绘制一条封闭线,是为了能封闭这个图形。调用 endFill 后,无论线条样式如何,都会自动将最后一条线绘制完成。当然,我们自己将线条封闭是个很好的习惯,这样一来,既确保了最后的能够正确绘制,又可以让看代码的人知道我们究竟想画的是什么图形。

下面来试一下绘制填充色,可以使用前面的封闭曲线示例(MultiCurve3.as)来完成,这里已生成了一个封闭的图形。只要将 beginFill 语句放在第一条 curveTo 前面的任何地方——如 beginFill(0xff00ff);,这样就创建了亮紫色的填充——最后使用 endFill() 结束。

  首页   上一页   1   2   3   4   5   6   7   8   9   下一页   尾页 

责编:yezi
相关搜索: Making   Things   Move   第四章  
Google
嗷嗷毙技术网版权申明:大家可以自由转载我站点的文章,但原作者和来自我站的链接必须保留(非我站原创的,按照原来链接,自行链接)。文章版权归作者所有。
特别注意:本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有,文章若有侵犯作者版权,请与我们联系,我们将立即删除修改。
子栏目
搜索 
Google