说明:周日休息,停发一期。大家也整理一下两周以来所学知识,温故知新嘛!
通过本章我们学习了Box类的例子。在现实世界中,我们的Box类可能是纯概念上的(即,永远不显示在屏幕上)也可能是一种直观表示。由于大多数Flash应用程序都是可见的,因此我们将总结本章,来看一看如何使一个Box实例显示在屏幕上。
并非所有的Flash应用程序都以同一种方式在屏幕上显示内容。每个应用程序必须决定如何绘制屏幕、何时绘制、以及哪个类或者哪些类包含绘制代码。当设计一个应用程序系统时,主要应考虑以下几个问题:
? 首先决定显示的元素是否是自己渲染(render themselves)或是通过一个中心类渲染(be rendered by a central class)。例如,是为Box类提供一个自己的drawBox( )方法,还是在其他的某个类中有一个drawBoxes( )或drawScreen( )方法?
? 决定时隔多久更新一次显示的元素——或者当某些事件放生时(例如一次鼠标点击)或者反复刷新(于Flash Player的帧速一致)。
? 决定渲染技术(rendering technique)。Flash影片中的每个可见元素必须显示在一个影片剪辑中。然而,影片剪辑可以在创作时手工放置或者在运行时使用Actionscript添加到舞台上。一个影片剪辑的内容同样可以使用MovieClip绘图API勾勒出来。
? 决定屏幕刷新策略。将每个可见元素作为一个单独表示的影片剪辑(有规律地更新)来维护,或者在显示更新时将舞台上的全部内容统统清除、然后从新创建?
在我们的例子中,由Box类来负责其屏幕显示。当创建一个Box实例时,我们将添加一个空的影片剪辑(命名为container_mc),在那上面来绘制我们的Box实例。如果Box实例调整尺寸,我们将重新绘制container_mc中的内容。为了移动Box实例,我们将移动container_mc,而不是在container_mc中移动Box实例。这是我们免于重新绘制container_mc中的内容。
我们的Box显示策略是唯一的运行时策略(runtime-only strategy)。在Flash Player中出现的每个Box实例,在编辑一个.fla文件时都不能被放置到舞台上。在第十三章,我们将看到如何创建一个可见的类,在运行时以及在Flash创作工具中都可以将实例放置到舞台上。
例如4-6 给出了一个Box类的最终的、完全的、包括屏幕显示代码的样子,请注意以下几点:
? width和height属性(不是伪属性)
? 存取器getWidth( )和getHeight( ) 方法(不是getter和setter方法)
以下内容对于这个版本的Box类而言是完全陌生的:
? container_mc属性,存储一个用于绘制Box图形的影片剪辑的引用
? 存取器方法getX( ), setX( ), getY( ), setY( ),用于取得并设置container_mc影片剪辑的位置
? draw( )方法,用于在container_mc影片剪辑中绘制Box图形
最后,以下内容在这个版本的Box类中已经被改变:
? 构造函数使用了额外的参数,如下:x和y指定container_mc的初始水平和垂直位置;target指定container_mc影片剪辑添加到哪个影片剪辑中去;depth指定添加的深度。
? 在设置Box实例的高度和宽度后,setHeight( )和setWidth( )方法调用draw( )。(注意,存取器方法的灵活度为我们提供了:我们改变我们的类如何工作,而无须改变如何去使用它)。
详细的注释将帮助我们学习代码。
例4-6 一个具有完整绘图程序的Box类
class Box {
// Box 的尺寸
private var width:Number;
private var height:Number;
// 用于包含Box实例直观表示的影片剪辑
private var container_mc:MovieClip;
//
// 构造函数
//
public function Box(w:Number, h:Number, x:Number, y:Number, target:MovieClip, depth:Number) {
// 创建用于保存Box可视实例的容器
container_mc = target.createEmptyMovieClip("boxcontainer" + depth, depth);
// 初始化尺寸
setWidth(w);
setHeight(h);
// 初始化位置
setX(x);
setY(y);
}
// 得到 width
public function getWidth():Number {
return width;
}
// 为 width 赋值
// 这个版本不但为 width 赋新值,而且根据新的 width 值重新绘制 Box 实例
public function setWidth(w:Number):Void {
width = w;
draw();
}
// 得到 height
public function getHeight():Number {
return height;
}
// 为 height 赋值
// 这个版本不但为 height 赋新值,而且根据新的 height 值重新绘制 Box 实例
public function setHeight(h:Number):Void {
height = h;
draw();
}
// 得到 x
// 为了方便,x 和 y 坐标直接存储影片剪辑容器的坐标。
// 如果关注数字的准确度,我们应该将 x 保存为一个独立的Box属性,
// 以便它不会被MovieClip类四舍五入。
public function getX():Number {
return container_mc._x;
}
// 为 x 赋值
public function setX(x:Number):Void {
container_mc._x = x;
}
// 得到 y
public function getY():Number {
return container_mc._y;
}
// 为 y 赋值
public function setY(y:Number):Void {
container_mc._y = y;
}
// 在屏幕上显示 Box 实例。使用 MovieClip 绘图方法在 container_mc 中画线。
public function draw():Void {
// 清除前一个Box
container_mc.clear();
// 使用 1-point 的黑线
container_mc.lineStyle(1, 0x000000);
// 定位画笔
container_mc.moveTo(0, 0);
// 开始白色填充
container_mc.beginFill(0x0000FF, 50);
// 绘制 Box 的边界
container_mc.lineTo(width, 0);
container_mc.lineTo(width, height);
container_mc.lineTo(0, height);
container_mc.lineTo(0, 0);
// 正式停止填充
container_mc.endFill();
}
}
以下代码展示了如何将
Box类用于一个
Flash文件(
.fla)时间线的一帧上:
代码,就像艺术一样,是永远不会真正完成的。你应该探索你的思想,即使是本章讨论的一个简单的Box类也是如此。你能为它添加自由放置每个Box实例到舞台上的代码吗?或者改变Box实例的颜色?旋转一个Box实例或者延直线运动的动画又该怎么写?试着为每个Box实例添加文本域显示其宽度和高度以及面积。你甚至可以让文本域接受用户输入来改变Box的尺寸。
在下一章你将看到如何添加这些特色,我们将研究ImageViewer类。本章涉及了大量的理论基础,因此如果你有些吃不消,不要着急。下一章将涉及具体的实现,以帮助你运用你所学到的知识。再见!