Happy Birthday ;)
Spark 勉強会の Geoff Stearns 氏のハッピーバースデー企画
* お誕生日おめでとーございまーす :-)
*
* @see http://wiki.libspark.org/wiki/SparkStudy/09
/**
* Copyright soundkitchen ( http://wonderfl.net/user/soundkitchen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/289Z
*/
/**
* Spark 勉強会の Geoff Stearns 氏のハッピーバースデー企画
* お誕生日おめでとーございまーす :-)
*
* @see http://wiki.libspark.org/wiki/SparkStudy/09
*/
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import com.flashdynamix.utils.SWFProfiler;
import org.libspark.thread.Thread;
import org.libspark.thread.EnterFrameThreadExecutor;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.LazyRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
[SWF(width=465, height=465, frameRate=60, backgroundColor=0x000000)]
/**
* document class.
*/
public class CodeBreak extends Sprite
{
/**
* constructor.
*/
public function CodeBreak()
{
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
/**
* initialize the object.
*/
private function initialize(evt:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
if (!Thread.isReady)
{
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
stage.scaleMode = StageScaleMode.NO_SCALE;
SWFProfiler.init(this);
Thread.initialize(new EnterFrameThreadExecutor());
}
var ctx:Context,
camera:Camera3D,
scene:Scene3D,
viewport:Viewport3D,
container:DisplayObject3D,
renderer:LazyRenderEngine;
// camera.
camera = new Camera3D();
camera.z = 1000;
//camera.focus = 20;
//camera.zoom = 40;
camera.lookAt(DisplayObject3D.ZERO);
// scene.
scene = new Scene3D();
// container.
container = new DisplayObject3D();
scene.addChild(container);
// viewport.
viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, true);
addChild(viewport);
// render engine.
renderer = new LazyRenderEngine(scene, camera, viewport);
// context.
ctx = new Context();
ctx.layer = this;
ctx.stage = stage;
ctx.camera = camera;
ctx.scene = scene;
ctx.container = container;
ctx.viewport = viewport;
ctx.renderer = renderer;
new MainThread(ctx).start();
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Stage;
import flash.display.StageDisplayState;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import frocessing.color.ColorHSV;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.targets.single.ISingleTweenTarget;
import org.libspark.betweenas3.easing.*;
import org.libspark.betweenas3.events.BetweenEvent;
import org.libspark.thread.Monitor;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.net.URLLoaderThread;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.materials.special.Letter3DMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.LazyRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.typography.Font3D;
import org.papervision3d.typography.Text3D;
import org.papervision3d.typography.fonts.HelveticaBold;
import org.papervision3d.view.Viewport3D;
internal const SOURCE_URL:String = "http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject_src.js";
internal const TARGET_WORDS:String = "Happy Birthday ;)";
/**
* context object.
*/
internal class Context
{
/**
* reference of document class object.
*/
public var layer:DisplayObjectContainer;
/**
* reference of stage object.
*/
public var stage:Stage;
/**
* reference of pv3d camera object.
*/
public var camera:Camera3D;
/**
* reference of pv3d container object.
*/
public var container:DisplayObject3D;
/**
* reference of pv3d scene object.
*/
public var scene:Scene3D;
/**
* reference of pv3d renderer object.
*/
public var renderer:LazyRenderEngine;
/**
* reference of pv3d viewport object.
*/
public var viewport:Viewport3D;
}
/**
* main task of this applicaiton.
*/
internal class MainThread extends Thread
{
private var context:Context;
private var loader:URLLoaderThread;
/**
* constructor.
*/
public function MainThread(context:Context)
{
this.context = context;
}
/**
* first executable.
*/
override protected function run():void
{
var t:Thread;
t = new WaitAnimationThread(context);
t.start();
t.join();
new HandleScreenThread(context).start();
next(startAnimation);
}
private function startAnimation():void
{
var req:URLRequest;
req = new URLRequest(SOURCE_URL);
loader = new URLLoaderThread(req);
loader.start();
loader.join();
next(loadComplete);
error(Error, loadFailure);
}
private function loadComplete():void
{
var data:String;
data = String(loader.loader.data);
new PV3DRenderThread(context).start();
new MainAnimationThread(context, data).start();
}
private function loadFailure(e:Error, t:Thread):void
{
trace(e.getStackTrace());
}
/**
* finalize the object.
*/
override protected function finalize():void
{
context = null;
}
}
/**
* wait user's action.
*/
internal class WaitAnimationThread extends Thread
{
private var context:Context;
private var message:Bitmap;
/**
* constructor.
*/
public function WaitAnimationThread(context:Context)
{
this.context = context;
}
/**
* first executable.
*/
override protected function run():void
{
var txt:TextField,
fmt:TextFormat,
bmd:BitmapData;
fmt = new TextFormat();
fmt.font = 'Lucida Grande';
fmt.size = 64;
fmt.color = 0x000000;
txt = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.defaultTextFormat = fmt;
txt.text = "click to start";
bmd = new BitmapData(txt.width, txt.height, true, 0);
bmd.draw(txt);
message = new Bitmap(bmd);
message.x = (context.stage.stageWidth - message.width) >> 1;
message.y = (context.stage.stageHeight - message.height) >> 1;
message.blendMode = BlendMode.INVERT;
context.layer.addChild(message);
event(context.stage, MouseEvent.CLICK, clicked);
event(context.stage, Event.RESIZE, resized);
}
/**
* will execute when clicked stage.
*/
private function clicked(evt:MouseEvent):void
{
message.x = (context.stage.stageWidth - message.width) >> 1;
message.y = (context.stage.stageHeight - message.height) >> 1;
new HideMessageThread(message).start();
}
/**
* will execute when resized stage size.
*/
private function resized(evt:Event):void
{
message.x = (context.stage.stageWidth - message.width) >> 1;
message.y = (context.stage.stageHeight - message.height) >> 1;
event(context.stage, MouseEvent.CLICK, clicked);
event(context.stage, Event.RESIZE, resized);
}
/**
* finalize the object.
*/
override protected function finalize():void
{
message = null;
context = null;
}
}
/**
* hide splash message.
*/
internal class HideMessageThread extends Thread
{
private var message:DisplayObject;
private var monitor:Monitor;
/**
* constructor.
*/
public function HideMessageThread(message:DisplayObject)
{
this.message = message;
this.monitor = new Monitor();
}
/**
* first executable.
*/
override protected function run():void
{
var b:ITween,
from:Object,
to:Object;
to = {
'alpha': 0,
//'y': message.stage.stageHeight,
'_blurFilter': {
'blurX': 128,
'blurY': 128
}
};
b = BetweenAS3.tween(message, to, from, 2, Quadratic.easeIn);
b.onComplete = monitor.notifyAll;
b.play();
monitor.wait();
}
/**
* finalize the object.
*/
override protected function finalize():void
{
message.parent.removeChild(message);
message = null;
monitor = null;
}
}
/**
* handle full screen.
*/
internal class HandleScreenThread extends Thread
{
private var context:Context;
/**
* constructor.
*/
public function HandleScreenThread(context:Context)
{
this.context = context;
}
/**
* first executable.
*/
override protected function run():void
{
event(context.stage, MouseEvent.CLICK, toggleDisplayState, false, int.MAX_VALUE);
}
/**
* toggle full screen and normal.
*/
private function toggleDisplayState(evt:MouseEvent):void
{
var s:Stage;
s = context.stage;
s.displayState = s.displayState == StageDisplayState.NORMAL
? StageDisplayState.FULL_SCREEN
: StageDisplayState.NORMAL;
event(s, MouseEvent.CLICK, toggleDisplayState, false, int.MAX_VALUE);
}
/**
* finalize the object.
*/
override protected function finalize():void
{
context = null;
}
}
/**
* main animation.
*/
internal class MainAnimationThread extends Thread
{
private var context:Context;
private var monitor:Monitor;
private var data:String;
private var hsv:ColorHSV;
private var dataIndex:uint;
private var targetIndex:uint;
/**
* constructor.
*/
public function MainAnimationThread(context:Context, data:String)
{
this.context = context;
this.data = data.replace(/\r+|\n+|\s+/g, ' ');
hsv = new ColorHSV(0, 1, 1, 1);
dataIndex = 0;
targetIndex = 0;
monitor = new Monitor();
}
/**
* first executable.
*/
override protected function run():void
{
if (targetIndex >= TARGET_WORDS.length)
{
showFullMessage();
}
else if (dataIndex >= data.length)
{
// todo: logic implement.
}
else
{
var t:String,
c:String;
t = TARGET_WORDS.charAt(targetIndex);
c = data.charAt(dataIndex);
if (t == c)
{
addTargetCharacter(t);
}
else
{
addDefaultCharacter(c);
}
next(run);
}
}
/**
* add target character.
*/
private function addTargetCharacter(str:String):void
{
var b:ITween,
mat:Letter3DMaterial,
fnt:Font3D,
txt:Text3D,
rot:Number3D;
targetIndex++;
dataIndex++;
rot = Matrix3D.matrix2euler(context.camera.transform);
fnt = new HelveticaBold();
mat = new Letter3DMaterial(0xffffff);
try
{
txt = new Text3D(str, fnt, mat);
}
catch (e:Error)
{
return;
}
txt.z = 950;
txt.rotationX = rot.x;
txt.rotationY = rot.y;
txt.rotationZ = rot.z;
txt.filters = [
new GlowFilter(0xffffff, 1, 8, 8)
];
txt.useOwnContainer = true;
context.container.addChild(txt);
b = BetweenAS3.tween(txt, {
'z': 0,
'alpha': 0,
'rotationX': 360 * Math.random(),
'rotationY': 360 * Math.random(),
'rotationZ': 360 * Math.random()
}, null, 1, Expo.easeIn);
b.addEventListener(BetweenEvent.COMPLETE, completeHandler);
if (targetIndex >= TARGET_WORDS.length)
{
b.onComplete = monitor.notifyAll;
monitor.wait();
}
else
{
sleep(200);
}
b.play();
}
/**
* add character.
*/
private function addDefaultCharacter(str:String):void
{
var b:ITween,
to:Object, from:Object,
mat:Letter3DMaterial,
fnt:Font3D,
txt:Text3D,
rot:Number3D;
dataIndex++;
hsv.h += 5;
rot = Matrix3D.matrix2euler(context.camera.transform);
fnt = new HelveticaBold();
mat = new Letter3DMaterial(hsv.value, .25);
try
{
txt = new Text3D(str, fnt, mat);
}
catch (e:Error)
{
return;
}
txt.z = 950;
txt.rotationX = rot.x;
txt.rotationY = rot.y;
txt.rotationZ = rot.z;
txt.filters = [
new GlowFilter(0xffffff, 1, 8, 8)
];
txt.useOwnContainer = true;
context.container.addChild(txt);
b = BetweenAS3.tween(txt, {
'z': 0,
'alpha': 0,
'rotationX': 360 * Math.random(),
'rotationY': 360 * Math.random(),
'rotationZ': 360 * Math.random()
}, null, .75, Quadratic.easeIn);
b.addEventListener(BetweenEvent.COMPLETE, completeHandler);
if (dataIndex >= data.length)
{
b.onComplete = monitor.notifyAll;
monitor.wait();
}
else
{
sleep(50);
}
b.play();
}
/**
* show complete message.
*/
private function showFullMessage():void
{
var b:ITween,
mat:Letter3DMaterial,
fnt:Font3D,
txt:Text3D,
rot:Number3D;
rot = Matrix3D.matrix2euler(context.camera.transform);
mat = new Letter3DMaterial(0xffffff);
fnt = new HelveticaBold();
txt = new Text3D(TARGET_WORDS, fnt, mat);
txt.z = -1000;
txt.rotationX = Math.random() * 360;
txt.rotationY = Math.random() * 360;
txt.rotationZ = Math.random() * 360;
txt.alpha = 0;
txt.useOwnContainer = true;
context.container.addChild(txt);
b = BetweenAS3.tween(txt, {
'z': 500,
'alpha': 1,
'rotationX': rot.x,
'rotationY': rot.y,
'rotationZ': rot.z
}, null, 5, Elastic.easeOut);
b.play();
}
/**
* will execute when tween complete betweenas3.
*/
private function completeHandler(evt:BetweenEvent):void
{
var b:ITween,
t:ISingleTweenTarget,
obj:DisplayObject3D;
b = ITween(evt.target);
t = ISingleTweenTarget(b.tweenTarget);
obj = DisplayObject3D(t.target);
obj.parent.removeChild(obj);
}
/**
* finalize the object.
*/
override protected function finalize():void
{
context = null;
data = null;
}
}
/**
* rendering pv3d.
*/
internal class PV3DRenderThread extends Thread
{
private var context:Context;
/**
* constructor.
*/
public function PV3DRenderThread(context:Context)
{
this.context = context;
}
/**
* first executable.
*/
override protected function run():void
{
if (checkInterrupted()) return;
context.renderer.render();
next(run);
}
/**
* finalize the object.
*/
override protected function finalize():void
{
context = null;
}
}