package {
import __AS3__.vec.Vector;
import com.almerblanklabs.view.ApplicationView;
import com.lifeztream.debug.FPS;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.external.ExternalInterface;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.media.SoundTransform;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.utils.setTimeout;
import hype.framework.behavior.SimpleBehavior;
import hype.framework.core.TimeType;
import hype.framework.rhythm.SimpleRhythm;
import hype.framework.sound.SoundAnalyzer;
import org.papervision3d.objects.primitives.Sphere;
[SWF(width='580', height='580', backgroundColor='#000000')]
/**
*
* @author Nolan Butcher
*
* DISCLAIMER : This code sample is by no means an optimized example. It is a PROTOTYPE.
* Please keep this in mind when looking through this code.
*
*/
public class Paper_Hype_Lab extends Sprite
{
private static const ARTIST : String = "Trioptic of the Sound Scientists";
private static const AUDIO_PATH : String = 'http://flexgraphix.com/blog/wp-content/uploads/2009/11/';
private static const AUDIO_FILES : Array = [
{file:'evil_violin.mp3', title:'Evil Violin(Rich \'n Stingy)'},
{file:'am_i_going_to_die.mp3', title:'Am I Going to Die'},
{file:'going_pro.mp3', title:'Going Pro'},
{file:'life_is_easily_taken.mp3', title:'Life is Easily Taken'},
{file:'bubachu.mp3', title:'Bubachu'},
{file:'midi_in-out.mp3', title:'Midi In/Out'},
{file:'may_6.mp3', title:'May 6'},
{file:'slow_descent.mp3', title:'Slow Descent'},
{file:'nocens_sonitus.mp3', title:'Nocens Sonitus'},
{file:'remember.mp3', title:'Remember'},
{file:'soulful_east_coast.mp3', title:'Soulful East Coast'},
{file:'sunrise_on_the_highway.mp3', title:'Sunrise on the Highway'},
{file:'the_sad_truth_of_it_all.mp3', title:'The Sad Truth of it All'},
{file:'blueberry_haze.mp3', title:'Blueberry Haze'}
];
private static const VOLUME : Number = 1;
private var _view : ApplicationView;
private var _sphere : Sphere;
private var _music : Sound;
private var _sndChannel : SoundChannel;
private var _soundAnalyzer : SoundAnalyzer;
private var _freq : Vector.<Number> = new Vector.<Number>;
private var _rythm : SimpleRhythm;
private var _fps : FPS;
private var _audioIndex : int = 1;
private var _button : Sprite;
private var _hitArea : Sprite;
private var _textField : TextField;
private var _songText : TextField;
private var _rotationX : Number = 0.3;
private var _rotationY : Number = 0.3;
private var _cameraPitch : Number = 90;
private var _cameraYaw : Number = 270;
private var _xDist : Number;
private var _yDist : Number;
private var _mouseDown : Boolean = false;
public function Paper_Hype_Lab()
{
Security.allowDomain('*');
stage.frameRate = 60;
_sphere = new Sphere(null, 300, 24, 14);
_view = new ApplicationView();
_view.object3D = _sphere;
_view.startRendering();
addChild(_view);
_initRythm();
_initTextField();
_loadSound();
_initUI();
// Get the FPS widget @ www.lifeztream.com
_fps = new FPS();
addChild(_fps);
}
private function _handleMouseEvents(evt:MouseEvent):void
{
switch(String(evt.type))
{
case MouseEvent.MOUSE_DOWN:
_mouseDown = true;
break;
case MouseEvent.MOUSE_UP:
_mouseDown = false;
break;
}
}
private function _loadSound():void
{
var context : SoundLoaderContext = new SoundLoaderContext(1000, true);
var req : URLRequest = new URLRequest();
req.url = AUDIO_PATH + AUDIO_FILES[_audioIndex].file;
if (_rythm && _rythm.isRunning) _pauseRythm();
if (_sndChannel)
{
_sndChannel.stop();
try {
_music.close();
} catch(e:Error) {
trace ('cannot close sound stream');
}
}
_music = new Sound(req, context);
_music.addEventListener(IOErrorEvent.IO_ERROR, _handleIOErrorEvents, false, 0, true);
_sndChannel = _music.play(0, 1, new SoundTransform(VOLUME));
_sndChannel.addEventListener(Event.SOUND_COMPLETE, _onSoundDone, false, 0, true);
_soundAnalyzer = new SoundAnalyzer();
_soundAnalyzer.start();
_updateSongText();
if (_rythm) _initRythm();
}
private function _onSoundDone(evt:Event):void
{
_button.mouseEnabled = false;
setTimeout(_nextSong, 1000);
}
private function _nextSong():void
{
_button.mouseEnabled = true;
_button.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
private function _handleIOErrorEvents(evt:IOErrorEvent):void
{
if (ExternalInterface.available)
{
ExternalInterface.call("window.alert('" + AUDIO_FILES[_audioIndex].file + " cannot be loaded')");
}
}
private function _initUI():void
{
_hitArea = new Sprite();
_hitArea.graphics.beginFill(0x000,0);
_hitArea.graphics.drawRect(0,0,580,580);
_hitArea.graphics.endFill();
_hitArea.addEventListener(MouseEvent.MOUSE_DOWN, _handleMouseEvents, false, 0, true);
_hitArea.addEventListener(MouseEvent.MOUSE_UP, _handleMouseEvents, false, 0, true);
addChild(_hitArea);
_button = new Sprite();
_button.graphics.beginFill(0x666666);
_button.graphics.drawRect(0,0,100,30);
_button.graphics.endFill();
_button.x = 476;
_button.y = 4;
_button.buttonMode = true;
_button.mouseChildren = false;
_button.useHandCursor = true;
_button.addEventListener(MouseEvent.CLICK, _handleButtonEvents, false, 0, true);
var buttonFormat : TextFormat = new TextFormat(null, 14, 0xFFFFFF, true);
var buttonText : TextField = new TextField();
buttonText.defaultTextFormat = buttonFormat;
buttonText.text = "NEXT RIFF";
buttonText.height = 18;
buttonText.y = (_button.height - buttonText.textHeight) * .5;
buttonText.x = (_button.width - buttonText.textWidth) * .5;
addChild(_button);
_button.addChild(buttonText);
}
private function _pauseRythm():void
{
_rythm.stop();
}
private function _resumeRythm():void
{
_rythm.start();
}
private function _initRythm():void
{
_rythm = new SimpleRhythm(_trackRythm);
_rythm.start(TimeType.ENTER_FRAME);
}
private function _initTextField():void
{
var textFormat : TextFormat = new TextFormat();
textFormat.color = 0x666666;
textFormat.align = TextFormatAlign.CENTER;
textFormat.size = 14;
_songText = new TextField();
_songText.defaultTextFormat = textFormat;
_songText.width = 1;
_songText.text = "-- :: --";
_songText.autoSize = TextFieldAutoSize.CENTER;
_songText.y = (stage.stageHeight - _songText.textHeight) - 4;
_songText.x = (stage.stageWidth - _songText.width) * 0.5;
addChild(_songText);
var artistText : TextField = new TextField();
artistText.defaultTextFormat = textFormat;
artistText.width = 1;
artistText.text = "-- Artist :: " + ARTIST + " --";
artistText.x = (stage.stageWidth - artistText.width) * 0.5;
artistText.y = (_songText.y - artistText.textHeight) - 4;
artistText.autoSize = TextFieldAutoSize.CENTER;
addChild(artistText);
_textField = new TextField();
_textField.width = 1;
_textField.defaultTextFormat = textFormat;
_textField.text = "-- Click and drag to rotate sphere --";
_textField.x = (stage.stageWidth - _textField.width) * 0.5;
_textField.y = artistText.y - _textField.textHeight - 5;
_textField.autoSize = TextFieldAutoSize.CENTER;
addChild(_textField);
}
private function _updateSongText():void
{
_songText.text = "-- Song :: " + AUDIO_FILES[_audioIndex].title + " --";
_songText.x = (stage.stageWidth - _songText.width) * 0.5;
}
private function _handleButtonEvents(evt:MouseEvent):void
{
_sndChannel.removeEventListener(Event.SOUND_COMPLETE, _onSoundDone);
if (_audioIndex < AUDIO_FILES.length-2)
{
_audioIndex++;
} else {
_audioIndex = 0;
}
_loadSound();
}
private function _trackRythm(rythm : SimpleRhythm):void
{
for (var i:int = 1;i < _sphere.geometry.vertices.length + 1;++i)
{
_freq[i-1] = _soundAnalyzer.getFrequencyIndex(i, 400, 100);
}
_view.moveParticles(_freq);
// Rotates camera around sphere depending on mouse position
if (_mouseDown)
{
_xDist = mouseX - stage.stageWidth * 0.5;
_yDist = mouseY - stage.stageHeight * 0.5;
_cameraPitch = _yDist * _rotationX + 90;
_cameraYaw = _xDist * _rotationY + 270;
_view.camera.orbit(_cameraPitch, _cameraYaw);
}
}
}
}