蛍っぽい Partile
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mqea
*/
package {
//import aquioux.display.colorUtil.RGBWheel;
import flash.display.Graphics;
import flash.display.BlendMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.Dictionary;
import net.hires.debug.Stats;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
/**
* 蛍的 Partile
* @see http://wonderfl.net/c/s439 (Particle の挙動)
* @see http://wonderfl.net/c/w1PJ (Particle を Dictionary で管理)
* @author YOSHIDA, Akio
*/
public class Main extends Sprite {
// ステージサイズ
private const STAGE_WIDTH:Number = 465;
private const STAGE_HEIGHT:Number = 465;
// ビューア
private var viewSprite_:Sprite;
// パーティクル・リスト
private var particleList_:Dictionary;
// パーティクル色要パラメータ
private var colorAngle:Number = 0;
private const COLOR_ANGLE_ADD:Number = Math.PI / 100;
// マウスダウン・フラグ
private var isMouseDown_:Boolean;
// 最初に表示するメッセージ
private var message_:TextField;
/**
* コンストラクタ
*/
public function Main():void {
setup();
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, function():void {isMouseDown_ = true;});
stage.addEventListener(MouseEvent.MOUSE_UP, function():void {isMouseDown_ = false;});
}
// セットアップ
private function setup():void {
// 背景
var back:Shape = new Shape();
var g:Graphics = back.graphics;
g.beginFill(0x0);
g.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
g.endFill();
addChild(back);
// ビューア
viewSprite_ = new Sprite();
addChild(viewSprite_);
// パーティクル・リスト
particleList_ = new Dictionary();
// 最初に表示するメッセージ
message_ = new TextField();
message_.autoSize = TextFieldAutoSize.LEFT;
message_.text = "please drag";
message_.selectable = false;
message_.x = (STAGE_WIDTH - message_.width) / 2;
message_.y = (STAGE_HEIGHT - message_.height) / 2;
message_.blendMode = BlendMode.INVERT;
addChild(message_);
// Stats
addChild(new Stats());
}
// マウスダウンイベント・ハンドラ
private function mouseDownHandler(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
// 最初に表示するメッセージを削除
removeChild(message_);
message_ = null;
// アップデート
addEventListener(Event.ENTER_FRAME, update);
}
// アップデート
private function update(event:Event):void {
// マウスダウン中はパーティクル生成
if (isMouseDown_) {
var p:Particle = new Particle(mouseX, mouseY, RGBWheel.getRadianColor(colorAngle += COLOR_ANGLE_ADD));
particleList_[p] = true;
viewSprite_.addChild(p);
}
// パーティクルのアップデート
for (var key:Object in particleList_) {
p = Particle(key);
if (!p.destroy) p.update(STAGE_WIDTH, STAGE_HEIGHT);
if (p.destroy) {
viewSprite_.removeChild(p);
delete particleList_[p];
}
}
}
}
}
//package {
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Shape;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
/**
* パーティクル
* @author YOSHIDA, Akio
*/
/*public*/ class Particle extends Shape {
// 破壊
public function get destroy():Boolean { return _destroy; }
private var _destroy:Boolean;
// 移動
// 加速度
private var ax_:Number;
private var ay_:Number;
// 速度
private var vx_:Number;
private var vy_:Number;
// 空気抵抗
static private const FRICTION:Number = 0.98;
// パーティクルの表示に関するパラメータ
private var color_:uint; // 色
private var radius_:Number; // 半径
private var ruin_:Number; // 半径減衰
/**
* コンストラクタ
*/
public function Particle(x:Number = 0.0, y:Number = 0.0, color:uint = 0xffffff) {
this.x = x;
this.y = y;
color_ = color;
// ブレンドモード
blendMode = BlendMode.ADD;
// ブラーフィルター
filters = [new BlurFilter(16, 16, BitmapFilterQuality.HIGH)];
// パーティクルの半径
var range:int = 30; // 半径の可動範囲
var min:int = 30; // 半径の最小値
radius_ = Math.random() * range + min; // 半径
ruin_ = 100 / (radius_ * radius_); // 半径減衰
// 加速度
ax_ = Math.random() + 1;
ay_ = Math.random() + 1;
// 速度
vx_ = (Math.random() - 0.5) * (Math.random() * 10 + 5);
vy_ = (Math.random() - 0.5) * (Math.random() * 10 + 5);
}
// アップデート
public function update(sw:int, sh:int):void {
// パーティクルの半径を小さくする
radius_ -= ruin_;
// 半径が0以下のときは破壊
if (radius_ <= 0) _destroy = true;
// 移動
if (!_destroy) {
// ブラウン運動
vx_ += (Math.random() - 0.5) * ax_;
vy_ += (Math.random() - 0.5) * ay_;
// 空気抵抗
vx_ *= FRICTION;
vy_ *= FRICTION;
// 座標に反映
x += vx_;
y += vy_;
}
// ステージ外に出たときは破壊
if (x < -radius_ || x > sw + radius_) _destroy = true;
if (y < -radius_ || y > sh + radius_) _destroy = true;
// 描画
if (!_destroy) draw();
}
// 描画
private function draw():void {
var g:Graphics = this.graphics;
g.clear();
g.beginFill(color_);
g.drawCircle(0, 0, radius_);
g.endFill();
}
}
//}
//package aquioux.display.colorUtil {
/**
* コサインカーブで色相環的に RGB を計算
* @author YOSHIDA, Akio
*/
/*public*/ class RGBWheel {
/**
* 角度 angle に応じた RGB を得る(弧度法指定 radian)
* @param radian 角度(弧度法)
* @return 色(0xRRGGBB)
*/
static public function getRadianColor(radian:Number):uint {
var r:uint = (Math.cos(radian) + 1) * 0xff >> 1;
var g:uint = (Math.cos(radian + 2.0943951023931953) + 1) * 0xff >> 1;
var b:uint = (Math.cos(radian - 2.0943951023931953) + 1) * 0xff >> 1;
// 2.0943951023931953 = Math.PI * 2 / 3 radian(= 120 degree)
return r << 16 | g << 8 | b;
}
/**
* 角度 angle に応じた RGB を得る(度数法指定 degree)
* @param degree 角度(度数法)
* @return 色(0xRRGGBB)
*/
static public function getDegreeColor(degree:Number):uint {
return getRadianColor(degree * 0.017453292519943295);
}
}
//}