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

[セルフフォーク]ひだまりスケッチの星 を飛び散るようにしてみた

ひだまりスケッチ ほしみっつ の星 を飛び散るようにしてみた
@author Hiiragi

セルフフォーク
作らなきゃいけないコンテンツを作る気が起きなかったので
なんとなく思いついて、違うことをしてみました。 

OPのサビ前に、星がバシバシ飛び散るのを再現してみました。
ステージをクリックすると星が飛び散ります。

本当は、写真を読み込んで、それをクリックしたときに
ガーッと揺れ動くというか拡大するというか
そういうのをやりたかったんですが、上手くいかなかったので終了。

FlashCampで話が出た「cacheAsBitmap」と「オブジェクトプール」を
試してみた感じです。確かにSpriteをガシガシ作ってるけど、
ガベージコレクションがかからない感じ。

最初に720個の星と初期設定をしてるので、最初若干重いです。
package 
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Matrix;
	import flash.net.FileReference;
	import flash.utils.Timer;
	
	import com.bit101.components.PushButton;
	
	/**
	 * ひだまりスケッチ ほしみっつ の星 を飛び散るようにしてみた
	 * @author Hiiragi
	 * 
	 * セルフフォーク
	 * 作らなきゃいけないコンテンツを作る気が起きなかったので
	 * なんとなく思いついて、違うことをしてみました。 
	 * 
	 * OPのサビ前に、星がバシバシ飛び散るのを再現してみました。
	 * ステージをクリックすると星が飛び散ります。
	 * 
	 * 本当は、写真を読み込んで、それをクリックしたときに
	 * ガーッと揺れ動くというか拡大するというか
	 * そういうのをやりたかったんですが、上手くいかなかったので終了。
	 * 
	 * FlashCampで話が出た「cacheAsBitmap」と「オブジェクトプール」を
	 * 試してみた感じです。確かにSpriteをガシガシ作ってるけど、
	 * ガベージコレクションがかからない感じ。
	 * 
	 * 最初に720個の星と初期設定をしてるので、最初若干重いです。
	 * 
	 */
	
	[SWF(width = 465, height = 465, frameRate = 60, backgroundColor = 0xFFAAAA)]
	public class Main extends Sprite 
	{
		private var _fr:FileReference;
		private var _loadBtn:PushButton;
		private var _loader:Loader;
		private var _loadImageSp:Sprite;
		
		private var _timer:Timer;
		private var _backSp:Sprite;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			start();
			// entry point
			//_fr = new FileReference();
			//_fr.addEventListener(Event.SELECT, fileSelectedHandler);
			//
			//_loadImageSp = new Sprite();
			//
			//_loader = new Loader();
			//_loadBtn = new PushButton(this, 0, 0, "load Image", loadImage);
			//_loadBtn.x = this.stage.stageWidth / 2 - _loadBtn.width / 2;
			//_loadBtn.y = this.stage.stageHeight / 2 - _loadBtn.height / 2;
		}
		
		//public function loadImage(e:MouseEvent):void
		//{
			//_fr.browse();
		//}
		//
		//private function fileSelectedHandler(e:Event):void 
		//{
			//trace("test");
			//_fr.addEventListener(ProgressEvent.PROGRESS,onProgress);
			//_fr.addEventListener(Event.COMPLETE,onComplete);
			// _fr.addEventListener(Event.OPEN, onOpen);
			// _fr.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
			//_fr.load(); // 読み込み処理を開始
		//}
		//
		//private function onProgress(e:ProgressEvent):void
		//{
			//trace("読み込んだバイト数:" + e.bytesLoaded + "、 全体のバイト数:" + e.bytesTotal);
		//}
		//
		//private function onComplete(e:Event):void
		//{
			//_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadComplete);
			//_loader.loadBytes(_fr.data);
			//
			// fr.type を参考にオブジェクト変換する等の処理を記述
			// fr.removeEventListener(...)
		//}
		//
		//private function imgLoadComplete(e:Event):void 
		//{
			//trace("enemyImage Load Completed");
			//
			//var loadImage:Bitmap = new Bitmap(imageSizeCompressor(Bitmap(_loader.content).bitmapData, this.stage.stageWidth, this.stage.stageHeight));
			//
			//_loadImageSp.addChild(loadImage);
			//
			//_loadImageSp.x = this.stage.stageWidth / 2 - _loadImageSp.width / 2;
			//_loadImageSp.y = this.stage.stageHeight / 2 - _loadImageSp.height / 2;
			//
			//this.addChild(_loadImageSp);
			//
			//start();
		//}
		//
		///**
		 //* 指定のBitmapDataを、幅と高さの比率をそのままに、閾値に合わせて拡大縮小します。
		 //* 
		 //* @param	inputBitmapData	拡大・縮小したいBitmapData
		 //* @param	maxWidth		幅の閾値
		 //* @param	maxHeight		高さの閾値
		 //* @return	閾値に合わせて拡大・縮小したBitmapData
		 //*/
		//private function imageSizeCompressor(inputBitmapData:BitmapData, maxWidth:int, maxHeight:int):BitmapData
		//{
			//var ratio:Number;	//どれくらい拡大・縮小するか
			//var fixWidth:int;	//拡大・縮小したときの幅
			//var fixHeight:int;	//拡大・縮小したときの高さ
			//
			//var returnBitmapData:BitmapData;
			//
			//maxWidth * maxHeightの範囲内に最大限に収める
			//横長の場合
			//if (inputBitmapData.width / inputBitmapData.height >=  maxWidth / maxHeight)
			//{
				//横長なので、横の大きさを閾値に合わせ、その比率分、高さを拡大縮小して、縦横の比率をそのままにサイズ変更する。
				//ratio = maxWidth / inputBitmapData.width;
				//fixWidth = maxWidth;
				//fixHeight = inputBitmapData.height * ratio;
			//}
			//縦長の場合
			//else if (inputBitmapData.width / inputBitmapData.height <  maxWidth / maxHeight)
			//{
				//ratio = maxHeight / inputBitmapData.height;
				//fixWidth = inputBitmapData.width * ratio;
				//fixHeight = maxHeight;
			//}
			//
			//returnBitmapData = new BitmapData(fixWidth, fixHeight, true, 0x0);
			//returnBitmapData.draw(inputBitmapData, new Matrix(ratio, 0, 0, ratio));
			//
			//return returnBitmapData;
		//}
	
		private function start():void 
		{
			//_timer = new Timer(33, 10);
			//_timer.addEventListener(TimerEvent.TIMER, shakeDisplayObject);
			//_timer.addEventListener(TimerEvent.TIMER_COMPLETE, shakeDisplayObjectComplete);
			
			var mtx:Matrix = new Matrix();
			mtx.createGradientBox(this.stage.stageWidth, this.stage.stageHeight, Math.PI / 2);
			var g:Graphics = this.graphics;
			g.beginGradientFill(GradientType.LINEAR, [0xFFEEEE, 0xFFFFFF], [1, 1], [0, 255], mtx);
			g.drawRect(0, 0, this.stage.stageWidth, this.stage.stageHeight);
			g.endFill();
			
			var burst:HidamariStarBurst = new HidamariStarBurst(this.stage.stageWidth, this.stage.stageHeight);
			this.addChild(burst);
			
			this.stage.addEventListener(MouseEvent.CLICK, burst.burst);
			//_loadImageSp.addEventListener(MouseEvent.CLICK, burst.burst);
			//_loadImageSp.addEventListener(MouseEvent.CLICK, startShakeDisplayObject);
		}
		
		//private function startShakeDisplayObject(e:MouseEvent):void 
		//{
			//if (_timer.running) _timer.stop();
			//_timer.reset();
			//_timer.start();
		//}
		//private function shakeDisplayObject(e:TimerEvent):void 
		//{
			//_loadImageSp.x = Math.random() * 30 - 15;
			//_loadImageSp.y = Math.random() * 30 - 15;
		//}
		//
		//private function shakeDisplayObjectComplete(e:TimerEvent):void 
		//{
			//_loadImageSp.x = _loadImageSp.y = 0;
		//}
	}
	
}



import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.Matrix;
import flash.geom.Point;

class HidamariStarBurst extends Sprite
{
	private const STAR_MAX:uint = 720;
	private const BURST_NUM:int = 60;
	
	private var _sw:int;
	private var _sh:int;
	
	private var _starPool:Array;
	private var _activeStars:Array;
	
	private var _burstFlag:Boolean;
	
	private var _clickPoint:Point;
	
	public function HidamariStarBurst(stageWidth:int, stageHeight:int)
	{
		_sw = stageWidth;
		_sh = stageHeight;
		
		_starPool = [];
		_activeStars = [];
		
		var star:HidamariStarExtend;
		var absX:Number;
		var absY:Number;
		
		for (var i:int = 0; i < STAR_MAX; i++) 
		{
			star = new HidamariStarExtend(Math.random() * 30 + 20);
			
			star.x = -2000;
			star.y = -2000;
			star.vx = Math.random() * 60 - 30;
			star.vy = Math.random() * 60 - 30;
			
			absX = Math.abs(star.vx);
			absY = Math.abs(star.vy);
			
			if (absX + absY < 10)
			{
				if (absX >= absY)
				{
					if (star.vx >= 0) star.vx += 30;
					else star.vx -= 30;
				}
				else
				{
					if (star.vy >= 0) star.vy += 30;
					else star.vy -= 30;
				}
			}
			star.rotation = i;
			
			star.cacheAsBitmap = true;
			
			this.addChild(star);
			_starPool[i] = star;
		}
		
		this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
	}
	
	public function velocityCompressor(velocity:Number):Number
	{
		if (velocity < 2 && velocity > -2)
		{
			if (velocity > 0)	velocity += 2;
			else				velocity -= 2;
		}
		
		return velocity;
	}
	
	public function burst(e:MouseEvent):void 
	{
		_burstFlag = true;
		_clickPoint = new Point(e.stageX, e.stageY);
	}
	
	private function burstStarProcess():void
	{
		var star:HidamariStarExtend;
		for (var i:int = 0; i < BURST_NUM; i++) 
		{
			star = _starPool.shift();
			star.x = _clickPoint.x;
			star.y = _clickPoint.y;
			_activeStars.push(star);
		}
	}
	
	private function onEnterFrameHandler(e:Event):void 
	{
		var len:int = _activeStars.length;
		var star:HidamariStarExtend;
		var deleteFlag:Boolean;
		
		for (var i:int = len - 1; i >= 0; i--) 
		{
			deleteFlag = false;
			
			star = _activeStars[i];
			star.x += star.vx;
			star.y += star.vy;
			
			if (star.x < -star.width / 2)
			{
				deleteFlag = true;
			}
			else if (star.x > _sw + star.width / 2)
			{
				deleteFlag = true;
			}
			
			if (star.y < -star.height / 2)
			{
				deleteFlag = true;
			}
			else if (star.y > _sh + star.height / 2)
			{
				deleteFlag = true;
			}
			
			if (deleteFlag)
			{
				_activeStars.splice(i, 1);
				_starPool.push(star);
				star.x = -2000;
				star.y = -2000;
			}
		}
		
		if (_burstFlag)
		{
			burstStarProcess();
			_burstFlag = false;
		}
	}
}

class HidamariStar extends Sprite
{
	private var _cx:Number;
	private var _cy:Number;
	private var _radius:Number;
	private var _insideRatio:Number;
	
	private var _secondStar:Sprite;
	private var _centerStar:Sprite;
	
	private var _secondStarBevelFilter:BevelFilter;
	private var _centerStarBevelFilter:BevelFilter;
	
	public function HidamariStar(radius:Number,
								 cx:Number = 0, 
								 cy:Number = 0, 
								 insideRatio:Number = 0.5) 
	{
		_radius = radius;
		_cx = cx;
		_cy = cy;
		_insideRatio = insideRatio;
		
		_secondStar = new Sprite();
		_centerStar = new Sprite();
		this.addChild(_secondStar);
		this.addChild(_centerStar);
		
		_secondStarBevelFilter = new BevelFilter(2, -45, 0x996666, 1, 0, .3, 2, 2, 1, 2, BitmapFilterType.OUTER, false);
		_centerStarBevelFilter = new BevelFilter(2, -45, 0x996666, 1, 0, .5, 2, 2, 1, 2, BitmapFilterType.OUTER, false);
		_secondStar.filters = [_secondStarBevelFilter];
		_centerStar.filters = [_centerStarBevelFilter];
		
		draw();
	}
	
	public function draw():void 
	{
		var mtx:Matrix = new Matrix();
		
		var g:Graphics = this.graphics;
		g.clear();
		
		g.beginFill(0xFFFFFF);
		g.lineStyle(10, 0xFFFFFF);
		drawStar(g, _radius);
		g.endFill();
		
		g = _secondStar.graphics;
		g.clear();
		mtx.createGradientBox(_radius * 2, _radius * 2, -Math.PI / 4, -_cx -_radius, -_cy - _radius);
		g.beginGradientFill(GradientType.LINEAR, [0xf0ac96, 0x780100], [1, 1], [0, 255], mtx);
		drawStar(g, _radius * .95);
		g.endFill();
		
		g = _centerStar.graphics;
		g.clear();
		mtx.createGradientBox(_radius * 2, _radius * 2, -Math.PI / 4, -_cx -_radius, -_cy - _radius);
		g.beginGradientFill(GradientType.LINEAR, [0xfdf9fa, 0xfdae10], [1, 1], [0, 255], mtx);
		drawStar(g, _radius * 0.8);
		g.endFill();
		
	}
	
	private function drawStar(g:Graphics, radius:Number):void
	{
		g.moveTo(_cx, _cy - radius);
		
		var diffRad:Number = Math.PI * 2 / 10;
		var rad:Number = -Math.PI / 2;
		var tempRadius:Number;
		
		for (var i:int = 1; i <= 10; i++)
		{
			rad += diffRad;
			tempRadius = (i % 2 == 1) ? tempRadius = radius * _insideRatio : tempRadius = radius;
			g.lineTo(Math.cos(rad) * tempRadius + _cx, Math.sin(rad) * tempRadius + _cy);
		}
	}
	
	public function get radius():Number { return _radius; }
	
	public function set radius(value:Number):void 
	{
		_radius = value;
		draw();
	}
	
	public function get insideRatio():Number { return _insideRatio; }
	
	public function set insideRatio(value:Number):void 
	{
		_insideRatio = value;
		draw();
	}
	
}


class HidamariStarExtend extends HidamariStar
{
	private var _vx:Number;
	
	public function get vx():Number { return _vx; }
	
	public function set vx(value:Number):void 
	{
		_vx = value;
	}
	
	private var _vy:Number;
	public function get vy():Number { return _vy; }
	
	public function set vy(value:Number):void 
	{
		_vy = value;
	}
	
	public function HidamariStarExtend(radius:Number,
								 cx:Number = 0, 
								 cy:Number = 0, 
								 insideRatio:Number = 0.5) 
	{
		super(radius, cx, cy, insideRatio);
		this.mouseEnabled = false;
	}
}