一、基础
先讲讲历史。一天,一个名叫罗伯特-布朗(Robert Brown)的植物学家正在观察一滴水中的花粉颗粒,随后他发现这些花粉是在随机运动的。虽然它们不是水流或水的运动,但是这些小小的颗粒却永远不会停下 来。他发现同样的事情会发生在微尘中,但它们不会像花粉那样游泳。虽然他不知道为什么会有这种现象,其实不只是他还有其他所有人在几十年内都不能给出解 释,但是他却将这种现象用自己的名字命名 —— 只是为了能意识到它!
当今,我们对布朗运动的解释是大量的水分子在一滴水中不断运动,虽然水滴看上去是静止的。这些水分子与花粉和灰尘发生碰撞,将一些动量传给它们。因为即使 是一颗小小的灰尘都要比一个水分子重上一百万倍,所以一次碰撞不会带来多大的影响。但是当每秒有几百万次的碰撞时,那么这些动量就会累计起来。
现在,一些水分子也许撞到了灰尘的一边,而另一些则撞在了另一边。最终,它们会达到总的平均值。但是,随着时间的变化,受到更多撞击的一边就会产生波动, 假设为左边,那么这个粒子就会向右运动一点。底部所受撞击越多,则粒子向上运动得就越多。最后所有的值趋于平均,最终的结果通常不会在任何一个方向产生太 多的动量。这就是随机悬浮动作。
我们可以在 Flash 中轻松地模拟出这种效果。在每一帧中,计算一个随机数加在运动物体的 x 和 y 速度中。随机的数值应该即可以是正数也可以是负数,并且一般来说都非常小,比如范围从 -0.1 到 +0.1。形式如下:

  1. vx += Math.random() * 0.2 - 0.1;
  2.     vy += Math.random() * 0.2 - 0.1;

用 0.2 乘以一个随机的小数,所得的值从 0.0 到 0.2。再减去 0.1 则值变为 -0.1 到 0.1。在这里加入一些摩擦力(friction)很重要,否则速度会增大,并产生不自然的加速。在 Brownian1.as 中,我创建了 50 个粒子并让它们以布朗运动的形式悬浮。粒子就是我们熟悉的 Ball 类的实例,让它们为黑色并缩小。以下是代码:

  1. package {
  2.     import flash.display.Sprite;
  3.     import flash.events.Event;
  4.     public class Brownian1 extends Sprite {
  5.         private var numDots:uint=50;
  6.         private var friction:Number=0.95;
  7.         private var dots:Array;
  8.         public function Brownian1() {
  9.             init();
  10.         }
  11.         private function init():void {
  12.             dots = new Array();
  13.             for (var i:uint = 0; i < numDots; i++) {
  14.                 var dot:Ball=new Ball(1,0);
  15.                 dot.x=Math.random()*stage.stageWidth;
  16.                 dot.y=Math.random()*stage.stageHeight;
  17.                 dot.vx=0;
  18.                 dot.vy=0;
  19.                 addChild(dot);
  20.                 dots.push(dot);
  21.             }
  22.             addEventListener(Event.ENTER_FRAME, onEnterFrame);
  23.         }
  24.         private function onEnterFrame(event:Event):void {
  25.             for (var i:uint = 0; i < numDots; i++) {
  26.                 var dot:Ball=dots[i];
  27.                 dot.vx+=Math.random()*0.2-0.1;
  28.                 dot.vy+=Math.random()*0.2-0.1;
  29.                 dot.x+=dot.vx;
  30.                 dot.y+=dot.vy;
  31.                 dot.vx*=friction;
  32.                 dot.vy*=friction;
  33.                 if (dot.x>stage.stageWidth) {
  34.                     dot.x=0;
  35.                 } else if (dot.x < 0) {
  36.                     dot.x=stage.stageWidth;
  37.                 }
  38.                 if (dot.y>stage.stageHeight) {
  39.                     dot.y=0;
  40.                 } else if (dot.y < 0) {
  41.                     dot.y=stage.stageHeight;
  42.                 }
  43.             }
  44.         }
  45.     }
  46. }

二、拓展
1、方形分布

  1. package {
  2.     import flash.display.Sprite;
  3.     public class Random2 extends Sprite {
  4.         private var numDots:uint=300;
  5.         public function Random2() {
  6.             init();
  7.         }
  8.         private function init():void {
  9.             for (var i:uint = 0; i < numDots; i++) {
  10.                 var dot:Ball=new Ball(1,0);
  11.                 dot.x = stage.stageWidth / 2 + Math.random() * 100 - 50;
  12.                 dot.y = stage.stageHeight / 2 + Math.random() * 100 - 50;
  13.                 addChild(dot);
  14.             }
  15.         }
  16.     }
  17. }

2、圆形分布

  1. package {
  2.     import flash.display.Sprite;
  3.     public class Random3 extends Sprite {
  4.         private var numDots:uint=300;
  5.         private var maxRadius:Number=50;
  6.         public function Random3() {
  7.             init();
  8.         }
  9.         private function init():void {
  10.             for (var i:uint = 0; i < numDots; i++) {
  11.                 var dot:Ball=new Ball(1,0);
  12.                 var radius:Number=Math.random()*maxRadius;
  13.                 var angle:Number = Math.random() * (Math.PI * 2);
  14.                 dot.x = stage.stageWidth / 2 + Math.cos(angle) * radius;
  15.                 dot.y = stage.stageHeight / 2 + Math.sin(angle) * radius;
  16.                 addChild(dot);
  17.             }
  18.         }
  19.     }
  20. }

3、圆形均匀分布

  1. package {
  2.     import flash.display.Sprite;
  3.     public class Random4 extends Sprite {
  4.         private var numDots:uint=300;
  5.         private var maxRadius:Number=50;
  6.         public function Random4() {
  7.             init();
  8.         }
  9.         private function init():void {
  10.             for (var i:uint = 0; i < numDots; i++) {
  11.                 var dot:Ball=new Ball(1,0);
  12.                 var radius:Number=Math.sqrt(Math.random())*maxRadius;
  13.                 var angle:Number = Math.random() * (Math.PI * 2);
  14.                 dot.x = stage.stageWidth / 2 + Math.cos(angle) * radius;
  15.                 dot.y = stage.stageHeight / 2 + Math.sin(angle) * radius;
  16.                 addChild(dot);
  17.             }
  18.         }
  19.     }
  20. }

4、偏向分布(1维6次迭代)

  1. package {
  2.     import flash.display.Sprite;
  3.     public class Random6 extends Sprite {
  4.         private var numDots:uint=300;
  5.         private var maxRadius:Number=50;
  6.         private var iterations:uint=6;
  7.         public function Random6() {
  8.             init();
  9.         }
  10.         private function init():void {
  11.             for (var i:uint = 0; i < numDots; i++) {
  12.                 var dot:Ball=new Ball(1,0);
  13.                 var xpos:Number=0;
  14.                 for (var j:uint = 0; j < iterations; j++) {
  15.                     xpos+=Math.random()*stage.stageWidth;
  16.                 }
  17.                 dot.x=xpos/iterations;
  18.                 dot.y = stage.stageHeight / 2 + Math.random() * 50 - 25;
  19.                 addChild(dot);
  20.             }
  21.         }
  22.     }
  23. }

5、偏向分布(2维6次迭代)

  1. package {
  2.     import flash.display.Sprite;
  3.     public class Random7 extends Sprite {
  4.         private var numDots:uint=300;
  5.         private var maxRadius:Number=50;
  6.         private var iterations:uint=6;
  7.         public function Random7() {
  8.             init();
  9.         }
  10.         private function init():void {
  11.             for (var i:uint = 0; i < numDots; i++) {
  12.                 var dot:Ball=new Ball(1,0);
  13.                 var xpos:Number=0;
  14.                 for (var j:uint = 0; j < iterations; j++) {
  15.                     xpos+=Math.random()*stage.stageWidth;
  16.                 }
  17.                 dot.x=xpos/iterations;
  18.                 var ypos:Number=0;
  19.                 for (j = 0; j < iterations; j++) {
  20.                     ypos+=Math.random()*stage.stageHeight;
  21.                 }
  22.                 dot.y=ypos/iterations;
  23.                 addChild(dot);
  24.             }
  25.         }
  26.     }
  27. }

相关文章:

  • 2021-09-18
  • 2021-12-27
  • 2021-08-06
  • 2022-12-23
  • 2022-12-23
  • 2021-04-15
  • 2021-12-08
  • 2021-07-29
猜你喜欢
  • 2021-12-16
  • 2021-07-19
  • 2021-11-18
  • 2021-12-05
  • 2022-01-22
  • 2021-11-13
相关资源
相似解决方案