In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

くすだま

2010年4月11日
明日は娘の9歳の誕生日なので, ひとつこんなものを...
----------------------------------------------------------------
先日の「紙ふぶき」
(see: http://wonderfl.net/code/d1bb28bd17493ad8e9e997e5c3ca4e8b7cc35eda)
は実はこのために試作したものです
----------------------------------------------------------------
流用歓迎. (Taremaku クラスの MESSAGE プロパティを変更してください) 
----------------------------------------------------------------
Get Adobe Flash player
by tenasaku 11 Apr 2010
/**
 * Copyright tenasaku ( http://wonderfl.net/user/tenasaku )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/g719
 */

// 2010年4月11日
// 明日は娘の9歳の誕生日なので, ひとつこんなものを...
// ----------------------------------------------------------------
// 先日の「紙ふぶき」
// (see: http://wonderfl.net/code/d1bb28bd17493ad8e9e997e5c3ca4e8b7cc35eda)
// は実はこのために試作したものです
// ----------------------------------------------------------------
// 流用歓迎. (Taremaku クラスの MESSAGE プロパティを変更してください) 
// ----------------------------------------------------------------

package {

	import flash.display.*;
	import flash.events.*;
	import flash.text.*;
	import flash.utils.*;

	public class Main extends Sprite {

		private const NUM_KAMIKIRE:int = 320;
		private const TEXT1:String = "たま を クリック してください";
		private const TEXT2:String = "もういちど みるには\nリロード してください";

		private var maku:Taremaku;
		private var kamiFubuki:Array;
		private var tama:Kusudama;
		private var tf:TextField;

		private function atEveryFrame(e:Event):void {
			if ( tama.scaleX > 1.0 ) {
				tama.scaleX = Math.max(1.0, tama.scaleX - 0.1);
				tama.scaleY = tama.scaleX;
				return;
			}
			if ( tama.tipOpen < Math.PI/3 ) {
				tama.tipOpen += Math.PI/30;
			}
			if ( ( tama.tipOpen >= Math.PI/4 ) && ( maku.scaleY < 1.0 ) ) {
					maku.scaleY += 0.1;
			}
			var i:int = 0;
			while ( i < kamiFubuki.length ) {
				kamiFubuki[i].rotation3D += kamiFubuki[i].omega;
				kamiFubuki[i].fall();
				if ( kamiFubuki[i].x < 0 ) {
					kamiFubuki[i].x += stage.stageWidth;
				}
				if ( kamiFubuki[i].x >= stage.stageWidth ) {
					kamiFubuki[i].x -= stage.stageWidth;
				}
				if ( kamiFubuki[i].y - Kamikire.SIZE/Math.SQRT2 >= stage.stageHeight ) {
					this.removeChild(kamiFubuki[i]);
					kamiFubuki.splice(i,1);
				} else {
					++i;
				}
			}
			if ( kamiFubuki.length == 0 ) {
				tf.text = TEXT2;
				tf.visible = true;
				tf.x = (stage.stageWidth - tf.width)/2;
				tf.y = stage.stageHeight - tf.height - 10;
				this.removeEventListener(Event.ENTER_FRAME, atEveryFrame);
			}
		}

		private function onClick(e:MouseEvent):void {
			tf.visible = false;
			tama.removeEventListener(MouseEvent.CLICK, onClick);
			this.addEventListener(Event.ENTER_FRAME, atEveryFrame);
		}

		private function initialize(e:Event):void {
			this.removeEventListener(Event.ADDED_TO_STAGE, initialize);
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			this.graphics.beginFill(0xff9966);
			this.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
			this.graphics.endFill();
			tama = new Kusudama();
			tama.x = stage.stageWidth/2;
			tama.y = 20;
			kamiFubuki = new Array();
			maku = new Taremaku();
			maku.x = stage.stageWidth/2;
			maku.y = tama.y + Kusudama.SIZE/2*Math.sqrt(3);
			addChild(maku);
			while ( kamiFubuki.length < NUM_KAMIKIRE ) {
				kamiFubuki.unshift(new Kamikire());
				kamiFubuki[0].x = stage.stageWidth/2;
				kamiFubuki[0].y = tama.y+Kusudama.SIZE/2;
				this.addChild(kamiFubuki[0]);
			}
			tama.scaleX = Math.min(stage.stageWidth-40,stage.stageHeight-40)/Kusudama.SIZE;
			tama.scaleY = tama.scaleX;
			this.addChild(tama);
			stage.frameRate = 20;
			var fmt:TextFormat = new TextFormat();
			var fontList:Array = Font.enumerateFonts(true);
			var i:int;
			for each ( var ft:Font in fontList ) {
				if ( ft.fontName == "ヒラギノ角ゴ Pro W6" ) {
					fmt.font = "ヒラギノ角ゴ Pro W6";
					break;
				} if ( ft.fontName == "MS ゴシック" ) {
					fmt.font = "MS ゴシック";
					break;
				}
			}
			fmt.size = 24;
			fmt.leftMargin = 4;
			fmt.rightMargin = 4;
			fmt.align = TextFormatAlign.CENTER;
			tf = new TextField();
			tf.autoSize = TextFieldAutoSize.CENTER;
			tf.defaultTextFormat = fmt;
			tf.background = true;
			tf.backgroundColor = 0x0000ff;
			tf.textColor = 0xffff00;
			tf.text = TEXT1;
			tf.visible = true;
			tf.x = (stage.stageWidth - tf.width)/2;
			tf.y = stage.stageHeight - tf.height - 10;
			this.addChild(tf);
			tama.addEventListener(MouseEvent.CLICK, onClick);
		}
		// The Main constructor simply calles initialize() function.

		public function Main():void {
			if ( stage != null ) {
				initialize(null);
			} else {
				this.addEventListener(Event.ADDED_TO_STAGE, initialize);
			}
		}

	} // end of class Main
} // end of package

import flash.display.*;
import flash.geom.*;
import flash.text.*;

// 固有の軸のまわりで3D回転しながらフラフラと落下する正方形の紙切れ
import flash.display.*;
class Kamikire extends Shape {
	public static const SIZE:Number = 10;
	private var _faceColor:uint;
	private var _backColor:uint;
	private var _theta:Number; // amount of rotation along the axis
	private var _omega:Number; // angular velocity
	private var _fallTheta:Number;
	private var _fallSpeed:Number;
	private var _Ax:Number,_Ay:Number,_Az:Number; // axis of rotation
	private var _Bx:Number,_By:Number,_Bz:Number; // a unit vector perp to A
	private var _Cx:Number,_Cy:Number,_Cz:Number; // a unit vector perp to A and B
	public function Kamikire() {
		var t:Number = Math.random()*Math.PI*2;
		var r:int = Math.floor((1+Math.cos(t))*127.9999);
		var g:int = Math.floor((1+Math.cos(t+Math.PI*2/3))*127.9999);
		var b:int = Math.floor((1+Math.cos(t-Math.PI*2/3))*127.9999);
		_faceColor = (r<<16)|(g<<8)|b;
		_backColor = 0x010101*Math.floor(127+Math.random()*64);
		_omega = (Math.random()*2-1)*Math.PI/4;
		_fallTheta = 0;
		_fallSpeed = 3+Math.random()*2;
		_theta = Math.random()*Math.PI*2;
		_Ax = 1;
		_Ay = Math.random();
		_Az = Math.random()*2-1;
		var _l:Number = Math.sqrt(_Ax*_Ax+_Ay*_Ay+_Az*_Az);
		_Ax /= _l;
		_Ay /= _l;
		_Az /= _l;
		var _s:Number = Math.sqrt(_Ax*_Ax+_Ay*_Ay);
		if ( _s == 0 ) { // then A == ( 0, 0, -1 );
			_Bx = 1.0; _By = 0.0; _Bz = 0.0;
			_Cx = 0.0; _Cy = 1.0; _Cz = 0.0;
		} else {
			_Bx = _Ay; _By = -_Ax; _Bz = 0;
			_Cx = _Ax*_Az; _Cy = _Ay*_Az; _Cz = -(_s*_s);
			_Bx /= _s; _By /= _s;
			_Cx /= _s*_l; _Cy /= _s*_l; _Cz /= _s*_l;
		}
		this.graphics.beginFill(_faceColor);
		this.graphics.drawRect(-SIZE/2,-SIZE/2,SIZE,SIZE);
		this.graphics.endFill();
	}
	public function get omega():Number {
		return _omega;
	}
	// rotate along the axis (_Ax,_Ay,_Az)...
	public function set rotation3D(theta:Number):void {
		_theta = theta - (Math.PI*2)*Math.floor(theta/(Math.PI*2));
		var _cos:Number = Math.cos(_theta);
		var _sin:Number = Math.sin(_theta);
		// vector F is the rotated image of (1,0,0);
		var _Fx:Number = _Ax*_Ax+(_Bx*_Bx+_Cx*_Cx)*_cos;
		var _Fy:Number = _Ax*_Ay+(_Bx*_By+_Cx*_Cy)*_cos+(_Bx*_Cy-_Cx*_By)*_sin;
		var _Fz:Number = _Ax*_Az+(_Bx*_Bz+_Cx*_Cz)*_cos-(_Bx*_Cz-_Cx*_Bz)*_sin;
		// vector G is the rotated image of (0,1,0);
		var _Gx:Number = _Ax*_Ay+(_By*_Bx+_Cy*_Cz)*_cos+(_By*_Cx-_Cy*_Bx)*_sin;
		var _Gy:Number = _Ay*_Ay+(_By*_By+_Cy*_Cy)*_cos;
		var _Gz:Number = _Ay*_Az+(_By*_Bz+_Cy*_Cz)*_cos+(_By*_Cz-_Cy*_Bz)*_sin;
		// let's see whether the piece shows its face or its back...
		var cc:uint = ( (_Az*_Az+(_Bz*_Bz+_Cz*_Cz)*_cos) >= 0 )?_faceColor:_backColor;
		// We can draw the image now...
		this.graphics.clear();
		this.graphics.beginFill(cc);
		this.graphics.moveTo(_Fx*SIZE/2+_Gx*SIZE/2,_Fy*SIZE/2+_Gy*SIZE/2);
		this.graphics.lineTo(-_Fx*SIZE/2+_Gx*SIZE/2,-_Fy*SIZE/2+_Gy*SIZE/2);
		this.graphics.lineTo(-_Fx*SIZE/2-_Gx*SIZE/2,-_Fy*SIZE/2-_Gy*SIZE/2);
		this.graphics.lineTo(_Fx*SIZE/2-_Gx*SIZE/2,_Fy*SIZE/2-_Gy*SIZE/2);
		this.graphics.lineTo(_Fx*SIZE/2+_Gx*SIZE/2,_Fy*SIZE/2+_Gy*SIZE/2);
		this.graphics.endFill();
	}
	public function get rotation3D():Number {
		return _theta - (Math.PI*2)*Math.floor(_theta/(Math.PI*2));
	}
	public function fall():void {
		this.x += _fallSpeed*Math.sin(_fallTheta);
		this.y += _fallSpeed*Math.cos(_fallTheta);
		_fallTheta += (Math.random()*2-1)*Math.PI/12;
		if ( _fallTheta < -Math.PI/2 ) {
			_fallTheta = -Math.PI - _fallTheta;
		}
		if ( _fallTheta > Math.PI/2 ) {
			_fallTheta = Math.PI - _fallTheta;
		}
	}
} // end of class Kamikire

class Kusudama extends Sprite {
	public static const SIZE:Number = 100;
	private var migi:Shape;
	private var hidari:Shape;
	public function set tipOpen(t:Number):void {
		if (t < 0) { t = 0; }
		if (t > Math.PI/2) { t = Math.PI/2; }
		hidari.rotation = t/Math.PI*90;
		migi.rotation = -hidari.rotation;
	}
	public function get tipOpen():Number {
		return hidari.rotation/90*Math.PI;
	}
	public function Kusudama() {
		var mat:Matrix = new Matrix;
		mat.createGradientBox(SIZE,SIZE,Math.PI/2,0,0);
		migi = new Shape();
		hidari = new Shape();
		migi.graphics.clear();
		migi.graphics.beginGradientFill(
			GradientType.LINEAR,
			[0xffffff,0xffcccc,0xcc3333],[1,1,1],[0,64,127],
			mat,
			SpreadMethod.PAD
		);
		migi.graphics.moveTo(0,0);
		migi.graphics.curveTo(SIZE/2,0,SIZE/2,SIZE/2);
		migi.graphics.curveTo(SIZE/2,SIZE,0,SIZE);
		migi.graphics.lineTo(0,0);
		migi.graphics.endFill()
		hidari.graphics.clear();
		hidari.graphics.beginGradientFill(
			GradientType.LINEAR,
			[0xffffff,0xffcccc,0xcc3333],[1,1,1],[0,64,127],
			mat,
			SpreadMethod.PAD
		);
		hidari.graphics.moveTo(0,0);
		hidari.graphics.curveTo(-SIZE/2,0,-SIZE/2,SIZE/2);
		hidari.graphics.curveTo(-SIZE/2,SIZE,0,SIZE);
		hidari.graphics.lineTo(0,0);
		hidari.graphics.endFill();
		this.addChild(migi);
		this.addChild(hidari);
	}
}

class Taremaku extends Sprite {
	private const MAKUHABA:Number = Kusudama.SIZE - 4;
	private const MESSAGE:String = "ゆきかちゃん\nおたんじょうび\nおめでとう!";
	private const MARGIN_TOP:Number = 12;
	private var fmt:TextFormat;
	private var letterList:Array; // List of TextFields associated to each letter...
	// constructor method...
	public function Taremaku() {
		letterList = new Array();
		fmt = new TextFormat();
		var fontList:Array = Font.enumerateFonts(true);
		var i:int;
		for each ( var ft:Font in fontList ) {
			if ( ft.fontName == "ヒラギノ明朝 Pro W6" ) {
				fmt.font = "ヒラギノ明朝 Pro W6";
				break;
			} if ( ft.fontName == "MS 明朝" ) {
				fmt.font = "MS 明朝";
				break;
			}
		}
		fmt.size = 18;
		fmt.bold = true;
		fmt.align = TextFormatAlign.CENTER;
		var p:int = 0;
		var horiz:int = MAKUHABA/3;
		var vert:int = MARGIN_TOP;
		for ( i = 0 ; i < MESSAGE.length ; ++i ) {
			var s:String = MESSAGE.charAt(i);
			if ( s == "\n" ) {
				horiz -= MAKUHABA/3;
				vert = MARGIN_TOP;
			} else {
				p++;
				letterList[p] = new TextField();
				letterList[p].defaultTextFormat = fmt;
				letterList[p].text = s;
				letterList[p].autoSize = TextFieldAutoSize.CENTER;
				letterList[p].x = horiz - letterList[p].width/2;
				letterList[p].y = vert;
				vert += letterList[p].height+3;
				this.addChild(letterList[p]);
			}
		}
		this.height += letterList[p].height+MARGIN_TOP/2;
		var h:Number = this.height;
		this.graphics.clear();
		this.graphics.beginFill(0xffffff);
		this.graphics.drawRect(-MAKUHABA/2,0,MAKUHABA,h);
		this.graphics.endFill();
		this.graphics.lineStyle(3,0xff0000);
		this.graphics.moveTo(-MAKUHABA/2,0);
		this.graphics.lineTo(-MAKUHABA/2,h);
		this.graphics.moveTo(+MAKUHABA/2,0);
		this.graphics.lineTo(+MAKUHABA/2,h);
		this.scaleY = 0;
	}
}