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

forked from: DeviceGameSample

Get Adobe Flash player
by picana 31 Jul 2010
/**
 * Copyright picana ( http://wonderfl.net/user/picana )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sZvo
 */

package {
    import flash.display.Sprite;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.display.Bitmap;
    import flash.display.BitmapData
    import flash.display.Graphics;
    import flash.geom.Matrix;
    import flash.events.Event;

    [SWF(width=544, height=392, frameRate="30")] 
    
    public class Main extends Sprite {
        private var field:Field;
        public var player:Player;
        private var enemy:Enemy;
        public static const WIDTH:Number = 544;
        public static const HEIGHT:Number = 392;
        public var mainBitmapData:BitmapData
        
        public function Main() {
                // 最初にinitを呼び出す
            addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            stage.scaleMode = StageScaleMode.EXACT_FIT;
            // 画面の左上に合わせて表示する
            stage.align = StageAlign.TOP_LEFT;
            field = new Field(this);
            addChild(field);
            
            graphics.beginFill(0xaaaaaaaa);
            graphics.drawRect(0, 0, WIDTH, HEIGHT);
            
            // プレイヤー作成
            player = new Player(171, 352);
            // fieldに追加
            field.addActor(player);
            // 敵作成
            enemy = new Enemy(171, 40, field);
            // fieldに追加
            field.addActor(enemy);
            
            // カメラとマイクのデータを取得するためのクラス
            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 = 352;
            video.y = 10;
        }

        private function powerChangeHnadler(e:DeviceManagerEvent):void {
            
            // 自機を動かす
            player.move((e.rightPower - e.leftPower)/200);
           
            // 一定以上の音量のときは弾発射
            if (e.micPower > 3) {
                field.nWay(BigBall, 3, Math.PI*3/2, Math.PI*1/12);
            }

        }
    }
}

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 {
    public var fieldBitmapData:BitmapData;
    private var actors:Array;
    public static const FIELD_WIDTH:Number = 322;
    public static const FIELD_HEIGHT:Number = 372;
    private var main:Main;

    public function Field(main:Main) {
        this.main = main;
        this.x = 10; this.y = 10;
        
        actors = [];
        fieldBitmapData = new BitmapData(FIELD_WIDTH, FIELD_HEIGHT, false, 0x000000);
        var bitmap:Bitmap = new Bitmap(fieldBitmapData);
        bitmap.blendMode = BlendMode.ADD;
        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);
            }
            
            a.update();
            mtx = new Matrix();
            mtx.translate(a.x, a.y);
            fieldBitmapData.draw(a.view, mtx,null,BlendMode.ADD);    
            index++;
            
            
        }
    }

    public function addActor(actor:Actor):void {
        actors.push(actor);
    }
    
    public function nWay(bullet:Class, n:int, direction:Number, range:Number):void {
        if (n > 1) {
            for (var i:int = 0; i < n; i++) {
                addBullet(new bullet(main.player.x, main.player.y, direction + range * (i/(n-1)-0.5)));
            }
        } else if (n == 1) {
            addBullet(new bullet(main.player.x, main.player.y, direction));
        }
    }
    
    public function addBullet(bullet:Bullet):void {
            actors.push(bullet);
    }

}

/*****************************
 * Fieldに追加される何かの基本クラス *
 *****************************/
class Actor {
    public var color:uint;
    public var x:Number;
    public var y:Number;
    public var vx:Number;
    public var vy:Number;
    public var view:Sprite;
    public var die:Boolean = false;
    public static var field:Field;

    public function Actor(x:Number, y:Number) {
        this.x = x;
        this.y = y;
    }

    public function update():void { }
    
    public function nWay(bullet:Class, n:int, direction:Number, range:Number):void {
        if (n > 1) {
            for (var i:int = 0; i < n; i++) {
                field.addBullet(new bullet(x, y, direction + range * (i / (n - 1) - 0.5)));
            }
        } else if (n == 1) {
            field.addBullet(new bullet(x, y, direction));
        }
    }
}

// 自機
class Player extends Actor {

    public function Player(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 < 10) x = 0;
        else if (x > Field.FIELD_WIDTH-10) x = Field.FIELD_WIDTH-10;
    }
}

class Enemy extends Actor {
    private var t:Number;
    
    // コンストラクタ
    public function Enemy(x:Number, y:Number, field:Field) {
        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);
        
        Actor.field = field;
        t = 0;
    }

    public override function update():void {
        t++;            
        // 攻撃開始
        if (t > 10) {
            if (!(t % 100)) {
                nWay(GrainBullet2, 30, Math.PI * (t % 360) / 180, Math.PI * 2);
            }
        }
    }
}

// 弾
class Bullet extends Actor {
    public var direction:Number;
    public var v:Number;
    
    public function Bullet(x:Number, y:Number, direction:Number, v:Number) {
        super(x, y);
        this.direction = direction;
        this.v = v;
    }
    
    
    
    public function checkDie():void {
        if (!(x > 0 && x < Field.FIELD_WIDTH && y > 0 && y < Field.FIELD_HEIGHT)) {
            die = true;
        }
    }
}

import flash.filters.GlowFilter;
import flash.filters.BlurFilter;
class GrainBullet1 extends Bullet {
    public function GrainBullet1(x:Number, y:Number, direction:Number, v:Number = 3) {
        super(x, y, direction, v);
        
        color = Math.random() * 0xFFFFFF;
        
        view = new Sprite();        
        var g:Graphics = view.graphics;
        g.lineStyle(2, color);
        g.drawCircle(0, 0, 2);
        view.filters = [new BlurFilter(2,2,3)];
        view.blendMode = BlendMode.ADD;
    }
    
    public override function update():void {
        vx =  Math.cos(direction) * v;
        vy = -Math.sin(direction) * v;
        
        x += vx;
        y -= vy;
        
        checkDie();
    }
}

// 大玉

class BigBall extends Bullet {    
    public function BigBall(x:Number, y:Number, direction:Number, v:Number = 10.5) {
        super(x, y, direction, v);
        
        color = 0xff0000;
        view = new Sprite();        
        var g:Graphics = view.graphics;
        g.lineStyle(2, color);
        g.drawCircle(0, 0, 5);
        view.filters = [new BlurFilter(2,2,3)];
        view.blendMode = BlendMode.ADD;
    }
    
    public override function update():void {
        vx =  Math.cos(direction) * v;
        vy = -Math.sin(direction) * v;
        
        x += vx;
        y -= vy;
        
        checkDie();
    }
    
    /*
    public function hitTest():Boolean {
        return Math.sqrt(Math.pow(player.x - x, 2) + Math.pow(player.y - y, 2)) < 10;
    }
    */

}

/*
class BigBall1 extends BigBall {
    public function BigBall1(x0:Number, y0:Number, d:Number, v:Number = 1) {
        super(x0, y0, d);
        vx =  Math.cos(direction) * v;
        vy = -Math.sin(direction) * v;
    }

    override public function update():void {
        x += vx;
        y += vy;

        if (x < -10 || x > field.fieldWidth + 10 ||
            y < -10 || y > field.fieldHeight + 10) {
            dead = true;
        }
    }
}
*/

/************************
 * 敵機の周りを回った後はじける *
 ************************/
class GrainBullet2 extends Bullet {

    private var t:uint = 0;

    public function GrainBullet2(x:Number, y:Number, direction:Number, v:Number = 4) {
        super(x, y, direction, v);
        
        color = 0x0000ff;
        
        view = new Sprite();        
        var g:Graphics = view.graphics;
        g.lineStyle(5, color);
        g.drawCircle(0, 0, 10);
        view.filters = [new BlurFilter(2,2,3)];
        view.blendMode = BlendMode.ADD;
    }

    override public function update():void {
        t++;
        if (t < 300) {
            direction += 0.06 - t * 0.0002;
            x += Math.cos(direction*2) * v;
            y -= Math.sin(direction*2) * v;
        } else {
            nWay(GrainBullet1, 6, t, Math.PI * 2);
            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, 40);
        _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;
    }
}