Director 8 相对于 director 7 有很多增量型的改动,其中对于 lingo 程序员来说,最引人注目的就是增加了相关的 image lingo 指令。有了它,我们可以做很多以前用 director 7 所无法做到的效果,例如你可以自己编写一些 transition 过渡效果,还有你还可以编写类似于 photoshop 的滤镜效果。这也进一步体现出 director 相对于 Flash 的优势所在--即:对于位图的强大处理能力。在这里我们将领略一下新增加的 image lingo 命令带来的强大功能。
有很多人在论坛上讨论 director 与 flash 孰优孰劣,无论是国内论坛还是国外讨论组,情况都是相同的。双方的拥护者都尽可能的说服对方自己喜欢的软件是最棒的,其实在很多情况下这种争论是没有任何意义的。我本人两种软件都使用,我喜欢用 flash 来做简单的动画角色,然后导入 director ,而不是象以前那样全部在 director 中做 film loop 动画。做动画方面, director 确实不如 flash, 但是我还是喜欢使用 lingo 来编写程序。所以我不会象一个真正的 flasher ("闪客")那样不停的发掘 flash 的潜力来做出一切效果(尽管有的效果做出来很勉强,或是效率太低,性能较差)。 最近我通过做一个剃须刀演示项目,进一步验证了 director 在处理点阵图像方面的确优于 flash。
其实这个项目很简单: 通过在网页中拖动剃须刀,将一个的人的面部胡须刮干净。
这个项目最开始的想法是用 flash 来做。我们的 flash 技术人员最开始的想法是,将这个人脸部胡须部分的照片图案(矩形区域),细致切分,然后将同一个人的脸部没有胡须的照片(为了达到头部图案完全吻合,我们是在同一张照片上通过 photoshop 做添加胡子的处理)同样分割为很多相同的小块,然后作为元素导入 flash。这样有胡须的部分分为很多小块,导入 flash ,然后相同的无胡须的部分也分为相同个数的小块导入 flash ,然后将对应的每一个小块做一个 MC.
这个 MC 的第一帧放置有胡须的切块图案,第二帧放置无胡须的切块图案,mc 的第一帧放置 stop action, 当鼠标 over 的时候,让这个 mc 跳动到第二帧没有胡须的小切块。这样,当用剃须刀做的 mc 替代鼠标后,当它滑动到这些MC(有胡须的小切块图案)的时候,他们就会跳到相应第二帧(也就是没有胡须的小切块图案),这样就可以完成刮胡子的演示了。
方法是很简单的: 但是实际做起来却出现了如下的问题。
1:通常这样的切图文件必须非常细,才可以满足客户的要求,然后切图越细致就意味在 flash 中要作更多的 mc 和 symbol。 这样不但增加了文件的大小,而且也使得文件运行特别慢。
2:由于这种方法制作的切图大小是开始定好的,如果希望将切块更加细分的话,你必须从新切图和导入。必须重复劳动。
3:这种方法制作 swf 文件通常比 director 制作的 dcr 文件大不少(至少是一倍)。
而采用 director 8 的 image lingo 指令,你可以完全的避免上述问题。
制作方法如下:
所需的素材:
一张没有刮胡子的照片位图,和一张同一个人刮完胡子的照片位图。(为了版权问题,我将脸部部分去掉,保留胡须部分的位图图案。)见图如下:
图形 1 face.jpg
图形 2 faceoff.jpg
接着我们开始介绍程序部分,这段程序非常的短小,核心部分的代码总共 6 行。然是为了理解这六行代码,你需要了解 director 8 新增加的 image lingo 的一个核心函数,这就是 copyPixels
copyPixels 的功能就是将位图数据从一个 image 复制到另一个 image。
现在任何一个 director 角色(member)都有一个 image 的属性,这是很多人忽略的地方。这个 image属性是内存中的一个图形对象的引用,而这个图形对象是角色成员的一个图形表示。角色成员可以是 位图,flash 角色,文字角色,甚至是舞台 stage. 我把刚刚导入的两个位图角色起名为 source (刮完胡子的照片位图 face.jpg)和 targer (未刮完胡子的照片位图 faceoff.jpg)
在 director 中角色分布图如下:
control + M 打开 director 中的消息窗口,输入
put member("source").image
n -- 1d151c 就是该 image 对象在内存中的地址。
而 image 属性是对实际数据的一个引用。而 image 图形对象是角色成员在内存中的实际数据。
任何对 image 对象的改动都是对 cast 中相应的原始角色的改动。这一点要注意,除非 image 对象是你自己创建的而且和角色成员不相关联,否则必须注意不要意外改动的原始角色成员。
你可以调用 image() 函数来创建自己的对象。实例如下:
image (width, height, bitdepth)
thisImage = image (320,240,16)
你现在创建了一个宽为 320 pixel 高为 240 pixel ,位深为 16 bit 图形对象。
你可以用 copyPixels 函数来给图形对象添加数据。该函数的格式如下(这是本程序的关键):
targetImage.copyPixels(sourceImage, destinationRect, sourceRect, )
该函数功能是通过目标图形对象调用 copyPixels 函数,将 源图形对象,从源图形对象的矩形区域 sourceRect 复制到 目标图形对象的矩形区域destinationRect。
以本程序为例子,我们的目的: 程序记录鼠标移动的轨迹,从鼠标滑动的点为左上角开始,记录一个虚拟的矩形区域,将这个矩形坐标(相对与该图形左上角为原点)记录下来。然后通过targetimage (就是我们这个程序的角色 "target "-未刮胡子的照片图案)调用 copyPixels 函数将 sourceimage (就是我们这个程序的角色 "source "-刮胡子后的照片图案)中鼠标滑动矩形区域的图形复制到相应的 targetimage 中,记住我们对 targetimage 角色的改动直接改动了 target 角色,所以我们必须有另外一个角色,它和 target 角色完全相同,但是名字不同,为的是在需要的时候恢复 target 角色的原貌。所以我们从新复制一下 target 角色,放在第 3 号角色,起名字为 "s"。下面会讲解为什么这样作。 现在开始制作:
1: 在第一帧的帧脚本 frame script 中写上
on exitframe me
go the frame
end
目的是让播放停止在这个帧上。让 director 等待响应鼠标事件。
将 target 角色拖动到 score 中的第一帧的 6号通道(可以是任何通道,但是最好不要用 1,2 号通道,因为你有可能将来在这些地方放置底图。所以尽量将变动的角色放在稍微高通道中。这是个人习惯的问题)。鼠标右键单击这个角色选中 script 打开该 sprite 的 sprite script 。
我们必须响应 exitfame 事件。
首先我们将定义一个属性(这是一个习惯性的写法)
就是在每个角色的 beginsprite 事件handle 中做初始化属性和某些全局变量的操作。
这部分代码是为了方便对大量 sprite(me.spritenum) 的调用而写的,其实在本程序中并不一定需要
property pMySprite
on beginsprite me
pMySprite = sprite(me.spritenum)
end