Pixel Swarm
@author Michael Svendsen
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.Point;
/**
* @author Michael Svendsen
*/
public class PixelSwarm_001 extends Sprite {
private var _w:Number;
private var _h:Number;
private var _bmd:BitmapData;
private var _swarmData:Vector.<Object>;
private var _leader:Object;
private var _swarmAmount:Number;
private var _leaderTime:Number;
private var _leaderSpeed:Number;
private var _leaderRotSpeed:Number;
private var _leaderRunTime:Number;
private var _swarmTwitch:Number;
private var _swarmSpeed:Number;
private var _swarmRotSpeed:Number;
public function PixelSwarm_001():void{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void{
_w = stage.stageWidth;
_h = stage.stageHeight;
_bmd = new BitmapData(_w, _h, false, 0xFFFFFF);
addChild(new Bitmap(_bmd));
initSwarm();
}
private function initSwarm():void{
_leaderTime = 0;
_swarmAmount = 25;
_leaderRotSpeed = 20;
_leaderSpeed = 10;
_leaderRunTime = 30;
//follower values
_swarmTwitch = 40;
_swarmRotSpeed = 10;
_swarmSpeed = 10;
_createSwarm();
}
private function _createSwarm():void{
_leader = [];
_leader.x = _w * 0.5;//Math.floor( Math.random() * _w);
_leader.y = _h * 0.5;//Math.floor( Math.random() * _h);
_leader.rotation = 0;
_leader.rotSpeed = 20;
_leader.speed = 30;
_leader.runTime = 30;
_leader.goalX = 0;
_leader.goalY = 0;
_leader.goalAngle = 0;
_swarmData = new Vector.<Object>();
var i:int = 0;
var max : int = _swarmAmount;
for(i; i<max; i++){
var f:Object = new Object();
f.x = _w * 0.5;//Math.floor( Math.random() * _w);
f.y = _h * 0.5;//Math.floor( Math.random() * _h);
f.rotation = 0;
f.rotSpeed = _swarmRotSpeed;
f.twitch = _swarmTwitch;
f.speed = _swarmSpeed;
f.goalX = 0;
f.goalY = 0;
f.goalAngle = 0;
_swarmData.push(f);
}
stage.addEventListener(Event.ENTER_FRAME, onStageEnterFrame);
}
private function onStageEnterFrame(e:Event):void{
moveSwarm();
drawSwarm();
}
private function moveSwarm():void{
if(_leaderTime == 0){
_leader.goalX = Math.floor( Math.random() * _w);
_leader.goalY = Math.floor( Math.random() * _h);
_leaderTime = _leader.runTime;
}
_leader.goalAngle = Math.atan2( _leader.goalY - _leader.y, _leader.goalX - _leader.x );
_leader.goalAngle = _leader.goalAngle * 180 / Math.PI;
_leader.goalAngle = angleFix(_leader.goalAngle - _leader.rotation);
if(_leader.goalAngle < 180){
_leader.rotation += _leader.rotSpeed;
} else {
_leader.rotation -= _leader.rotSpeed;
}
_leader.x += calcCos(_leader.rotation) * _leader.rotSpeed;
_leader.y += calcSin(_leader.rotation) * _leader.rotSpeed;
_leaderTime --;
var i:int = 0;
var max : int = _swarmAmount;
for(i=0; i<max; ++i){
var follower:Object = _swarmData[i];
follower.goalX = _leader.x;
follower.goalY = _leader.y;
follower.goalAngle = Math.atan2(follower.goalY-follower.y, follower.goalX-follower.x);
follower.goalAngle = follower.goalAngle*180/Math.PI;
follower.goalAngle = angleFix(follower.goalAngle-follower.rotation);
if (follower.goalAngle<180) {
follower.rotation += follower.rotSpeed;
} else {
follower.rotation -= follower.rotSpeed;
}
follower.rotation += Math.floor(Math.random() * follower.twitch) - Math.floor(follower.twitch*0.5);
follower.x += calcCos(follower.rotation)*follower.speed;
follower.y += calcSin(follower.rotation)*follower.speed;
}
}
private function drawSwarm():void{
var s:Shape = new Shape();
s.graphics.beginFill(0xFFFFFF, 0.2);
s.graphics.drawRect(0, 0, _w, _h);
s.graphics.endFill();
_bmd.draw(s);
_bmd.applyFilter(_bmd, stage.getRect(this), new Point(), new BlurFilter(5,5,1));
_bmd.setPixel(_leader.x, _leader.y, 0xFF0000);
var i:int = 0;
var max : int = _swarmAmount;
while(i<max){
var f:Object = _swarmData[i];
_bmd.setPixel(f.x, f.y, 0x000000);
i++;
}
}
private function calcCos(pAngle:Number):Number{
return Math.cos( pAngle * Math.PI/180);
}
private function calcSin(pAngle:Number):Number{
return Math.sin(pAngle * Math.PI/180);
}
private function angleFix(pAngle:Number):Number{
if(pAngle > 360){
pAngle = pAngle%360;
}
while(pAngle < 0) {
pAngle += 360;
}
return pAngle;
}
}
}