魔法もどきパーティクル(MotionTrack Particle)
カメラからモーションを検知してパーティクルを出現させます。
かめはめ波みたいなものを目指しましたが、今回は残念な結果に終わりました・・・が、部屋を薄暗くしてLEDランプ(ペンライトなど)をカメラの前で振り回せばライトセーバーで闘っている気分が味わえます。
暗い部屋でやってみたデモ映像はこちら:http://www.youtube.com/watch?v=6ScRbB7DYGA
/**
* Copyright mousepancyo ( http://wonderfl.net/user/mousepancyo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7ZmR
*/
package {
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.Event;
import flash.media.Camera;
import flash.media.Video;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.geom.ColorTransform;
import flash.filters.BlurFilter;
import flash.utils.Timer;
import flash.events.TimerEvent;
import idv.cjcat.stardust.common.clocks.SteadyClock;
import idv.cjcat.stardust.common.emitters.Emitter;
import idv.cjcat.stardust.common.renderers.Renderer;
import idv.cjcat.stardust.twoD.renderers.BitmapRenderer;
import frocessing.color.ColorHSV;
import net.hires.debug.Stats;
[SWF(backgroundColor=0, width=465, height=465, frameRate=30)]
public class Main extends Sprite {
private var _cam:Camera;
private var _tracker:Tracker;
private var _px:Number = 465 * .5
private var _py:Number = 465 * .5
protected var emitter:Emitter;
protected var renderer:Renderer;
private const stw:uint = stage.stageWidth,sth:uint = stage.stageHeight;
private var _hsv:ColorHSV;
private var _bmd:BitmapData;
private var _ctf:ColorTransform;
private var _isMotion:Boolean;
public function Main() {
initVideo()
_hsv = new ColorHSV(0, .8, .95);
_bmd = new BitmapData(465, 465, false, 0);
_ctf = new ColorTransform(.999, .999, .999);
//
var bm:Bitmap = new Bitmap(_bmd);
bm.blendMode = "add"
addChild(bm)
addChild(new Stats());
//
emitter = new MyEmitter(new SteadyClock(10));
renderer = new BitmapRenderer(_bmd);
renderer.addEmitter(emitter);
}
private function initVideo():void {
var video:Video = new Video(465, 465);
_cam = Camera.getCamera();
_cam.setMode(video.width, video.height, 25);
video.attachCamera(_cam);
var container:Sprite = new Sprite();
container.addChild(video);
addChild(container);
var mirror:Matrix = new Matrix();
mirror.scale( -1, 1);
mirror.translate(465,0)
container.transform.matrix = mirror;
//
_tracker = new Tracker(video);
addEventListener(Event.ENTER_FRAME, update);
_tracker.addEventListener("isMotion", motion);
// Check Tracking
//addChild(_tracker)
}
private function update(e:Event):void{
_tracker.track();
_px = _tracker.px;
_py = _tracker.py;
//
_ctf.redMultiplier = (_hsv.value >> 16 & 0xff) / 255;
_ctf.greenMultiplier = (_hsv.value >> 8 & 0xff) / 255;
_ctf.blueMultiplier = (_hsv.value & 0xff) / 255
//
if(_px){
_bmd.colorTransform(_bmd.rect, _ctf)
_bmd.applyFilter(_bmd, _bmd.rect, new Point(), new BlurFilter(8, 8, 3))
MyEmitter(emitter).point.x += (_px - MyEmitter(emitter).point.x) * .2;
MyEmitter(emitter).point.y += (_py - MyEmitter(emitter).point.y) * .2;
//
if(_isMotion){
_hsv.h++;
emitter.step();
}
}
}
private var _timer:Timer
private function motion(e:Event):void{
if(_timer) return;
_isMotion = true;
//
_timer = new Timer(1000, 1);
_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerComp);
_timer.start();
//
function timerComp():void{
_isMotion = false;
_timer = null;
}
}
}
}
// MotionTrack
import flash.display.BlendMode;
import flash.filters.BlurFilter;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Video;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
class Tracker extends Sprite {
public var _previous:BitmapData;
public var _current:BitmapData;
public var px:Number;
public var py:Number;
private var _blur:BlurFilter = new BlurFilter(64,64);
private var _vid:Video;
private var _mirror:Matrix;
private var _point:Point = new Point();
private var _area:Rectangle;
private var _isMotion:Boolean = false;
public function Tracker(vid:Video) {
_vid = vid;
_mirror = new Matrix();
_mirror.scale( -1, 1);
_mirror.translate(_vid.width, 0);
_current = new BitmapData(_vid.width,_vid.height,false,0x000000);
_previous = _current.clone();
}
public function track():void {
_current.draw(_vid, _mirror);
_current.draw(_previous, null, null, BlendMode.DIFFERENCE);
_current.applyFilter(_current, _current.rect, _point, _blur);
_current.threshold(_current, _current.rect, _point, ">", 0xFF333333, 0xFFFFFFFF);
_previous.draw(_vid, _mirror);
_area = _current.getColorBoundsRect(0xFFFFFFFF,0xFFFFFFFF,true);
_isMotion = ( _area.width > ( _vid.width / 100) * 10 || _area.height > (_vid.height / 100) * 10 );
if (_isMotion) {
px = _area.x + _area.width * .5;
py = _area.y + _area.height * .5;
graphics.clear();
graphics.lineStyle(1, 0xFF0000, .5);
graphics.drawRect(_area.x, _area.y, _area.width, _area.height);
dispatchEvent(new Event("isMotion"));
}
}
}
//Emitter
import idv.cjcat.stardust.common.actions.*;
import idv.cjcat.stardust.common.clocks.*;
import idv.cjcat.stardust.common.initializers.*;
import idv.cjcat.stardust.common.math.*;
import idv.cjcat.stardust.twoD.actions.*;
import idv.cjcat.stardust.twoD.emitters.*;
import idv.cjcat.stardust.twoD.initializers.*;
import idv.cjcat.stardust.twoD.zones.*;
import idv.cjcat.stardust.twoD.renderers.*;
import idv.cjcat.stardust.twoD.fields.BitmapField;
import idv.cjcat.stardust.twoD.fields.UniformField;
class MyEmitter extends Emitter2D {
public var point:SinglePoint = new SinglePoint();
public function MyEmitter(clock:Clock = null) {
super(clock);
addInitializer(new DisplayObjectClass(MyCircle));
addInitializer(new Velocity(new LazySectorZone(0.1, 0)));
addInitializer(new Life(new UniformRandom(40, 20)));
addInitializer(new Position(point));
//
addAction(new AlphaCurve(20,40));
addAction(new Age());
addAction(new DeathLife());
addAction(new Accelerate(0.1));
addAction(new Move());
//
var bmpField:BitmapField = new BitmapField();
bmpField.max = 0.1;
bmpField.massless = false;
bmpField.scaleX = bmpField.scaleY = 0;
//
var gravity:Gravity = new Gravity();
gravity.addField(bmpField);
gravity.addField(new UniformField( 0, 0.01));
addAction(gravity);
}
}
// Circle
import flash.display.Shape;
class MyCircle extends Shape {
public function MyCircle() {
graphics.beginFill (0xFFFFFF,1.0);
graphics.drawCircle(0, 0, Math.random()*6 | 0);
graphics.endFill()
}
}