flash as 打字

键盘打字效果实例讲解

作者:xfykzz    来源:闪客帝国  日期:2003-12-31  人气:7829  提问:0

收藏教程 | 查看提问 | 我要投稿 | 发给好友 | 错误报告

 
简介:
    本篇通过一个实例,围绕着attachMovie这个复制语句,详细讲解了如何给批量复制的MC赋给不同的动作……
<script language=JavaScript type=text/javascript> </script> <script language=JavaScript src="http://ad.flashempire.com/adjs.php?n=332921308&what=zone:23&block=1&exclude=," type=text/javascript></script>
 

本篇要讲的是关于给批量复制的MC赋给不同的动作的教程。

效果预览:

可以看到这是一个简单的打字作品,为了突出我讲的重点,这里对作品本身就没有加修饰了.按钮是共享库中的现成,改成了MC.场景里只有一具动态文本框. 本来文本框也可以用AS建,但是我担心那样就把本篇的主题掩盖了.

在结合源文件讲解前,我的对于本篇的中心作一下说明.

由于现在用FLASH进行动画创作的人是越来越多,作品的规模也是越来越大,因此很多时候会用到复制影片剪辑的语句.通常是用attachMovie来复制库中的语句,使得场景本身不显得太乱.而我们要说的“给批量复制的MC加不同的动作”其实也是围绕着attachMovie这个复制语句来讲的.

有些时候,我们的确需要给很多MC加上动作,于是在大的工作量下面就产生了这样一个问题,能不能用AS编写出一种能够简化工作量的代码,使得给很多MC加上动作时不必那么费事(的确,如果MC有几十个,每一个都加上不同的动作,不累死也烦死的).

关于问题的答案是不确定的.关键在于你要加的动作和MC之间有没有某种规律性地联系.如果你要给完全不同的MC(也就是说不是用attachMovie复制出来的MC,而是你自己一个一个做出来的形态各异的MC)加上完全不同的代码,那么我只能说:“无能为力“.我们之所以有理由去让AS完成给不同的MC加上不同的动作,是因为这些MC和这些动作之间有某些相同或相似之处,我们自己处理不同的地方,而把相同的部分留给了代码.

那么,“相似“二字如何理解呢?或者说,什么样的MC和什么样的AS才叫做相似呢?

这里我要举的例子就是循环语句.利用循环语句我们知道可能批量地完成某一工作,比如说给一个数组的每个元素赋予不同的值. 我们自然而然地想到循环. 那么进一步问:为什么要用循环? 原因有两个:

1、数组元素的变量有相似性,可以用下标来逐个表示。
2、赋予的值有规律性,比如是一个以i值变化的数列等等。

这样我们才能够把代码简化,而这种简化前提就是数组元素和赋值的“相似“.

说了这么多,无非就是一个意思:如果MC(我们类比的数组元素)之间有规律性,相应的动作代码也有规律性(我们类比赋予的值),那么我们就可能简化我们的工作量.

幸运的是,大多数要用到attachMovie复制MC的时候,我们需要的“不同的代码“之间也是相似的.

等等,为什么我们一再强调用attachMovie呢?

因为我们要批量出现的MC就是靠它来完成. 那么如果我的MC相差很大,而代码相似,怎么办?

呆会儿你会看到,其实MC的相似与否不是MC本身决定的,而是由它的标识符,也就是MC的名称决定的,因为我们是用MC的名称来完成对MC的引用的,所以关于这一点您不用担心,而且我也相信在看完本篇后你会有办法举一反三的. 现在回到attachMovie中来.我们之所以考虑这个语句,是因为我们经常用如下语句来批量复制MC:

for(i=1;i<=50;i++{
  attachMovie("mcName",mcName"+i,i);
}

当然,这里我省略了对坐标的定义,出来的MC全部是在左上角的(0,0),看上去50个就像是一个.

看出来了吧,复制出的50个MC的唯一差别只在于i的值,这就是规律,这就是相似. 如果我们的动作代码本身也有着对i的函数关系的话,毫无疑问,我们可以定义不同的代码了.

明白了吗?一切的一切关键就在于i的有规律的取值,使得复制出来的MC的标识符(名称)与代码之间都有着对i的函数关系,那么我们就可以用AS来简化我们的工作了!就算MC不同,只要它们之间的名称与i有函数关系,代码也与i有函数关系,那就没问题.

那么如何得到这个序列号(i值)呢?下面还是结合我给的例子来详细说明一下我们的做法.

例子中当你敲击键盘时,场景中的相应的按键就按下,动态框里出来相应的字母.而实际上我只用了一个MC,不多的代码就完成了.唯一美中不足的是键盘没有像现实中那样排列.因为我实在找不出排列与i值的关系.

好了,可以看到,代码一共分为三部分,第一部分是对一个MovieClip类的子类的定义.

function keyMc(){
}
keyMc.prototype = new MovieClip();
keyMc.prototype.onLoad = function(){
  this.label = String.fromCharCode(96+parseInt(String(this).substr(10)));
};

千万别头晕,如果您懂得一点儿对象的概念,我想是不难理解的.
首先我们定义了一个类:

function keyMc(){}

您不必奇怪为什么会这样写,只要知道这种写法是对的就行了.就相当于java中的class keyMc{}一样.一个定义而已.然后把这个类定义为 MovieClip类的一个子类:

keyMc.prototype = new MovieClip();

这里需要说明一下,我们建立的所有的MC都是MovieClip类的一个子类. 这是AS里面的语法,prototype是原型的意思,这样就表示MovieClip是keyMC的原型(父类),当然我们的目的是让keyMc类继承MovieClip中的方法:

keyMc.prototype.onLoad = function(){
  this.label = String.fromCharCode(96+parseInt(String(this).substr(10)));
}

先别管{}里面的内容.我们看到了熟悉的onLoad方法.还有一个不太熟悉的prototype.
上面已经说过,prototype表示“原型“,而keyMc类又是继承了MovieClip类,所以自然有onLoad方法.因此该句意思是把onLoad方法加入到期keyMc的原型中,简单地说就是所有的从keyMc类实例化的对象都有了这个onLoad方法.

而我们可以看到,这个方法里面的代码:

this.label = String.fromCharCode(96+parseInt(String(this).substr(10)));

什么意思呢?看起来是对对象里的label属性赋值.赋的什么值呢?括号是有点多,不过我们发现最外边的是String.fromCharCode(),它的意思是把里面的数字转为对应的ASCII字符.那么是什么样的数字呢?

我们可以看到数字是96加上某一个数,这个数是这样表示的arseInt(String(this).substr(10)).外括号是一个parseInt()函数,它的作品是把()里面的字符串转为数字.这个字符串是tring(this).substr(10),this指代的是对象本身,String(this)表示把对象本身的名称转为字符串. 那后面的substr(10)是什么意思呢? substr是String对象的一个方法,表示取从字符串的第10个字符开始,取出到字符串结束的子字符串.

好了,看起来我们基本理解了代码的意思:把对象名称的第10个字符及以后的字符取出(很可能是数字,因为我们用到了parseInt来转换),并加上96,再把与此数字对应的ASCII字符赋给该对象里的label属性.

等等,说了半天,好像与要讲的不太相干呀?您别急.

现在我们到源文件第一帧的代码里找到了这样的一条语句:

Object.registerClass("mc", keyMc);

并注意到在库里面我已经把按键的MC的链接名称写成了mc,keyMc是我们刚刚定义的类. 好象有些眉目了. 事实上这句代码是把mc与keyMc关联起来了,您不用知道为什么是Object.registerClass(),您只需要知道这样做就能把自定义的类与一个在库中的MC关联起来就行了,会照搬就行了.

那么,关联的什么东西呢?是不是onLoad方法?
答对了!就是onLoad方法!
联想到我们说过用attachMovie来批量复制,以及onLoad方法中的String(this).substr(10),好像有点儿联系了!
的确如此,再下面我们会看到这样的代码:

for(i=1;i<=26;i++) {
  attachMovie("mc", "mc"+i, i)
  with(evel("mc"+i)) {
    _x = ((i-1)%9)*50+100;
    _y = Math.floor((i-1)/9)*60+300;
  }
}

至于with语句,您可以看到只是对坐标的赋值,这里我们不管.我们要注意的是attachMovie("mc", "mc"+i, i), 显示,复制出来的MC的名称就是"mc"+i. 再联想到substr(10)是从对象名称的第十个字符起取出,是不是正好取到了i的值呢? 但是为什么是10,而不是三阶段呢?i的值明明是第三位呀!

您的猜想完全正确! 而之所以我们取10的原因是String(this)返回的是当前对象的完整名称,在这里也就是:_level0.mc1项(我们用mc13来代表复制出来的MC),您看,到1正好是十个字符,因此String(this).substr(10)取出的值是13!也就是i的值!

我们已经说过,通过Object.registerClass("mc", keyMc);语句使得所有从mc复制出来的MC都有了keyMc定义的onLoad方法.而现在我们通过对对象本身的名称的筛选找到了不同!

明白了这一点,剩下的就好解释了.我们注意到97对应的ASCII字符是小写的"a",而i值是从1开始循环的,那么代码的意思就是:找到复制的MC的序列号(也就是i值),并从a开始,把"mc"中的label赋给对应的字母!而label您可以在"mc"里面看到,是一个动态的文本框.因此我们才可能看到复制出来的按键上的字母是从a~z的! 而用onLoad方法是让代码在初始时就被执行.

我们终于找到了关键点所在了,就是通过命名的有序性,找到这个序列号(i值),利用它来使代码互异而有序.

接下来代码就更容易理解了,我们已经把关键问题解决了.

可以看到剩下的一段代码是对按键监听器的定义:

keyLis = new Object();
keyLis.onKeyDown = function() {
  eval("mc"+(Key.getAscii()-96)).gotoAndStop(3);
  labelText+=eval("mc"+(Key.getAscii()-96)).label;
};
keyLis.onKeyUp = function() {
  eval("mc"+(Key.getAscii()-96)).gotoAndStop(1);
};
Key.addListener(keyLis);
Object.registerClass("mc", keyMc);
for (i=1; i<=26; i++) {
  attachMovie("mc", "mc"+i, i);
  with (eval("mc"+i)) {
    _x = ((i-1)%9)*50+100;
    _y = Math.floor((i-1)/9)*60+300;
  }
}

这里我们声明了一个新的Object对象keyLis,并对它定义了onKeyDown和onKeyUp方法.也就是监听器.eval("mc"+(Key.getAscii()-96))表示对所按键对应的MC的引用.Key.getAscii()表示所按键对应的ASCII值,减去96,正好是对应的i值的一个序列号,用eval计算得到的就是对应的MC.我们让该MC跳到第三帧,也就是按下的状态. 并在某些方面labelText里面留下对应的字符.labelText是主场景里的一个动态框.onKeyUp是让该MC跳回到第一帧,也就是普通状态.

Key.addListener(keyLis)是把这个对象注册给Key对象,使得它可以监听对键盘的响应.

回顾一下全部的代码,我们无非是做了这样几件事:
1 自定义一个对象,并自定义onLoad方法(您也可以添加同样的方法,如onEnterFrame),把这个对象与库里的MC链接,使得所有从中复制的MC都拥有该方法.
2 方法中有对MC序列的提取,并依靠这个序列号给MC定义相似的方法.
3 注册一个键盘监听器,使之接受键盘事件,并对相应的MC做出反应.
4 复制名称相似的MC.

我们一再强调,完全不同的方法定义是不可能的(除非您真的不怕麻烦,而宁愿用一堆if...else...语句来判断MC的名称),我们的关键就是找到复制出来的MC对应的序列号:String(this).substr(10).

注意,这里我们用10而不是其它,是因为我们把MC命名为诸如mc13之类,如果是abc13,您可得改成11.

也许您对自定义对象并把它注册给一个库中的对象有些不解,或者是对监听器有些疑问,请查看FLASH帮助文档并结合源文件.

源文件下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值