Beat wanderer

by aobyrne forked from Beat Clock (diff: 423)
mashed:
forked (that is http://wonderfl.net/c/sRED )
and
http://wonderfl.net/c/ubO1
♥0 | Line 313 | Modified 2012-05-03 23:43:34 | MIT License
play

ActionScript3 source code

/**
 * Copyright aobyrne ( http://wonderfl.net/user/aobyrne )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3VbX
 */

// beat clock, clock listens to sound :-)
// forked from Event's Human Clock
package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.events.*;
    import flash.filters.BlurFilter;
    import flash.geom.Rectangle;
    import flash.geom.Vector3D;
    import flash.geom.Point;
    import flash.utils.Timer;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;
    public class HumanClockBeatTracker extends Sprite {
        private var _sec:int;
        private var _pathCommands:Vector.<int> = Vector.<int>([1,2,2,2,2]);
        private var beats :Number;
        private var sound:Sound;
        private var oldBeats:Number;
        private var wanderingTarget:WanderingTarget;
        private var wanderer:Sprite;
        private var bitmapData:BitmapData;
        private var blurFilter:BlurFilter;
        private var point:Point;
        private var rr:Rectangle;
        private var container:Sprite;
        private var count:uint;
              
        public function HumanClockBeatTracker() {
            beats =0
            oldBeats = 0
            initSound();
            //initView();
            //var timer:Timer = new Timer(100);    
            //timer.addEventListener(TimerEvent.TIMER, onTimer);
            //timer.start();
            
        }
        
        private function initView():void {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            wanderingTarget =          new WanderingTarget;
            var canvasHeight :Number = 465;
            var canvasWidth:Number = 465;
            wanderingTarget.position = new Vector3D(canvasHeight * 0.5,canvasHeight * 0.5);
            wanderingTarget.boundsCentre = new Vector3D(canvasHeight*0.5, canvasWidth*0.5, 0);
            wanderingTarget.boundsRadius = canvasHeight * 0.5;
            container = addChild(new Sprite) as Sprite;
            wanderer = new Sprite;
            wanderer.x = wanderingTarget.position.x;
            wanderer.y = wanderingTarget.position.y;
            wanderer.graphics.beginFill(0xff);
            wanderer.graphics.drawCircle(0, 0, 7);
            container.addChild(wanderer);
            blurFilter = new BlurFilter(2,2,3);
            bitmapData = new BitmapData(canvasWidth, canvasHeight,true,0x00ffffff);
            rr = bitmapData.rect;
            point = new Point;
            addChild(new Bitmap(bitmapData));
            
            
            //onTimer();
            start();
        }
        
        private function initSound() :void {
            var soundPath:String = "http://www.takasumi-nagai.com/soundfiles/sound001.mp3";
            sound = new Sound();
            sound.addEventListener(Event.COMPLETE, function(e :Event) :void {
                initView();
            }, false, 0, true);
            sound.load(new URLRequest(soundPath), new SoundLoaderContext(10, true));
        }
        

        private function start():void {
            var channel:SoundChannel = sound.play(0, 1000);
            addEventListener(Event.ENTER_FRAME, update, false, 0, true);
        }

        private function update(evt:Event):void {
            var tt:Number;
            var bytes:ByteArray = new ByteArray();
            SoundMixer.computeSpectrum(bytes);

            bytes.position = 0;
            var rf:Number;
            var count:int = 0;
            for (var q:int = 0; bytes.bytesAvailable >= 4; q++) {
                rf = bytes.readFloat();
                tt = Math.abs(rf);
                if (tt >= 0.3) {
                    count ++;
                }
            }
            oldBeats = beats;
            beats += count * 1;
            onTimer();
            bitmapData.draw(container);
            if(count++>5){
            bitmapData.applyFilter(bitmapData,rr,point,blurFilter);
            count=0;
            }
        }
        
        private function onTimer():void 
        {
            var o:Number = beats - oldBeats;
            if (o)
            {
            trace( "(beats - oldBeats) : " + (beats - oldBeats) );
            wanderingTarget.wander();
            wanderingTarget.update();
            
            wanderer.x = wanderingTarget.x;
            wanderer.y = wanderingTarget.y;
            }
        }
        
    }
}
import flash.display.DisplayObject;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Vector3D;

import org.papervision3d.cameras.Camera3D;
import org.papervision3d.objects.DisplayObject3D;

internal class WanderingTarget extends Point
{
    /** 
     * SEE http://blog.soulwire.co.uk/laboratory/flash/as3-flocking-steering-behaviors
     * SOUL WIRE
     */
    private var _matrix : Matrix3D;
    private var _maxForce : Number;
    private var _maxSpeed : Number;
    private var _distance : Number;
    private var _drawScale : Number;
    private var _maxForceSQ : Number;
    private var _maxSpeedSQ : Number;
    private var _velocity : Vector3D;
    private var _position : Vector3D;
    private var _oldPosition : Vector3D;
    private var _acceleration : Vector3D;
    private var _steeringForce : Vector3D;
    private var _screenCoords : Point;
    private var _renderData : DisplayObject;
    private var _edgeBehavior : String;
    private var _boundsRadius : Number;
    private var _boundsCentre : Vector3D = new Vector3D();
    private var _radius : Number = 10.0;
    private var _wanderTheta : Number = 0.0;
    private var _wanderRadius : Number = 16.0;
    private var _wanderDistance : Number = 60.0;
    private var _wanderStep : Number = 0.25;
    private var _lookAtTarget : Boolean = true;
    
    protected var _config : Object = {
        minForce:3.0,
        maxForce:6.0,
        minSpeed:6.0,
        maxSpeed:12.0,
        minWanderDistance:10.0,
        maxWanderDistance:100.0,
        minWanderRadius:5.0,
        maxWanderRadius:20.0,
        minWanderStep:0.1,
        maxWanderStep:0.9,
        boundsRadius:250,
        numBoids:120
    };
    
    public function WanderingTarget()
    {
        maxForce = 4;//random(_config.minForce, _config.maxForce);
        maxSpeed = 10//;random(_config.minSpeed, _config.maxSpeed);
        _wanderDistance = 25;//random(_config.minWanderDistance, _config.maxWanderDistance);
        _wanderRadius = 15;//random(_config.minWanderRadius, _config.maxWanderRadius);
        _wanderStep = 5;//random(_config.minWanderStep, _config.maxWanderStep);
        
        super();
        reset();
        //super(fov, near, far, useCulling, useProjection);
    }
    
    /**
     * Generates a random wandering force for the Boid. 
     * The results of this method can be controlled by the 
     * _wanderDistance, _wanderStep and _wanderRadius parameters
     * 
     * @param    multiplier
     * 
     * By multiplying the force generated by this behavior, 
     * more or less weight can be given to this behavior in
     * comparison to other behaviors being calculated by the 
     * Boid. To increase the weighting of this behavior, use 
     * a number above 1.0, or to decrease it use a number 
     * below 1.0
     */
    
    public function wander( multiplier : Number = 1.0 ) : void
    {
        _wanderTheta += Math.random() * _wanderStep;
        
        if ( Math.random() < 0.5 )
        {
            _wanderTheta = -_wanderTheta;
        }
        
        var pos : Vector3D = _velocity.clone();
        
        //trace(pos)
        
        pos.normalize();
        pos.scaleBy(_wanderDistance);
        pos.incrementBy(_position);
        
        var offset : Vector3D = new Vector3D();
        
        offset.x = _wanderRadius * Math.cos(_wanderTheta);
        offset.y = _wanderRadius * Math.sin(_wanderTheta);
        //offset.z = _wanderRadius * Math.tan(_wanderTheta);
        //    trace(offset)
        //trace(_wanderRadius, _wanderTheta, pos, offset)
        _steeringForce = steer(pos.add(offset));
        
        if ( multiplier != 1.0 )
        {
            _steeringForce.scaleBy(multiplier);
        }
        //    trace(_steeringForce)
        
        _acceleration.incrementBy(_steeringForce);
    }
    
    private function steer( target : Vector3D, ease : Boolean = false, easeDistance : Number = 100 ) : Vector3D
    {
        //trace(_steeringForce,target.clone());
        
        _steeringForce = target.clone();
        _steeringForce.decrementBy(_position);
        //trace(_steeringForce,target.clone());
        _distance = _steeringForce.normalize();
        //trace('ab', _distance)
        
        if ( _distance > 0.00001 )
        {
            if ( _distance < easeDistance && ease )
            {
                _steeringForce.scaleBy(_maxSpeed * ( _distance / easeDistance ));
            }
            else
            {
                _steeringForce.scaleBy(_maxSpeed);
            }
            
            _steeringForce.decrementBy(_velocity);
            
            if ( _steeringForce.lengthSquared > _maxForceSQ )
            {
                _steeringForce.normalize();
                _steeringForce.scaleBy(_maxForce);
            }
        }
        //trace(_steeringForce)
        
        return _steeringForce;
    }
    
    public function update() : void
    {
        _oldPosition.x = _position.x;
        _oldPosition.y = _position.y;
        _oldPosition.z = _position.z;
        
        _velocity.incrementBy(_acceleration);
        
        if ( _velocity.lengthSquared > _maxSpeedSQ )
        {
            _velocity.normalize();
            _velocity.scaleBy(_maxSpeed);
        }
        
        _position.incrementBy(_velocity);
        
        x = _position.x;
        y = _position.y;
        //z = _position.z;
        
        
        _acceleration.x = 0;
        _acceleration.y = 0;
        _acceleration.z = 0;
        
        if ( isNaN(_boundsRadius) )
        {
            trace( "isNaN(_boundsRadius) : " + isNaN(_boundsRadius) );
            return;
        }
        
        if( !_position.equals(_oldPosition) )
        {
            var distance : Number = Vector3D.distance(_position, _boundsCentre);
            
            if( distance > _boundsRadius + _radius )
            {
                    
                /**
                 * Move the boid to the edge of the boundary 
                 * then invert it's velocity and step it 
                 * forward back into the sphere 
                 */
                
                _position.decrementBy(_boundsCentre);
                _position.normalize();
                _position.scaleBy(_boundsRadius + _radius);
                
                _velocity.scaleBy(-1);
                _position.incrementBy(_velocity);
                _position.incrementBy(_boundsCentre);
                    
            }
        }
    }
    
    /**
     * Resets the Boid's position, velocity, acceleration and 
     * current steering force to zero
     */
    
    public function reset() : void
    {
        _velocity = new Vector3D();
        _position = new Vector3D();
        _oldPosition = new Vector3D();
        _acceleration = new Vector3D();
        _steeringForce = new Vector3D();
        _screenCoords = new Point();
    }
    
    /**
     * The maximum force available to the Boid when
     * calculating the steering force produced by 
     * the Boids steering bahaviors
     */
    
    public function get maxForce() : Number
    {
        return _maxForce;
    }
    
    public function set maxForce( value : Number ) : void
    {
        if ( value < 0 )
        {
            value = 0;
        }
        
        _maxForce = value;
        _maxForceSQ = value * value;
    }
    
    /**
     * The maximum speed the Boid can reach
     */
    
    public function get maxSpeed() : Number
    {
        return _maxSpeed;
    }
    
    public function set maxSpeed( value : Number ) : void
    {
        if ( value < 0 )
        {
            value = 0;
        }
        
        _maxSpeed = value;
        _maxSpeedSQ = value * value;
    }
    
    protected function random( min : Number, max : Number = NaN ) : Number
    {
        if ( isNaN(max) )
        {
            max = min;
            min = 0;
        }
        
        return Math.random() * ( max - min ) + min;
    }
    
    /**
     * The centrepoint of the Boids bounding sphere.
     * If the Boid travels futher than boundsRadius 
     * from this point the specified edge behavior 
     * will take affect.
     */

    public function get boundsCentre() : Vector3D
    {
        return _boundsCentre;
    }

    public function set boundsCentre( value : Vector3D ) : void
    {
        _boundsCentre = value;
    }

    /**
     * The maximum distance which this Boid can 
     * travel from it's boundsCentre before the 
     * specified edge behavior takes affect
     */

    public function get boundsRadius() : Number
    {
        return _boundsRadius;
    }

    public function set boundsRadius( value : Number ) : void
    {
        _boundsRadius = value;
    }    
    
    public function get position():Vector3D 
    {
        return _position;
    }
    
    public function set position(value:Vector3D):void 
    {
        _position = value;
    }
}