Random Motion in Flash
July 9th, 2009
No comments
Here are two different methods of moving objects in random patterns, making them seem to wander around.
The one on the left is based on a brownian movement tutorial that uses variable velocities. The one on the right is based on a post about random circular movement. The latter is much more interesting, as the dot will rotate around an imaginary circle, and then after a random interval, the circle radius will change, and the dot will start on a new path around the new adjacent imaginary circle.
I think both methods are great, it just depends on what you want to use.
Here’s the code for the left method (brownian):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | // settings var numDots:uint = 20; var defaultDotSize:uint = 5; var maxSpeed:Number = 0.5; var dampen:Number = 0.95; // make dots function makeDots():void { // create desired number of dots for (var dotNum:uint=0; dotNum<numDots; dotNum++){ var c1:Number = randomColor(); var c2:Number = randomColor(); // create dot var thisDot:MovieClip = new MovieClip(); thisDot.graphics.beginFill(c1, .9); thisDot.graphics.lineStyle(defaultDotSize/3, c2, .9); thisDot.graphics.drawCircle(defaultDotSize, defaultDotSize, defaultDotSize); thisDot.graphics.endFill(); thisDot.alpha = 0.5; addChild(thisDot); // coordinates thisDot.x = Math.random() * stage.stageWidth; thisDot.y = Math.random() * stage.stageHeight; // initial velocity thisDot.vx = 0; thisDot.vy = 0; // dot animation thisDot.addEventListener(Event.ENTER_FRAME, animateDot); } } makeDots(); // animation function function animateDot(e:Event):void{ var thisDot:Object = e.target; // apply randomness to velocity thisDot.vx += dampen*(Math.random() * maxSpeed - maxSpeed/2); thisDot.vy += dampen*(Math.random() * maxSpeed - maxSpeed/2); // keep dot inside stage if(thisDot.x+thisDot.width >= stage.stageWidth) thisDot.vx = -maxSpeed; else if(thisDot.x <= 0) thisDot.vx = maxSpeed; else if(thisDot.y+thisDot.height >= stage.stageHeight) thisDot.vy = -maxSpeed; else if(thisDot.y <= 0) thisDot.vy = maxSpeed; // apply velocity thisDot.x += thisDot.vx; thisDot.y += thisDot.vy; } function randomColor():Number{ return Math.floor(Math.random() * 16777215); } |
Here’s the code for the right method (circular):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | // settings var numDots:int = 20; var defaultDotSize:uint = 5; var step:int = 1; var maxRadius:int = 50; var minRadius:int = 5; var minInterval:int = 400; var maxInterval:int = 1200; function makeDots():void { // create desired number of dots for (var dotNum:uint=0; dotNum<numDots; dotNum++){ var c1:Number = randomColor(); var c2:Number = randomColor(); // create dot var thisDot:MovieClip = new MovieClip(); thisDot.graphics.beginFill(c1, .9); thisDot.graphics.lineStyle(defaultDotSize/3, c2, .9); thisDot.graphics.drawCircle(defaultDotSize, defaultDotSize, defaultDotSize); thisDot.graphics.endFill(); thisDot.alpha = 0.5; addChild(thisDot); // dot properties thisDot.radius = Math.random() * (maxRadius - minRadius) + minRadius; thisDot.centerX = Math.random() * (stage.stageWidth - thisDot.radius*2 - thisDot.width*2) + thisDot.radius + thisDot.width; thisDot.centerY = Math.random() * (stage.stageHeight - thisDot.radius*2 - thisDot.height*2) + thisDot.radius + thisDot.height; thisDot.rotationIncrement = (dotNum%2==0?1:-1) * 360 / (2*Math.PI*thisDot.radius/step); thisDot.currentRotation = thisDot.rotationIncrement; var radians:Number = Math.PI/180*thisDot.currentRotation; var vy = Math.sin(radians); var vx = Math.cos(radians); thisDot.y = thisDot.centerY + vy*thisDot.radius; thisDot.x = thisDot.centerX + vx*thisDot.radius; thisDot.intrvl = setInterval(swapInterval, Math.random()*(maxInterval-minInterval)+minInterval, thisDot); // dot animation thisDot.addEventListener(Event.ENTER_FRAME, animateDot); } } makeDots(); // animation function function animateDot(e:Event):void{ var thisDot:Object = e.target; thisDot.currentRotation += thisDot.rotationIncrement; var radians:Number = Math.PI/180*thisDot.currentRotation; var vy = Math.sin(radians); var vx = Math.cos(radians); thisDot.y = thisDot.centerY + vy*thisDot.radius; thisDot.x = thisDot.centerX + vx*thisDot.radius; // keep dot inside stage if(thisDot.x + thisDot.width > stage.stageWidth || thisDot.x < 0 || thisDot.y + thisDot.height > stage.stageHeight || thisDot.y < 0) thisDot.rotationIncrement *= -1; } // creates new point to rotate around function swap(thisDot:Object):void{ // pick a new random length for the radius var newRadius:Number = Math.random()*(maxRadius-minRadius)+minRadius; // determine new center based on old center, dot's current position and new radius var xd:Number = thisDot.centerX-thisDot.x; var yd:Number = thisDot.centerY-thisDot.y; var ratio:Number = (thisDot.radius+newRadius)/thisDot.radius; thisDot.centerX = thisDot.centerX-xd*ratio; thisDot.centerY = thisDot.centerY-yd*ratio; thisDot.radius = newRadius; // rotate the opposite direction around new point var dir:int = thisDot.rotationIncrement>0 ? 1 : -1; thisDot.rotationIncrement = dir* -1 * 360 / (2*Math.PI*thisDot.radius/step); thisDot.currentRotation -= 180; } // random interval to change the point of rotation function swapInterval(thisDot:Object){ clearInterval(thisDot.intrvl); thisDot.intrvl = setInterval(swapInterval, Math.random()*(maxInterval-minInterval)+minInterval, thisDot); swap(thisDot); } function randomColor():Number{ return Math.floor(Math.random() * 16777215); } |