|
白骷争宝髅气 银牌会员
- 帖子
- 1280
- 体力
- 2116
- 威望
- 73
- 当前
- 浙江 杭州
|
1#
大 中
小 发表于 2006-11-22 03:18

"偶学会艾克申斯苦瑞普特咧~~~偶好高兴耶"
大家好!偶是新手小白,以前没有还没学过编程语言,今年AS2刚入了门,做了些用代码控制的影片,兴奋之余忍不住就来论坛嚷嚷两下.(有要扔西红柿鸡蛋之类的同学请跟贴并注明所扔物品名称规格及数量)
=演示地址0=
=演示地址1=
=演示地址2=
源文件下载:
=源文件下载1=
=源文件下载2=
言规正传,偶在自己的学习和制作时遇到的最大阻碍就是Flash8+ActionScript2的动态文本比之静态文本的诸多限制之处(比如不能被遮罩,不能改变透明度,不能旋转等等)而论坛上每个月少说也有2贴提出相关问题----这可给斑斑们添了不少忙(当然偶自己当初就是提问的).所以偶觉得把自己解决动态文本问题的方法共享出来是很有必要的,同时也是给在偶学习过程中提供帮助最多的蓝色理想灌水的最好机会,以此表达对各位热心斑斑和老师同学们的感谢.
PS:这些话是9月份写的,东西也是那时候做出来的,但由于我为了追求效果,要做个很罗嗦的演示,而自己又是新手进度太慢,遇到挫折很多,所以就一拖再拖,如今FLASH9已经出了测试版,也许AS3中的动态文本已经得到改进,那我就白忙活了半天.不过根据一般规律来说AS2还会存活相当长的一段时间(好像现在还有人在用FLASH-MX),这个玩意也许还有一点存在的价值.
偶滴解决办法就是把动态文本做成位图数据,具体的实现途径做了两种:
一是函数形式,用参数控制文字的内容及样式,输出位图
二是影片剪辑形式,可实现监视变量,同时可避开用代码设置中文无效的bug
会AS的老师和同学们直接复制了用就是了,正在AS2入门和想学习交流的同学可以看看下面的相关说明(其实就是灌水,呵呵),还可以下载源文件,里面的代码有注释,可以当作讲义来看,相信AS2菜鸟同学们看了以后水平会很快赶上偶滴^_^.复制内容到剪贴板 代码:function txt2bmp( txt, txtColor, txtSize, txtFont, bold, italic, txtWidth ) {
import flash.display.BitmapData
import flash.geom.Rectangle
import flash.geom.Point
bmpPaper.dispose()
var txtColor:Number = txtColor || 0xFF000000
var txtAlpha:Number = txtColor >> 24 & 0x000000FF
var txtWidth:Number = txtWidth || 350
var format:TextFormat = new TextFormat()
format.font = txtFont
format.size = txtSize
format.bold = bold || false
format.italic = italic || false
_level0.createEmptyMovieClip ( 'mcText' ,_level0.getNextHighestDepth() )
_level0.mcText.createTextField ( 'field',1,0,0,0,0 )
with( _level0.mcText.field ) {
autoSize = true
_width = txtWidth
wordWrap = true
textColor = txtAlpha
background = true
backgroundColor = 0xFFFF00
_quality = 'BEST'
text = txt
setTextFormat( format )
}
var txtH:Number = _level0.mcText.field._height
var txtW:Number = _level0.mcText.field._width
var bmpGetAlpha : BitmapData = new BitmapData( txtW,txtH,false )
bmpGetAlpha.draw( _level0.mcText )
removeMovieClip ( _level0.mcText )
var bmpPaper : BitmapData = new BitmapData( txtW, txtH, true, txtColor )
bmpPaper.copyChannel ( bmpGetAlpha ,new Rectangle( 0,0,txtW,txtH ),new Point( 0,0 ), 4, 8 )
bmpGetAlpha.dispose()
return bmpPaper
}txt2bmp函数使用说明:复制内容到剪贴板 代码: txt2bmp( txt, txtColor, txtSize, txtFont, bold, italic, txtWidth ): BitmapData可用性: ActionScript 2.0 ( Flash8版本,低于Flash8/ActionScript2.0不能用哦! )
参数:
txt: 字符串 -要转换为位图的文字
txtColor: 十六进制8位整数 -给生成的文字指定颜色
txtSize: 整数 -字体大小
txtFont: 字符串 -要使用的字体的名称
bold: 布尔值 -是否粗体,可以用1和0来代替true/false
italic: 布尔值 -是否斜体
txtWidth: 整数 -限制文本宽度,超过则自动换行
除第一个之外,其他参数都可以省略或者指定为null,则会使用默认的值来工作
txtColor的格式是十六进制8位整数,用来表示一个ARGB形式的32位色('0x'之后的8位,1-2位控制透明度,3-4位控制红色浓度,5-6位绿色浓度,最后两位蓝色.不懂ARGB的同学玩玩Flash8的混色器就知道了)
默认颜色是不透明黑色(0xFF000000)
默认字体大小12磅(偶没trace,不过看起来是12吧?大小实际上好像就是文字高度的象素数)
粗体样式和斜体样式都默认关闭
自动换行默认为350,单位是象素
使用者可根据需要修改函数代码来改变默认值
!注意:
* 输出的是bmp图像(也就是函数的返回),需要用一个变量来接收这个图像
并将其附加到某个对象(通常是MovieClip.attachBitmap方法)才可在舞台见到
* 函数调用时会在_level0创建临时mc,其深度是_level0.getNextHighestDepth(),如果此时_level0的1048575深度被占用就可能无法完成工作,此时需修改函数体代码手动指定深度
* txt2bmp函数代码所在之处需使用以下语句声名所使用的类(函数体里也可以,只是要放在使用它们的语句之前):
import flash.display.BitmapData
import flash.geom.Rectangle
import flash.geom.Point
示例1:复制内容到剪贴板 代码: _level0.createEmptyMovieClip('look',1)
_level0.look.attachBitmap( txt2bmp( '好好学习' , 0x66FF0000 , 64 ) , 9999 )以上代码会让影片中出现一个影片剪辑,包含"好好学习"字样,红色半透明的图形
示例2:复制内容到剪贴板 代码: var hhxx:BitmapData = txt2bmp( '好好学习' , 0x66FF0000 , 64 )
_level0.createEmptyMovieClip('look',1)
_level0.look.attachBitmap(hhxx,1)以上代码与示例1效果完全相同
示例3:复制内容到剪贴板 代码: _level0.attachBitmap( txt2bmp( '天天向上' , 0xFF77FFFF , 64 , null , 1 , 1 , 135 ) , 9999 )以上代码会使舞台上出现倾斜加粗的"天天向上"文字
========================================================================================
Bitmap-Typer说明书:
Bitmap-Typer是txt2bmp函数的影片剪辑形式(同学们也可以把它翻译成"位图打字机"),它提供了比txt2bmp函数更强的功能:
1.最大好处是可以监视变量,当变量改变时实例也自动更新其内容,相当于TextField之variable特性
(做计数器,时钟之类的东东方便! ^_^-V 不过坏处是大家不能像函数那样直接指定要显示的字符串了,它只显示变量中的字符串!)
即便是已经监视了某个变量的实例亦可改变被监视的对象(如在游戏中同一位置交替显示玩家名称/玩家得分/当前时刻)
2.可以设置中文字体(需手动)
工作方式略有不同----txt2bmp函数输出一个位图;Bitmap-Typer将生成的位图直接附加给自己来显示
制作Bitmap-Typer库元件:
进入Flash8工作界面,在需要使用Bitmap-Typer的影片的库中新建元件
名称为"Bmp-Typer"(或其他任意名称),类型为影片剪辑
建立的同时指定"为ActionScript导出"和"在第一帧导出",标识符为"_BmpTyper"(亦可自定)
编辑Bmp-Typer,使用"文本"工具在里面新建一个文本框
在"属性"面板中设置这个textField的实例名称为"field",类型为"动态文本"
在Bmp-Typer的时间轴第一帧里添加以下代码:复制内容到剪贴板 代码:import flash.display.BitmapData
import flash.geom.Rectangle
import flash.geom.Point
format = new TextFormat()
format.font = txtFont
format.size = txtSize
format.bold = bold || false
format.italic = italic || false
format.leading = leading || 2
var txtColor:Number = txtColor || 0xFF000000
var txtAlpha:Number = (txtColor>>24) & 0x000000FF
var txtWidth:Number = txtWidth || Stage.width-100
with(field){
autoSize = true
_width = txtWidth
textColor = txtAlpha
background = true
backgroundColor = 0x000000
border = true
wordWrap = true
_quality = 'BEST'
text = eval( Target )
setTextFormat (format)
setNewTextFormat (format)
}
var txtH:Number = field._height-2
var txtW:Number = field._width-2
field._visible = false
drawBmp()
if( lock ){
lockTarget( Target )
this.watch( 'Target',watchTarget ) }
else{ this.createEmptyMovieClip( 'cleaner',field.getDepth() ) }
function watchTarget( prop, oldVal, newVal, userData ){
lockTarget( newVal )
return newVal
}
function lockTarget(obj){
eval(path).unwatch( body )
body = obj.slice( obj.lastIndexOf('.') +1 ,obj.length )
path = obj.slice( 0 , obj.lastIndexOf('.') )
eval(path).watch( body , watchText )
}
function watchText( prop, oldVal, newVal, userData ){
field.text = newVal
field.setNewTextFormat( format )
txtH = field._height-1
txtW = field._width-1
drawBmp()
return newVal
}
function drawBmp(){
bmpPaper.dispose()
var bmpGetAlpha : BitmapData = new BitmapData( txtW,txtH,true )
bmpGetAlpha.draw(field)
var bmpPaper : BitmapData = new BitmapData( txtW,txtH,true,txtColor )
bmpPaper.copyChannel ( bmpGetAlpha , new Rectangle( 0,0,txtW,txtH ) , new Point(0,0) , 4 , 8 )
bmpGetAlpha.dispose()
this.attachBitmap( bmpPaper ,7 )
}建议:
如果遇到一个影片中可能同时出现许多个Bitmap-Typer实例之情形
将以上代码中的drawBmp()函数体的代码移动到影片的时间轴第一帧,并将其定义为_global属性
可在一定程度上节省影片对系统资源的消耗
用法:复制内容到剪贴板 代码:object.attachMovie( '_BmpTyper' , name , depth , [initObject:Object] ) : MovieClipobject: 对象 -需要使用Bitmap-Typer的对象,一般是影片剪辑或者_level0
'_BmpTyper':字符串 -影片的库中Bitmap-Typer元件被指定的链接标识符
name: 字符串 -给新实例指定的名称
depth: 整数 -新实例的深度
initObject: 属性[可选] -指定将要生成的新实例的某些属性是什么值,全部项目放进{ }内,并且用逗号分开,每个项目的格式是: 属性:值 (小贴士:偶自己查字典认为init是来自于名词initialization的前缀,意为设定初值,初始化;initObject可理解为初始化对象)
MovieClip: 影片剪辑 -attachMovie方法的返回值,整个语句在达到其生成舞台实例功效的同时本身也是一个值,可以赋值到其他变量中作为对所生成实例的引用或将整个attachMovie语句放进trace()的括号里面方便使用者了解操作是否成功
示例:复制内容到剪贴板 代码: _level0.attachMovie('_BmpTyper','typer',55, {Target:'_level0.txt0',txtColor:0xFFFF0000,txtWidth:255,lock:1} )关于initObject的内容:(不明白initObject的同学再看看上面的用法)
复制内容到剪贴板 代码: Target: 字符串 -需要监视的目标,要求用绝对路径表示,在_root者需使用"_level0.object"形式
若其中没有'.'(点运算符)则会失败
txtColor: 8位十六进制整数 -生成文字的颜色
txtWidth: 整数 -文本的宽度限制(单位是象素),达到这个值则自动换行
txtFont: 字符串 -要使用的字体的名称
txtSize: 整数 -文字大小
bold: 布尔值 -是否粗体,true或false可以用1或0代替
italic: 布尔值 -是否斜体
lock: 布尔值 -是否开启监视功能
注意:这个值唯一作用的机会是它在attachMovie语句中被执行时
实例生成后不能再用它来设置监视功能是否开启
注:
* 其他的属性亦可在此处人为指定(相关内容请参阅Flash8帮助文档中的:ActionScript 2.0 语言参考>ActionScript 类 > TextField)
* 除Target之外的属性都具有默认值,可以省略这些项目来使用默认值,默认值的值可以用过修改Bitmap-Typer元件内部的代码来设定
* initObject中所有项目的顺序可任意颠倒,类型是布尔值的可以用1和0来代替
* Target属性本来该是Object类型,但此处要求用字符串形式是由于算法所限(Object.watch方法的奇怪之处,对象要用字符串形式输入)
* 文本格式以及换行长度都可以随时改变,效果将在下一次drawBmp()函数被调用时呈现
* 直接调用Bitmap-Typer的drawBmp()方法可以立即刷新显示内容
* 注意'Target'是首字母大写,其它属性亦需注意其中的大写字母
制作心得:
测试演示动画时,发现在drawBmp函数里如果去掉开头的bmpPaper.dispose(),则播放器的内存使用会不断上升,(好在播放器似乎会自己删除不再用的数据,观察了个把分钟发现在10M-15M之间波动,猜测这就是垃圾回收机制的体现吧?)相同的参数设定情况下,当加上这句之后内存使用稳定在了8M-9M,总之认为加了是好习惯啊!
flash.geom.Point平时不用声名这个就可以用Point的,但是如果Point里面不是0,0的话,就必须要声明才可以用
之所以做出mc形式,主要是因为flash8的严重bug----用as给中文文本设置字体是无效的,(黑体的话有个斑斑给出的办法是设置字体为'_sans'),我所知唯一的有效办法是手动创建的textField手动设置字体.如果有需要在一个flash中使用多种字体,可以给这个mc建立数个textField,各自设置字体,再由参数决定从哪个textField里刻字出来(当然这样麻烦了,一般只要在库里制作它的具有不同字体的副本即可^_^)其次函数形式无论是返回BitmapData还是返回MovieClip都无法解决自动更新舞台呈现的问题(使用时必须再加代码来呈现)
演示影片中的参数传递遇到困难,费了太多脑筋,代码也写了好几十行.开始觉得没什么难的,全装进数组里面就是了,写了之后发现要用不停的用眼睛和脑子来确定在使用它们时哪里要写settings[0],哪里要写settings[2],特费神,于是打算不用数组直接在mc里放变量,各是各的名字不会眼花,但是这样的话for循环里面又不能访问了----我发现我需要一种数据类型既可以用Array[n]来叫"老大,老二,老三",又可以用Array.state如同"鼠,牛,虎,兔"一样当成对象来访问的,而AS2的Array类看来不可以.虽然C语言里的指针貌似不怎么讨人喜欢,但是此刻我却发现我是那么滴渴望能够使用指针!好在我发现AS2的Array本身是可以当成指针来使的,以为问题解决了,再写代码发现还是不行,因为var name:Type这样的语句中name不能是带有点运算符或数组访问运算符的,也就是说我执行严格数据类型指定只能用于创建代码所在之处的新对象,而不能给某个对象创建指定严格数据类型的属性----这非常让人愤怒!好吧,严格数据类型指定的对象只能存在于声明它们的代码所在的路径下了,我只好让_level0里出现一堆乱七八糟的数据了,如果当初把option菜单做成库元件在里面写代码就就不会这样.肯定有人会说我有毛病了,数据放_level0里又不会死人的,然而我就是有把一切都装进MC里的癖好----时间就是这么浪费掉的.
可惜Windows自带的中文字体太可怜,一种艺术的都没,如果大家机器上都有一些好看的中文字体的话,偶就可以设置那些字体,好玩的多.
还有有件事情值得一提,就是看到了一位前辈说AS2不该提供Bitmap,"会导致滥用"(网站应该是这里http://www.j2eemx.com/ris/index.cfm,不过页面找不到了),于是觉得自己就是滥用BitmapData滴人@_@.
不足之处:
1.由于本人初学,还不会写类,而且还要上学,写成类的日子无法预期,不过论坛里勤劳而又朴实滴斑斑们也许会为大家写出一个类来.如果同学们有多次用我这个东西的话,其实有比做成类来的更简便的方法:就是把"Bitmap-Typer.fla"保存成模板(菜单项目就在Flash8的[文件]菜单里),以后要用,就[新建]->[模板],选它出来.其实这样封装成元件用起来不用写import语句,也比做成类的方便,*_-
2.本人对AS2路径的规则还没摸透,所以出现了给调用mc的函数时加上mc自己作为参数的奇怪写法(因为很郁闷的事情是在mc里面的嵌套函数里,trace(this),通常得到的都是"undefined")不过好在这种情况只出现在用来演示的影片代码里.
另外还有:
option.button.onRollOver = function(){
......
option.createEmptyMovieClip( ......
......
这样的代码,在下级mc的事件里面直接叫上级mc名字的写法,可能不太规范,仓促之故没有仔细考究
2.BitmapData的大小取自文本框的长宽属性值,Bitmap-Typer中当给Bitmap-Typer加上倾斜角度之后发现tf的_height随着实例的_rotate值成余弦曲线一样的变化,结果就是显出的文本高度时大时小,在90度和270度时最窄,都块没了!用textHeight一样,没办法用了取文本行数*字体大小的方法,想不到随着mc的旋转,field.bottomScroll的值竟然能在4-9之间变化(就算字符串的内容长度不变,依然如此,除非我停止更新字符串),后来我在不更新字符串的情况下让mc旋转,再看文本有几行,结果还是在变,一会4行,一会5行,一会9行!我苦思很久也想不明白这是怎么回事,同时认为迈可揉米狄丫真不是一个有多好的公司,那里的工程师们没有为中国的客户考虑周全,结果大家用着不方便,偶现在做滴这些应该由他们在几年前就做好地,实际上我是在给这玩意的文本功能打补丁!(话说回来偶讲这些话脸皮太厚了,因为偶用D版,偶从来没买过什么正版软件)其实讲良心话Flash是可以打90分以上的好产品,偶很想买正版Flash----如果Flash只卖几十块人民币的话.要是Flash软件是中国人开发滴那该有多好......不过我想大家不会象我这样让多行文本一边改变内容一边旋转吧? :-D 希望大家都早日学会用FLEX和AS3
3.目前的算法转换出的图像是带着透明背景的,而不是真正的"没有背景",这样带着很多透明象素会增加运算量和内存的占用,而且生成的图形实际上是矩形的,不能让文字的形状做其他mc的遮罩,以后如果可能,我还是会找时间尝试写抠掉透明象素的版本出来
4.还是仓促之故,滤镜功能没有实现参数设置,而且我把滤镜部分代码设成注释了,理想的做法是在textField上加滤镜(需要用到的老师和同学麻烦你们自己写吧)
5.设计Typer工作时如果监视功能未开启就删除textfield,但mc里面的tf因为是手动添加的,深度为负不能删除,swapDepths方法我试来试去就是换不了深度,觉得好像又是bug,这让我很怒,一怒之下用建立新mc的方法来消灭这家伙,谁知道怎样好删回帖讲呀
6.演示动画中的txt2bmp函数定义成了全局属性,那是由于不这样在MC中就不能调用它,其他动画中某些路径下的对象不能调用影片根轴里函数的情况也不少(记得有些可以有些不行,这也是本人一大疑惑)
7.命名不规范,有首字母大写以及和某些类属性同名的变量之类不符合<ActionScript 2.0 的最佳做法和编码约定>的代码
8.显示单个字符的character剪辑,我想要它们在完成任务后删除自己,但是无论我用removeMovieClip方法还是用removeMovieClip函数都不行,无奈之下只好让他们自动去排队,给flower的blossom函数里加了删除废物队列的代码.最后效果仍然很让人不爽,大家眼力不是太差都看的到的.
9.还有让人笑话的是我以为把Loader做成元件放第一帧就行了,结果发现好像不是,要做成影片来载入影片才对,不过还好整个文件才几十K,要Load的是MP3
本人初学,脑子又笨,进度太慢,因为暑假在家没有做完,开学以后去租房子继续搞,没想到房子实在难租,资金又非常困难,11月8号才拉上网线(一上网发现FLASH9都已经发布了,始终不敢面对----如果AS3中的动态文本已经得到改进,那我这些日子就白辛苦了).这期间由又于诸多原因没有可以囫囵日子可以让我好好搞,而且没有连上网,只能闭门造车,挤出来空闲的时间就断断续续写了这么多废话出来.本来开学就已经搞好,函数版本在国庆之后已经放出来了,但后来打算做个比较华丽的演示,没想到这一做又是半个学期,最后发现我用了几百行代码来演示那几十行代码!真是浪费青春啊!
演示动画中使用的txt2bmp函数和最后发布的不一样,大家要用注意不要用演示里这个,参数少了几个的.
抛砖引玉之作,滤镜参数化以及抗锯齿等特性都未尝试,未列出之不足还有很多;更完善版本正在调试中,希望收到有价值意见及建议,同时期待老师同学们的更强解决方案出现----那样的话偶就不用再在这个问题上花费时间,可以去好好学一阵了@_@(偶还未有时间升级AS3捏).
好想早日学好编程赚钱喔~!
关于MP3/LRC播放器:
LRC解码问题是最头疼的,我弄了两天本以为一句System.useCodepage = true全搞定了,结果发现在Flash设计里测试是正常的,但在Player里运行又成乱码了.后来又发现好像System.useCodepage = true和unescape()都不用反而会好些,到底怎么样大家测试吧.
本来没想要做这玩意的,并且刚想到用它来帮助演示Bitmap-Typer时候打算是直接抄别人的来用(MP3+LRC播放应该有很多人做过了).但是在不能上网的艰苦岁月里,只能靠自己的指头了.偶这个东东简陋而且bug多,并且是个半成品,还不能拖进度,不能调音量,不能用列表……上网以后发现blueidea的HBrO(现任Flash版主)早在今年一月就做出了,汗……就当我那纯粹是练习另一种算法吧.
特别声明:复制内容到剪贴板 代码:演示动画的MP3/LRC播放器使用了mirycat(现任本版版主)的IntervalCaster技术,鸣谢!
由于演示动画在未获得许可的情况下,使用了艺术家陶晶莹的歌曲<吻别>(太老的歌,买不到正版CD了),并且公开传播,所以向其表示公开道歉.我最喜欢听她的歌,希望大家多买她的正版CD.
本贴所见txt2bmp,Bitmap-Typer,MP3/LRC-player及其他源代码使用MarcoMedia(R) FLASH8(R) Professional试用版制作,鸣谢MarcoMedia公司!
QQ群交流:15534025
[ 本帖最后由 xbstu2006 于 2007-1-17 21:34 编辑 ]
|