flash 颜色 action 自定义教程

2006-03-14 15:03:50

默认是红绿蓝都打到最强255,这实际上就是白光。大家可以分别调节3个颜色的灯光强度,看一下白、红、绿、蓝、黑这5个代表性的小球颜色的变化。呵呵,怎么样,很过瘾吧。 下面我说一下这个课件是怎么做的,核心的action代码是颜色的计算和设置部分,下面的拉条做的很不好,半年前做的,现在懒得改了。 如果我们想一个物体的颜色为#996633,代码很简单: mycolor = new Color(themc); mycolor.setRGB(0x996633); 如果仅仅知道各个颜色的大小,就是红色为153,绿102,蓝51: mycolor = new Color(themc); r=153; g=102; b=51; mycolor.setRGB(r<< 16 | g << 8 | b); 我觉得这个算法还是比较巧妙的,通过“左移”和“或”两个运算得到颜色的RGB值大小。 下面看看我课件里的5个小球,白球是反射任何光的。所以颜色就是: onClipEvent (load) { mycolor = new Color(this); } onClipEvent (enterFrame) { mycolor.setRGB(_root.r << 16 | _root.g << 8 | _root.b); } 红球之反射红光,只需把颜色设置改为mycolor.setRGB(_root.r << 16 |0); 同理,绿球:mycolor.setRGB(_root.g << 8 |0); 蓝球:mycolor.setRGB(_root.b); 黑球什么颜色的光都不反射,就是:mycolor.setRGB(0x000000); 简单吧! 你如果说,一个对红光反射75%,绿光50%,蓝光25%的物体,什么颜色, mycolor.setRGB(Math.floor(_root.r*0.75) << 16 | Math.floor(_root.g*0.5) << 8 | (_root.b*0.25));X 不要忘记Math.floor()啊,我们要的可是整数,不然出错的话,flash自动设为黑色。 是不是很简单啊,大家可能开始看到我做的flash的时候,很惊讶,看到源码,又太简单。但是我为了想到这个制作思路,可是画了很多很多的时间啊。教程写的不好,希望对大家能有一点点用处。 今天的基础教程主要是介绍一下RGB的基本知识,和flash中RGB设置的基本方法。以后我会再写一些扩展方面的内容,不如怎么设置比较漂亮随机颜色,怎么计算颜色渐变,怎么模拟彩虹……请大家拭目以待!:cool: 前面基础篇里我们讨论了怎么设置指定的颜色,我觉得不能算是很难的。但是一位朋友通过qq告诉我,他觉得有一点吃力。对此我很抱歉,以前我一直觉得有些ction的基础问题是不用多解释的,大家查查参考手册就是,现在看来朋友们的实际情况还是差别很大的,以后我会在这些方面注意一些,每一个新语句都加上注释。 上次说得是颜色设置的基础,代码实际上只有两三句,从现在看时我们来继续说说颜色问题的一些深入问题,大概代码会逐渐的多起来,有我写的不明白的地方,大家结合提供的源文件看一下,或者在后面跟贴提问。 今天这一讲教程咱们看看随机颜色的问题,这个问题论坛上常有讨论,算是个老问题了。 我觉得实现随机颜色最简单的一句就是: mycolor = new Color(this); //新建一个color对象,名字是mycolor,指定的mc是它本身 mycolor.setRGB(random(0xffffff)); //mycolor对象设置RGB颜色,取色范围是从0到0xffffff随机 好像已经没有办法使代码更少了吧?如果有,告诉我。我这一篇教程里面随机比较多,每一个都单独做swf很麻烦,我于是干脆做到一起来,用区域来区别。并且提供了flash源文件,大家那我提供的代码替换掉ball这个mc里的action,可以自己预览一下看看,还可以自己随便做做修改看看。这一段代码是区域1。 但是我觉得这样最不好的方面在于,得到的很多色彩效果可能不太好,比如太接近白色不容易和背景区别,或者颜色太深了感觉不美观。 如果我们希望颜色分布在一个区间之内,比如不希望出现接近红色的颜色,好办: mycolor = new Color(this); mycolor.setRGB(random(0x80ffff)); (区域2) 因为红色是最大的一位,但是不希望出现接近绿色的,可就不能random(0xff80ff)了,不信你自己改改试试。这是因为在random函数看来,0x00ff00也是比0xff80ff小的,没办法了吧。 我的改进方法是三色分别random,然后再用“左移 << ”和“或 | ”的方法组合成一个数值。这种方法我在基础篇就用过,我觉得算不得新方法了。这是全色系的随机函数: mycolor = new Color(this); mycolor.setRGB(random(255)<<16|random(255)<<8|random(255)); (区域3) 如果仅仅是这样用,和开始那种方法比,除了显得深奥,实在是没什么优点了。不过我们想再进一步做修改就容易了,刚才那个不要绿色,就可以: mycolor = new Color(this); mycolor.setRGB(random(255)<<16|random(128)<<8|random(255)); (区域4) 如果想得到红色0xff0000和黄色0xffff00之间的颜色,因为红色和黄色之间只有g在改变,可以把r和b固定,仅仅random绿色: mycolor = new Color(this); mycolor.setRGB(255<<16|random(255)<<8|0); (区域5) 再比如不希望得到太深的颜色,只需要使random值不要太小,比如rgb三色加起来不小于384吧: mycolor = new Color(this); while (r+g+b<384) { r = random(255); g = random(255); b = random(255); } //默认rgb都为0,循环执行;如果rgb相加小于384,继续random,直到r+g+b大于等于384 mycolor.setRGB(r << 16 | g << 8 | b); (区域6) 怎么样?这下看出三色分别计算方便的地方来了吧。最后举了好多好多的例子,大家还可以继续举下去,我就不一一生成swf文件给大家看看了,有源码,大家自己动手DIY吧。 下次我们来说说怎么做根据一个数值的变化得到连续的颜色变化,就像染色的地形图似的那种。再说说怎么用action实现计算机上像彩虹那样的呈现赤橙黄绿青蓝紫连续变化的色谱。还是那句话——请大家拭目以待。 [img]attachments/month_0603/if8l_color.jpg[/img] 这样用颜色来表示y轴数值的大小,还是很直观的,怎么做的呢?有了前面关于颜色讨论的基础,我想大家应该都差不多猜出做法来了,就是把rgb中的一个跟随变量的增加而增加,就像这样: for (n=1; n<=200; n++) { attachMovie("ball", "ball"+n, n); //复制200个点 this["ball"+n]._x = 2*n; y = Math.sin(n*Math.PI/100)*100+150; this["ball"+n]._y = y; //设置点的位置 mycolor = new Color(this["ball"+n]); mycolor.setRGB(255 << 16 | Math.floor(255*(y-50)/200)<<8 | 0); //根据y的位置定义点的颜色 } 关键就在红色的Math.floor(255*(y-50)/200)<<8处,为什么这么写我就不用解释了吧?大家应该都明白了吧?不明白再问。 看了上面的颜色渐变,大家肯定想做出更复杂的颜色渐变吧,看看下面: [img]attachments/month_0603/sphv_color2.gif[/img] 是不是很有意思啊,下面是用flash自带的调色板做的渐变,上面是用action计算出的渐变。看起来好像很麻烦,其实也很容易的,因为我们只要知道了色谱渐变的规律就行了,色谱渐变关键是找关键点。大家可以在连续色谱上自己距离不远取取颜色看看,很快就可以发现规律。写出来就是: FF0000-g增加-FFFF00-r减少-00FF00-b增加-00FFFF-g减少-0000FF-r增加-FF00FF-b减少-FF0000 这是一个分段函数,用action实现起来就是: a = Math.floor(n*6/nmax); b = Math.floor((n*1530/nmax)%255); //nmax=320;n从1增加到320;所以a最小值0,最大值6;b最小值0,最大值255 if (a == 0 || a == 6) { mycolor.setRGB(255 << 16 | b << 8 | 0); //FF0000--FFFF00段 } else if (a == 1) { mycolor.setRGB((255-b) << 16 | 255 << 8 | 0); //FFFF00--00FF00段 } else if (a == 2) { mycolor.setRGB(0 | 255 << 8 | b); //00FF00--00FFFF段 } else if (a == 3) { mycolor.setRGB(0 << 16 | (255-b) << 8 | 255); //00FFFF--0000FF段 } else if (a == 4) { mycolor.setRGB(b << 16 | 0 | 255); //0000FF--FF00FF段 } else if (a == 5) { mycolor.setRGB(255 << 16 | 0 | (255-b)); //FF00FF--FF0000段 } 呵呵,是不是很容易?怎么把这一段代码用到实际编程中去,大家还是自己来吧,我就不多举例子了。 不过需要说明的是,如果去掉FF00FF--FF0000这一段的代码,这个渐变次序很符合彩虹赤橙黄绿青蓝紫的变化规律的,但是和彩虹可是不一样的。自然界的可见光波长一般从4000埃(长度单位,10的-10次方米)到7600埃,它们的颜色转变成RGB颜色和肉眼的光感特性有关,并不是线性变化的。不过如果拿这个渐变示意彩虹的话,我想是可以的,我在杨氏双缝干涉实验这个课件里就是这么做的。 颜色渐变写完了,下次写写颜色(色光)叠加,其实在我原来的计划里,我没有打算加入色光叠加的内容,因为我可以说以前从来没有认真的想过,但是在那天和cnmusa网友经过讨论之后,我感觉我找到了计算色光叠加的方法,而且经过简单的验证,我认为这种算法是正确的。所以我把色光叠加作为RGB颜色action自定义教程的第四部分内容,希望大家喜欢。 最后,还是那句话,希望大家拭目以待! 通过前几篇教程,相信大家对于RGB颜色方面的编程应该已经是得心应手了吧?还有一个方面我们没有涉及,那就是:颜色叠加。等这一篇写完,我想我的这个RGB教程也该结束了,因为我肚子里可就只有这么点东西了。 这个色光叠加部分,更多的是一种想法,连算法都算不上。因为这一部分连可以copy了直接用的代码都没有,只有一个swf文件,还是为了演示用的,不过我想这个swf里模仿photoshop的取色器大概还是有一点意思的,因为这不是本节的重点,大家还是自己分析源码吧,看过上一节和这一节后,应该不难理解! 言归正传,我们都知道可以用RGB的3色值来表示一个颜色。但是这并不是说我们在实际中看到的眼色就是由3原色光叠加组成的(计算机屏幕自然如此),而是说这种光的颜色和对应的3色光叠加对人眼的刺激是相同的,也就可以等效起来了。因此或许如果对于别的生物,比如猫,因为眼睛构造的不同,我们看来屏幕上和实物完全相同,猫看起来却不一样。这一部分在学科划分上属于色度学和心理学(交叉),大家有兴趣可以自己找资料看一看。 说这些废话是为了分清楚一件事情,光叠加和色(比如水彩)叠加。红光加上绿光看起来是黄光,但是红墨水掺上绿墨水可就差不多是黑的了。我们在计算机上所作的,都是光叠加的内容。 如果是一束ff0000的光和一束00ff00的光线叠加,是什么颜色?不错,是黄色:0xffff00。这也种简单的叠加方法其实也适合于更复杂的情况。 看到这里大家可能有一个担心,如果一种色光的强度超过255怎么办?很简单,超过255就把他设置为255,可不要进位啊!呵呵,开个玩笑。其实,这个担心是多余的,我们能证明,实际的情况中,永远也不会出现某一色光强度超过255的情况,最高等于255。 我觉得色光叠加最核心的问题是:如果是一个半透明的东西覆盖在另一个物体上,颜色怎么计算? 这可能是很多网友最头疼的问题之一,我也是和cnmusa讨论这个到问题才开始深入的思考色光叠加问题的。为简单考虑,我们先考虑整块的色块。一个色块的alpha值是30,意味着什么?就是说他本身的颜色我们可以看到30%,有70%(1-30%)的底色可以透过它射上来。是不是这个样子的呢?我们来做一下验证,看下面这个flash。 在这个flash,你可以自己选择底色、覆盖层颜色、覆盖层透明度,然后看看我根据刚才那个原理预测的颜色是否和实际颜色相同。因为用了很多Math.floor(),肯定有误差,但是到目前我自己还没发现误差很大的情况。基本上可以证明,我关于半透明覆盖的猜想是正确的。 那现在我们可以得出计算公式了: 叠加色r=覆盖色r*覆盖alpha+底色r*(1-覆盖色alpha); 绿和蓝也是如此,然后再3色组合起来。 在我的这些flash文件里,rgb都是自己定义的,开始就是分立的。如果不是这样,那我们如果怎么得到一个诸如0xf456c7这样的颜色代码的rgb分立值?很简单: color=0xf456c7; r=(color&0xff0000)>>16; g=(color&0x00ff00)>>8; b=color&0x0000ff; 如果大家不明白,用下面这个也是一样的: color = 0x666666; r = Math.floor(color/65536); g = Math.floor((color-65536*r)/256); b = color-65536*r-256*g; 是不是很简单?:) 色光叠加写完了,我的这个《RGB颜色action自定义教程》也就算是可以告一段落了,写的不好,占用了大家很多的宝贵时间来都读、看,甚至是替我改错,真是非常感谢。其中特别感谢desigm、cnmusa两位网友。:D 希望大家对本教程的各种错误、不足提出意见,我将尽力将它修改完善。我也将继续就网友提出的各种问题在论坛为大家作出解答,谢谢大家。:D [img]attachments/month_0603/96xb_color3.jpg[/img]