みかんパーティクル
...
* @author mattodesign
*
* 要WEBCAM。
* 動体検知でみかんパーティクル!
*
/**
* Copyright mattodesign ( http://wonderfl.net/user/mattodesign )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gqp9
*/
/**
* ...
* @author mattodesign
*
* 要WEBCAM。
* 動体検知でみかんパーティクル!
*
*/
package {
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.media.Camera;
import flash.media.Video;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
//import com.flashdynamix.utils.SWFProfiler;
[SWF(backgroundColor = 0x000000, width = "465", height = "465", frameRate = 60)]
public class Main extends Sprite {
private var _loader:Loader;
private var _camera:Camera;
private var _video:Video;
private var _videoBmd:BitmapData;
private var _mat:Matrix;
private var _p:Particle;
private var _particleList:Vector.<Particle>;
private var _beforeBmd:BitmapData;
private var _oldBmd:BitmapData;
private var _pt:Point;
private var _mikan:Sprite;
public function Main():void {
// プロファイラの表示
//SWFProfiler.init(stage, this);
// 初期化
init();
}
//========================================================================
// 初期化
//========================================================================
private function init():void {
// みかん読み込み
_loader = new Loader();
var context:LoaderContext = new LoaderContext(true);
_loader.load(new URLRequest("http://level0.kayac.com/src/doke/mikan.png"), context);
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
// カメラをセットアップ
_camera = Camera.getCamera();
if (_camera != null) {
_video = new Video(stage.stageWidth, stage.stageHeight);
_video.attachCamera(_camera);
} else {
throw new Error("カメラがありません。");
}
// _videoBmdにカメラ映像を当て込む
_videoBmd = new BitmapData(_video.width, _video.height, false, 0x000000);
addChild(new Bitmap(_videoBmd));
addEventListener(Event.ENTER_FRAME, loop);
// 動体検出用のBitmapData作成
_pt = new Point(0, 0);
_oldBmd = new BitmapData(_video.width, _video.height, false, 0x000000);
_beforeBmd = new BitmapData(_video.width, _video.height, false, 0x000000);
// _particleListを作成
_particleList = new Vector.<Particle>();
}
//========================================================================
// みかんの読み込み完了処理
//========================================================================
private function complete(e:Event):void {
_mikan = new Sprite();
_mikan.addChild(_loader);
}
//========================================================================
// ENTER_FRAME処理
//========================================================================
private function loop(e:Event):void {
// カメラ映像を左右反転してdrawする
_mat = new Matrix( -1, 0, 0, 1, _videoBmd.width);
_videoBmd.draw(_video, _mat);
// 動体検知
_oldBmd.copyPixels(_videoBmd, _videoBmd.rect, _pt);
_oldBmd.draw(_beforeBmd, null, null, BlendMode.DIFFERENCE);
_oldBmd.threshold(_oldBmd, _oldBmd.rect, _pt, ">", 0xFF222222, 0xFFFFFFFF);
_beforeBmd.copyPixels(_videoBmd, _videoBmd.rect, _pt);
// 動体検知情報を_particleListに格納
var margin:int = 20;
for (var x:int = 0; x < _oldBmd.width; x = x + margin) {
for (var y:int = 0; y < _oldBmd.height; y = y + margin) {
if (_oldBmd.getPixel(x, y) == 0xFFFFFF) {
_p = new Particle();
_p.x = x;
_p.y = y;
_particleList.push(_p);
}
}
}
// みかん生成
createParticle();
}
//========================================================================
// Particle発生
//========================================================================
private function createParticle():void {
var radian:Number;
var speed:Number;
var mat:Matrix;
// _videoBmdにみかんを描画
_videoBmd.lock();
for (var i:Number = 0; i < _particleList.length; i++) {
_p = _particleList[i];
radian = Math.random() * Math.PI * 2;
speed = Math.random() * 30;
_p.vx = Math.cos(radian) * speed;
_p.vy = Math.sin(radian) * speed;
_p.x += _p.vx;
_p.y += _p.vy;
mat = new Matrix(1, 0, 0, 1, _p.x, _p.y);
_videoBmd.draw(_mikan, mat);
// 不要なパーティクルを_particleListから削除
if ((_p.x > stage.stageWidth || _p.x < 0) || (_p.y < 0 || _p.y > stage.stageHeight) || Math.abs(_p.vx) < 1 || Math.abs(_p.vy) < 1) {
_particleList.splice(i, 1);
}
}
_videoBmd.unlock();
}
}
}
//========================================================================
// Particleクラス
//========================================================================
class Particle {
public var x:Number = 0;
public var y:Number = 0;
public var vx:Number = 0;
public var vy:Number = 0;
public function Particle()
{
}
}