打造完美物体空间散射
[color=Red]提示:这是个很妙的效果,说这句话是为了引起你的阅读兴趣,提供思路为主,以文字为例,更好的效果如把文字换成图片散射依照这个思路应当可以很完美的实现,同时,第三部分的BUG已经清除,所以我对本文章作下修改,谢谢各位的帮忙。[/color]
[color=Red]第一部分:同一坐标点散射,类似烟花效果[/color]
目标:大量文字从一个原点向四周散射
[color=Red]关键字:大量 一个原点 散射
“大量”———————很显然,要用到duplicatemovieclip或者attachmovie,这里我选择attachmovie,至于
什么原因,以下我将阐述。
“散射”——————x,y偏移,结合Math.random()就是随机偏移.随机数的取值要有正且有负,因为散射是四
面八方的X,Y偏移。
“一个原点”————这个效果的原理理解关键点就在这里,一个原点,换句话说就是将复制出来的MC坐标归
于一个位置,这样任意一个x,y偏移值,播放起来就是一个散射,他不同于那种“不同坐标点散射”,即如果
你把复制出来的坐标值随机设定,加上一个单纯的x,y偏移,MC会到处乱飞,画面会毫无规律。这一点一定
要理解。[/color]
实现步骤:
1,随便做个带文字的MC,在库中linkage名为mymc
2,舞台时间轴代码:
LEFT = 0;
TOP = 0;
RIGHT = Stage.width;
BOTTOM = Stage.height;
maxspeed=25
maxmc=100
minmc=20
function randrange(min,max){
var randomnum=Math.floor(Math.random()*(max-min+1))+min
return randomnum
}//自定义函数,取两数之间的随机数
mcnum=randrange(minmc,maxmc)
trace(mcnum)//测试用
for(i=0;i<=mcnum;i++){
dupmc=attachMovie("mymc","mymc"+i,10+i)
trace(dupmc)//测试用
dupmc._x=200
dupmc._y=200//设定同一个坐标位置
dupmc._xscale=dupmc._yscale=randrange(0,100)
dupmc.speedx=randrange(-maxspeed,maxspeed)
dupmc.speedy=randrange(-maxspeed,maxspeed)//每一个复制出来的MC都会有一个随机x,y偏移(从自己
的负值到自身值,保证了坐标既有正也有负)
dupmc.onEnterFrame=function(){
[color=Red]this._x+=this.speedx
this._y+=this.speedy[/color]
if (this._x < LEFT || this._x > RIGHT || this._y < TOP || this._y > BOTTOM) {
this.removeMovieClip();
}//end if
}
}
ok,代码结束,以下我谈谈我为什么不用duplicatemovieclip而用attachmovie
我们都知道把duplicatemovieclip或attachmovie前面加一个变量,很方便调整MC属性,书写也简单,但实
现方式有两种。
起初我是用duplicatemovieclip,前面设定了一个变量,即:
dupmc=duplicatemovieclip("mymc","mymc"+i,10+i)
trace(dupmc)//测试用
输出undefined,而换成attachmovie就能正常输出了
所以我选择了attachmovie,但说实在话,attachmovie也不是什么好鸟,MC一大,就会延迟进度,所以这
是个问题,欢迎共同探讨,我就来抛砖引玉。
欣赏地址:[attach]90019[/attach]
源代码下载:[attach]90018[/attach]
[color=Red]第二部分:不同坐标点的文字散射[/color]
目标:文字呈一种空间放射状散射出来,并不断循环,外加透明度,缩放比例动态调整塑造立体感,空间
感。
[color=Red]要点:空间感和节奏感(动作执行有间隔,逐个出现并依次放射)
概念理解:MC内部时间轴的坐标系是制作空间感最好的坐标系,任何点无论在在哪个象限内,用坐标值乘
以一个递增的正变量,都可以达到放射的目的。
首先,得明白主时间轴和MC内部时间轴的坐标差别——————推出MC内部时间轴坐标特点:就是一个直
角坐标系,中心为原点,分为四个象限,这正是我们所要的坐标系,因为我们要放射,坐标值的偏移应该
有正有负,而在舞台的时间轴,画面只能显示_x>=0&&_y>=0的区域,是个不易操作的坐标系。下面来举
个例子说明MC内部时间轴的坐标系是制作空间感最好的坐标系。[/color]
以一个公式开头(在头脑中画出高中数学的直角坐标系):
mymc._x = a*c
mymc._y = b*c
其中,a,b是坐标系中随机的一个点,它的x坐标为a, y坐标为b, c是一个递增值。
那现在推算下是不是无论该点在哪个象限内,都可以达到放射的目的呢?
在第一象限:a>0,b>0,c递增————————X坐标不断增加,同时Y坐标也不断增加————放射
在第二象限:a<0,b>0,c递增————————X坐标不断递减,同时Y坐标不断增加————放射
在第三象限:a<0,b<0,C递增————————X坐标不断递减,同时Y坐标也不断递减————放射
在第四象限:a>0,b<0,c递增————————X坐标不断增加,同时Y坐标不断递减————放射
[color=Red]思路:首先,在限定范围内(最好小一点,为他的散射留出更多空间,这样会觉得字从很深的地方飘来,
以下我限定的是-10——9),为复制的MC设定一个随机位置,这就相当于我上面所举例子中的a和b,他们
其实是个坐标初值。
然后,要达到放射效果,还需要一个递增的正变量,即c,[/color]
所以我打了个字,转换成了MC,再次转换,命名为mymc,并延长至第3祯,新建一AS层。
为了让要出现的东西依次出现(既可以体现节奏感,又可以防止文字重叠现象),我选择祯循环的编程方式
。
第一祯:设一些要用到的变量初值
mymc._alpha = 0;
i = 1;
numOfText = 20;
minOfZ = 1;
maxOfZ= 120;
第二祯:主程序
function randrange(min,max){
var randomnum=Math.floor(Math.random()*(max-min+1))+min
return randomnum
}//自定义函数,取两数之间的随机数
duplicateMovieClip("mymc", i, i);
this[i].x = randrange(-11,9);
this[i].y = randrange(-10,9)//我选择的初始坐标范围是-10到9
this[i].z = random(maxOfZ)+1;//1——120之间的整数
this[i].dz = -2;
this[i].gotoAndStop(random(this[i]._totalframes)+1);
this[i].onEnterFrame = function() {
this.z += this.dz;//做加速运动
if (this.z<minOfZ) {
this.x = randrange(-11,9);
this.y = randrange(-10,9)//这里的this也可以改为this[i]
this.z = maxOfZ;//this.z<minOfZindex时,也就是MC到达极限透明度,X,Y,比例
时,此时他已经超出了舞台,要不间断播放,需要重新设定他的初值
}
this.pers =600/this.z;//由于每次减2,所以this.z最小值为2,因为再减2就为0了,小于1
this._x = this.x*this.pers;
this._y = this.y*this.pers;//this.pers会越逐渐递增
this._xscale = this._yscale=this.pers;
this._alpha = 1000/this.z;//这里的1000你也可以改,不过别太小
};
第三祯:条件判断
i++;
if (i>=numOfText) {
stop();//停在第二祯
}else{
gotoAndPlay(_currentframe-1);
}
顺便提一下,我们要的c就是代码中的this.pers=600/this.z,他是个递增函数,且恒正。
很简单吧,测试下,思考下,也许你会比我想到的更多。
欣赏地址:[attach]90020[/attach]
源码下载:[attach]90021[/attach]
[color=Red]第三部分:XML控制散射内容[/color]
目标:我们先前散射出来的内容是固定的,在经典里前不久看到一篇帖子,说如何用XML控制显示内容,所
以特来介绍。
思路:简单的XML载入
步骤:1,把第二部分中包含三祯的MC删除,重建一个MC,实例名为mymc,在内部拉一动态文本框,实例名
为mytxt,变量名为content,这里要注意,这也就是我起先出现BUG的关键点所在,一定要设“嵌入字体”,
把a-z,A-Z,0-9都嵌入进去,至于原因,蓝紫光解释得很清楚。
2,在MYMC内部时间轴加动作,我们荏苒采用祯循环方式变成
第一祯:定义初始变量,载入XML文件并取节点值
stop();
mymc._alpha = 0;
i = 1;
numOfText = 20;
minOfZ = 1;
maxOfZ= 120;
var myxml=new XML()
myxml.ignoreWhite=true
myxml.onLoad=function(suc){
if(suc){
gotoAndPlay(2);
mylist=this.firstChild.childNodes
}
}
myxml.load("myxml.xml")
第二祯:主程序
function randrange(min,max){
var randomnum=Math.floor(Math.random()*(max-min+1))+min
return randomnum
}//自定义函数,取两数之间的随机数
duplicateMovieClip("mymc", i, 10+i);
this[i].x = randrange(-11,9);
this[i].y = randrange(-10,9)
this[i].z = random(maxOfZ)+1;//1——120之间的整数
this[i].dz = -4;
this[i].mytxt.text=mylist[i].attributes.content
this[i].onEnterFrame = function() {
this.z += this.dz;
if (this.z<minOfZ) {
this.x = randrange(-11,9);
this.y = randrange(-10,9)//这里的this也可以改为this[i]
this.z = maxOfZ;//this.z<minOfZindex时,也就是MC到达极限透明度,X,Y,比例
时,此时他已经超出了舞台,要不间断播放,需要重新设定他的初值
}
this.pers =600/this.z;//由于每次减2,所以this.z最小值为2,因为再减2就为0了,小于1
this._x = this.x*this.pers;
this._y = this.y*this.pers;//this.pers会越逐渐递增
this._xscale = this._yscale=this.pers;
this._alpha = 1000/this.z;//这里的1000你也可以改,不过别太小
第三祯:条件判断
i++;
if (i>=mylist.length) {
stop();
}else{
gotoAndPlay(_currentframe-1);
}
[color=Red]注意点:载入延迟问题解决方案[/color]
第一祯代码我为什么要加个stop();,然后通过条件判断myxml.onLoad执行gotoAndPlay(2);?
还是一个载入延迟问题,参考我的一篇帖子:[url]http://bbs.blueidea.com/thread-2859991-1-1.html[/url]
和loadmovie差不多,如果我不加个STOP,影片就会从1到3毫无障碍地播放,由于XML载入的延迟性,在
XML文件还没载入完毕之前(一般是一轮,从1到3播放完毕一遍的时间)所执行的程序里面根本无法取得
节点,则mylist也将是NaN,那么紧跟的第二祯里面this[i].mytxt.text=mylist[i].attributes.content取不到
值,文本内容会是undefined,也就是说不按我那样弄的话的直接后果将是所载入的MC中有一个文本内容为
undefined。
欣赏地址:由于有XML,无法欣赏
源码下载:[attach]90090[/attach]
后续:我只是以文字形式具体讲解了散射特效,你可以把文字换成图片并用XML载入,鼠标控制空间移动,
等等,需要我们共同去想。
[[i] 本帖最后由 SUNXINZHE 于 2008-6-2 19:03 编辑 [/i]] 这么好的教程,谢谢楼主.希望大家多发些AS的. flash023,能帮忙看下吗
很信赖你的 我还是觉得AE做出来比较好. 1,在影片播放前一段时间(初步估计是在mymc复制完毕之前),舞台上有一个mymc老是不消失,而且还在不断更新显示内容。尔后一切正常。
2,我的文件大部分是由代码组成的,理论上应该很小,测试速度也应当很快,但测试时,到了中间部分就停下来了,半天显示不出来,不知道是不是载入XML的问题,还是哪个代码不够优化。
3,播放不大流畅,估计是动态载入文字造成的锯齿问题。
第一条和第三条都是因为动态文本惹的祸..第二条我不太懂是什么意思.也没有看到什么问题..所以我来解决第三条..
解决方案:
进入mymc中,选中mytxt文本.你使用的字体是Verdana,这个没有问题.但是把加粗去掉.然后点击嵌入,把A~Z,a~z,0~9嵌入进去后一切正常...
在这里注意两点.去掉一加粗,一定要去掉.因为嵌入的是没有加粗时的字体.第二点.字体消除锯齿应该选择"动画消除锯齿";经过测试这种效果是最好的.."位图消除锯齿"和"可读性消除锯齿"都会出现锯齿及抖动.. 第一条可以把mymc丢到舞台外面去。 HOHO!~!~
按照我说的方法的话就已经解决第一条和第三条了... 谢谢紫极光
问题清除了,马上修改,原来还真没想过一个“嵌入字体”还会引来这么大的麻烦,开始还以为是代码不优化,有没有时间把关于“嵌入”的所需要注意的地方列出来,如字体的选择就是个很好的话题。
至于6楼newaraya所说的,我就不客气的说哈,我做的时候还比你“偏激”,我完全剥夺了他在舞台出现的机会,用的是attachmovie都没解决,才知道是别的问题,要是那样能解决的话我也没必要还专门搞个“特别求助”了,不过你的思维是那样,应该考虑到这种情况,共同学习吧。 嵌入字体的和英文没问题.中文的话.嘿嘿....所以考虑考虑吧.如果要做一个项目需要特定的字体的话直接嵌入就行了..但是如果想通用的话..哈哈....想别的办法吧.. 哦,谢谢,明白
下载要注意:第三部分请下带有“源码下载:”字样后面的链接
最后一个链接不是我最后修改的,也不知道怎么去除了,编辑里面也看不到, 鼓励原创.代码内有不少地方值得商酌.
多用var,会让你代码运行效率更高
不要每个MC都onEnterFrame,都放到一个容器里循环
attachMovie出来的东西可以直接赋予属性.如attachMovie("mc","mc",1,{_x:100,_y:100})
主场景里也不要用帧循环了.
在确定了同屏幕元素最大值的情况下,可以不removeMovieClip,而是重新赋予初始值使它运动,这样可以避免更多运算.
只是建议,希望能再接再厉.:) 对我来说,这篇帖子最有价值,代码优化是编代码的重要内容,这正是我的薄弱环节,哈哈,感激不尽。
不过有些我将做些解释,下面我编号说明:
1,多用var,会让你代码运行效率更高
2,不要每个MC都onEnterFrame,都放到一个容器里循环
3,attachMovie出来的东西可以直接赋予属性.如attachMovie("mc","mc",1,{_x:100,_y:100})
4,主场景里也不要用帧循环了.
5,在确定了同屏幕元素最大值的情况下,可以不removeMovieClip,而是重新赋予初始值使它运动,这样可以避免更多运算.
1——————用var和不用var,包括一般变量后面的数据类型,在我的概念中是一样的,var到底有什么优化之处呢,还请说明。
2——————这一点我承认,会浪费很多计算资源,不过我改成:
mymc2.onEnterFrame=function(){
dupmc._x+=dupmc.speedx
dupmc._y+=dupmc.speedy
if (dupmc._x < LEFT || dupmc._x > RIGHT || dupmc._y < TOP || dupmc._y > BOTTOM) {
this._parent.removeMovieClip();
}//end if
}
结果只有一个MC在动,其他的没效果,不知错在哪儿?
3——————这点以前确实没用过,很好。能解释下为什么用dupmc=duplicateMovieClip("mymc","mymc"+i,10+i)
trace(dupmc)
输出undefined,没道理啊,我在文章中提过的。
4——————我采用祯循环是为了让MC依次出现,至于优势我也说了的,难道有什么不对的。
5——————removeMovieClip问题,我是在第一部分的实例中用到的,因为为了简单说明问题,我只想让他出现一次,故浪费不了什么资源,但如果是要重复执行的话,最好的就是采用重赋值的方法,在第二部分代码中应用过的:
if (this.z<minOfZ) {
this.x = randrange(-11,9);
this.y = randrange(-10,9)//这里的this也可以改为this[i]
this.z = maxOfZ;//this.z<minOfZindex时,也就是MC到达极限透明度,X,Y,比例
时,此时他已经超出了舞台,要不间断播放,需要重新设定他的初值
} 这帖中有不少值得学习的地方,做个标记。呵。 蓝色月光 1. [url]http://bbs.blueidea.com/thread-1057820-1-1.html[/url]
2. 你需要一个容器来放置需要进行属性变动的对象,在循环里枚举出来
3. 你需要这么写:var tmp = mc.duplicateMovieClip("mc1", 1);trace(tmp);
4. xml有个onData方法,你可以利用其进行扩展.附件里有个XMLloader,希望能对你有所帮助.这里使用帧循环是浪费资源的,可扩展性也不好. 谢谢,1,2,3明白,都测试过了,4不怎么熟悉,慢慢看咯 月光:
关于祯循环“可扩展性也不好.”如何解释?
如果我不用祯循环,又要保证依次出现,在有限坐标空间内不出现重叠,有什么方法能够达到目标呢?我好象还没发现。
:D ;-) :mad:
刚看了下你给我的XMLLOADER,你是在帮我解决“XML载入延迟问题”吧,好象和解决祯循环没什么关系啊,同时觉得有一点小题大做的味道,直接用ondata简单判断下就行了,当然我写得不够严谨,ondata是当 XML 文本从服务器完全下载后,或当从服务器下载 XML 文本的过程中出现错误时调用,我忽视了SRC为null即下载 XML 文本的过程中出现错误时的情况,嘿嘿,个人之见,也许我还没碰到钉子,不过,又给了我一种新的思路和提示,感谢。
受你提供的类的启示,谈谈我对ondata的一点看法,不知对不对:
ondata=function(src){.....}
依据src是不是空,最多有三个判断,即开始载入,载入完成,载入失败三个,差了一个类似moviecliploader的过程监视,可惜,关于这方面的好象有人写过用自定义类方法解决,不过复杂, 有没有什么新的思路。 我只是不建议在时间轴里使用循环,不利于外部控制.
别忘了onEnterFrame就是帧循环...setInterval也一样能达到效果
对于AS项目,我个人建议还是单帧的好.
关于XML的加载进度,你也可以用MovieClipLoader来加载xml,一样能在progress里显示
不过基于XML文件通常不会太大,在目前的带宽下基本可以忽略 明白了你所指“祯循环”
以后会尽量避免
用MovieClipLoader监视XML的加载进度,真没用过,简略说下吧。 对不起..是我记错了.不是MovieClipLoader.
XML类自带了onHTTPStatus和getBytesLoaded,getBytesTotal方法,相信能满足你的要求. 这个会用 如果你的文字转成Bitmap,再放到舞台会更平滑流畅。
回复 sheetstone 在 22# 的帖子
楼上想法很好可以实现
页:
[1]