DeviceGameSample
/**
* Copyright ll_koba_ll ( http://wonderfl.net/user/ll_koba_ll )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/44el
*/
package {
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Bitmap;
import flash.display.Graphics;
import flash.events.Event;
public class GameSample extends Sprite {
private var _field:Field;
private var _ship:Ship;
private const FIELD_WIDTH:Number = 465;
private const FIELD_HEIGHT:Number = 465;
public function GameSample() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_field = new Field(FIELD_WIDTH, FIELD_HEIGHT);
addChild(_field);
// 宇宙船作成
_ship = new Ship(FIELD_WIDTH/2, FIELD_HEIGHT- 35);
// fieldに追加
_field.addActor(_ship);
// カメラとマイクのデータを取得するためのクラス
var dm:DeviceManager = new DeviceManager();
dm.addEventListener(DeviceManagerEvent.POWER_CHANGE, powerChangeHnadler);
dm.start();
// カメラ映像を横に右上に置いておく
var video:Bitmap = addChild(new Bitmap(dm.nowBitmapData)) as Bitmap;
video.x = FIELD_WIDTH - video.width;;
}
private function powerChangeHnadler(e:DeviceManagerEvent):void {
// 自機を動かす
_ship.move((e.rightPower - e.leftPower)/100);
// 一定以上の音量のときは弾発射
if (e.micPower > 50) {
addBullet();
}
}
private function addBullet():void {
// 弾追加
var s:Bullet = new Bullet(_ship.x, _ship.y);
_field.addActor(s);
}
}
}
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Camera;
import flash.media.Video;
import flash.media.Microphone;
import flash.media.SoundTransform;
import flash.media.SoundMixer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.EventDispatcher;
import flash.utils.Timer;
// 自機、弾、敵を表示する
class Field extends Sprite {
private var _fieldBitmapData:BitmapData;
private var _actors:Array;
public function Field(w:Number, h:Number) {
_actors = [];
_fieldBitmapData = new BitmapData(w,h, false, 0x00000);
addChild(new Bitmap(_fieldBitmapData));
addEventListener(Event.ENTER_FRAME, enterFrameHandler)
}
private function enterFrameHandler(e:Event):void {
_fieldBitmapData.fillRect(_fieldBitmapData.rect, 0x000000);
var mtx:Matrix;
var index:int = 0;
// 自機、弾、敵をBitmapDataに描画
for each(var a:Actor in _actors) {
// 死亡フラグ
if (a.die) {
_actors.splice(index, 1);
continue;
}
a.update();
mtx = new Matrix();
mtx.translate(a.x, a.y);
_fieldBitmapData.draw(a.view, mtx);
index++;
}
}
public function addActor(actor:Actor):void {
_actors.push(actor);
}
}
// Fieldに追加される何かの基本クラス
class Actor {
public var x:Number = 0;
public var y:Number = 0;
public var view:Sprite;
public var die:Boolean = false;
public function Actor(x:Number, y:Number) {
this.x = x;
this.y = y;
}
public function update():void {}
}
// 自機
class Ship extends Actor {
public function Ship(x:Number, y:Number) {
super(x,y);
view = new Sprite();
// view
var g:Graphics = view.graphics;
g.lineStyle(1,0xFFFFFF);
g.moveTo(10, 10);
g.lineTo(0, -10);
g.lineTo(-10, 10);
g.lineTo(10,10);
}
public override function update():void {
}
public function move(value:Number):void {
x += value;
if (x < 0) x = 0;
else if (x > 465) x = 465;
}
}
// 弾
class Bullet extends Actor {
private var _speed:Number;
public function Bullet(x:Number, y:Number, speed:Number = 10) {
super(x,y);
_speed = speed;
view = new Sprite();
var g:Graphics = view.graphics;
g.lineStyle(1, 0xFFFFFF);
g.lineTo(0, -5);
}
public override function update():void {
y -= _speed;
if (y < 0) die = true;
}
}
class DeviceManager extends EventDispatcher {
private var _camera:Camera;
private var _mic:Microphone;
private var _video:Video;
private var _timer:Timer;
private var _now:BitmapData;
private var _nowLeft:BitmapData;
private var _prevLeft:BitmapData;
private var _nowRight:BitmapData;
private var _prevRight:BitmapData;
private var _rectLeft:Rectangle;
private var _rectReght:Rectangle;
private var _zero:Point;
public function get nowBitmapData():BitmapData {
return _now;
}
public function DeviceManager() {
// camera
_camera = Camera.getCamera();
if (_camera == null) {
return
}
_mic = Microphone.getMicrophone();
if (_mic == null) {
return;
}
_camera.setMode(160, 120, 15);
_video = new Video(_camera.width, _camera.height);
_video.attachCamera(_camera);
_now = new BitmapData(_camera.width, _camera.height);
_nowLeft = new BitmapData(_camera.width/2, _camera.height);
_prevLeft = new BitmapData(_camera.width/2, _camera.height);
_nowRight = new BitmapData(_camera.width/2, _camera.height);
_prevRight = new BitmapData(_camera.width/2, _camera.height);
// 左右分割のためのRectangle
_rectLeft = new Rectangle(0,0,_camera.width/2, _camera.height);
_rectReght = new Rectangle(_camera.width/2, 0, _camera.width/2, _camera.height);
_zero = new Point();
_mic.setLoopBack(true);
var stf:SoundTransform = SoundMixer.soundTransform;
stf.volume = 0;
SoundMixer.soundTransform = stf;
}
public function start():void {
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHnadler);
_timer.start();
}
private function timerHnadler(e:TimerEvent):void {
var mtx:Matrix = new Matrix();
mtx.scale(-1,1);
mtx.translate(_camera.width, 0);
_now.draw(_video, mtx);
// left
_nowLeft.copyPixels(_now, _rectLeft, _zero);
// 前回との比較
_nowLeft.draw(_prevLeft, null, null, BlendMode.DIFFERENCE);
// 変更されたピクセルの数が取得できる
var l:uint = _nowLeft.threshold(_nowLeft, _nowLeft.rect, _zero, ">", 0xFF111111, 0xFFFFFFFF);
_prevLeft.copyPixels(_now, _rectLeft, _zero);
// right
_nowRight.copyPixels(_now, _rectReght, _zero);
// 前回との比較
_nowRight.draw(_prevRight, null, null, BlendMode.DIFFERENCE);
// 変更されたピクセルの数が取得できる
var r:uint = _nowRight.threshold(_nowRight, _nowRight.rect, _zero, ">", 0xFF111111, 0xFFFFFFFF);
_prevRight.copyPixels(_now, _rectReght, _zero);
var level:Number = _mic.activityLevel;
dispatchEvent(new DeviceManagerEvent(DeviceManagerEvent.POWER_CHANGE,
l,r, level));
}
}
class DeviceManagerEvent extends Event {
public static const POWER_CHANGE:String = "powerChange";
public var leftPower:Number;
public var rightPower:Number;
public var micPower:Number;
public function DeviceManagerEvent(type:String,
leftPower:Number = 0,
rightPower:Number = 0,
micPower:Number = 0,
bubbles:Boolean = false,
cancelabable:Boolean = false){
super(type, bubbles, cancelabable);
this.leftPower = leftPower;
this.rightPower = rightPower;
this.micPower = micPower;
}
}