Beautifl - Flash Gallery

Thumbnail : きまぐれ作曲機 - forked from: Instrument
きまぐれ作曲機 - forked from: Instrument
AtuyL 2010-11-03 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from Event's Instrument
/*
 * 細胞さんたちが勝手に作曲してくれるよ(´・ω・)
 * 細胞さんたちは適当に結婚して落ち着くけど、
 * マウスで新しい出会いを与えてあげるとまた婚活をはじめるからね(´・ω・)
 * 
 * ある意味人生の縮図だね(´・ω・)
 */
package  {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.PixelSnapping;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.ColorTransform;
    import flash.geom.Rectangle;
    import frocessing.color.ColorHSV;
    import org.si.sion.events.SiONTrackEvent;
    import org.si.sion.sequencer.SiMMLTrack;
    import org.si.sion.SiONDriver;
    import org.si.sion.SiONVoice;
    import org.si.sion.utils.SiONPresetVoice;
    import org.si.sound.DrumMachine;
    
    [SWF(width=465,height=465,frameRate=30,backgroundColor=0xFFFFFF)]
    public class LifeGame extends Sprite {
        public var driver:SiONDriver = new SiONDriver();
        public var presetVoice:SiONPresetVoice = new SiONPresetVoice();
        
        // forked from keim_at_Si's "SiON TENORION for v0.57"
        // http://wonderfl.net/c/qf4b
        public var voices:Vector.<SiONVoice> = new Vector.<SiONVoice>(16);
        public var notes :Vector.<int> = Vector.<int>([36,48,60,72, 43,48,55,60, 65,67,70,72, 77,79,82,84]);
        public var length:Vector.<int> = Vector.<int>([ 1, 1, 1, 1,  1, 1, 1, 1,  4, 4, 4, 4,  4, 4, 4, 4]);
        
        private var bitmapWidth:int = 64;
        private var bitmapHeight:int = 64;
        private var bitmapData:BitmapData;
        private var bitmap:Bitmap;
        
        private var beatmapData:BitmapData;
        private var beatmap:Bitmap;
        
        private var colors:Vector.<uint>;
        private var field:Field;
        public function LifeGame() {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            
            // forked from keim_at_Si's "SiON TENORION for v0.57"
            // http://wonderfl.net/c/qf4b
            var i:int;
            for (i=0; i<4; i++) voices[i] = presetVoice["triangle8"];
            for (i=4; i<8;  i++) voices[i] = presetVoice["valsound.bass18"];
            for (i=8; i<16; i++) voices[i] = presetVoice["valsound.piano11"];
            
            field = new Field(bitmapWidth,bitmapHeight);
            
            bitmapData = new BitmapData(bitmapWidth,bitmapHeight,true,0x00FFFFFF);
            bitmap = new Bitmap(bitmapData,PixelSnapping.NEVER,false);
            bitmap.scaleX = stage.stageWidth / bitmapWidth;
            bitmap.scaleY = stage.stageHeight / bitmapHeight;
            addChild(bitmap);
            
            beatmapData = new BitmapData(bitmapWidth,bitmapHeight,true,0x0);
            beatmap = new Bitmap(beatmapData,PixelSnapping.NEVER,false);
            beatmap.scaleX = stage.stageWidth / bitmapWidth;
            beatmap.scaleY = stage.stageHeight / bitmapHeight;
            addChild(beatmap);
            
            // forked from ton's "ライフゲーム「グライダー銃」 Game of Life「Glider gun」"
            // http://wonderfl.net/c/8TxM
            var color:ColorHSV = new ColorHSV();
            colors = new Vector.<uint>(bitmapWidth * bitmapHeight, true);
            for (i = 0; i < bitmapHeight; i++) {
                for (var j:int = 0; j < bitmapWidth; j++) {
                    color.h = (i + j) * 4;
                    colors[bitmapWidth * i + j] = color.value32;
                }
            }
            
            driver.setBeatCallbackInterval(1);
            driver.addEventListener(SiONTrackEvent.BEAT,beat);
            driver.setTimerInterruption(1,interruption);
            
            driver.addEventListener(SiONTrackEvent.BEAT,beat);
            stage.addEventListener(Event.ENTER_FRAME,enter_frame);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,mouse_down);
            stage.addEventListener(MouseEvent.MOUSE_MOVE,mouse_move);
            stage.addEventListener(MouseEvent.MOUSE_UP,mouse_up);
            
            driver.bpm = 96;
            driver.play();
            
            var drum:DrumMachine = new DrumMachine(0,0,8,1,0,0);
            drum.bassVoiceNumber = 5;
            drum.hihatVoiceNumber = 2;
            drum.snareVoiceNumber = 1;
            drum.play();
        }
        
        private function beat(event:SiONTrackEvent):void{
            for each (var trk:SiMMLTrack in driver.sequencer.tracks) trk.keyOff();
        }
        
        private var beatCounter:int;
        private function interruption() : void{
            var x:int = beatCounter & bitmapWidth - 1;
            
            beatmap.bitmapData.colorTransform(beatmapData.rect,new ColorTransform(1.0,1.0,1.0,0.9));
            beatmap.bitmapData.fillRect(new Rectangle(x,0,1,bitmapHeight),0x10000000);
            
            for(var y:int = 0;y < bitmapHeight; y++) {
                var node:Node = field.getNode(x,y);
                if(node.status){
                    noteOn(node.x,node.y);
                }
            }
            beatCounter++;
        }
        
        private var keyFlag:int;
        private function noteOn(x:int,y:int):void{
            var i:int = x % 16;
            var note:int = notes[i];
            var len:int = length[i];
            
            var v:int = y / 4;
            trace(v);
            var voice:SiONVoice = voices[v];
            this.driver.noteOn(note,voice,len);
        }
        
        private var isDown:Boolean;
        private function mouse_down(e:MouseEvent):void {
            isDown = true;
        }
        private function mouse_move(e:MouseEvent):void {
            if(!isDown) return;
            
            var x:int = bitmap.mouseX >> 0;
            var y:int = bitmap.mouseY >> 0;
            x = x < 0 ? 0 : x >= bitmapWidth - 1 ? bitmapWidth - 1 : x;
            y = y < 0 ? 0 : y >= bitmapHeight - 1 ? bitmapHeight - 1 : y;
            
            var node:Node = field.getNode(x,y);
            for(var i:int = 0,iLength:int = node.relationNodes.length;i < iLength;i++){
                node.relationNodes[i].status = true;
            }
        }
        private function mouse_up(e:MouseEvent):void {
            isDown = false;
        }
        
        private function enter_frame(event:Event):void{
            field.update();
            bitmapData.lock();
            bitmapData.colorTransform(bitmapData.rect,new ColorTransform(1.0,1.0,1.0,0.9));
            for(var i:int = 0;i < field.length;i++){
                var node:Node = field.nodes[i];
                if(node.status){
                    var color:uint = (0xFF << 24) + colors[node.y * bitmapWidth + node.x];
                    bitmapData.setPixel32(node.x,node.y,color);
                }
            }
            bitmapData.unlock();
        }
    }
}

internal class Field{
    public var length:int;
    public var nodes:Vector.<Node>;
    private var indices:Vector.<Vector.<int>>;
    public function getNode(x:int,y:int):Node{
        return nodes[indices[y][x]];
    }
    public function Field(w:int,h:int){
        length = w * h;
        nodes = new Vector.<Node>(length);
        buffer = new Vector.<Boolean>(length);
        indices = new Vector.<Vector.<int>>(h);
        var i:int;
        
        // create nodes
        var x:int,y:int;
        for(i = 0;i < length;i++){
            x = i % w;
            y = i / h;
            nodes[i] = new Node(x,y);
            indices[y] ||= new Vector.<int>(w);
            indices[y][x] = i;
        }
        
        // attach relation nodes ( link list
        var t:int,b:int;
        var l:int,r:int;
        for(i = 0;i < length;i++){
            x = i % w;
            y = i / h;
            
            l = x - 1;
            l = l < 0 ? w - 1 : l;
            
            r = x + 1;
            r = r >= w ? 0 : r;
            
            t = y - 1;
            t = t < 0 ? h - 1 : t;
            
            b = y + 1;
            b = b >= h ? 0 : b;
            
            //trace(l,x,r);
            //trace(t,y,b);
            
            nodes[i].relationNodes[0] = nodes[indices[t][l]];// top left
            nodes[i].relationNodes[1] = nodes[indices[t][x]];// top center
            nodes[i].relationNodes[2] = nodes[indices[t][r]];// top right
            nodes[i].relationNodes[3] = nodes[indices[y][l]];// middle left
            //nodes[i].relationNodes[0] = nodes[indices[y][x]];// middle-center is current node
            nodes[i].relationNodes[4] = nodes[indices[y][r]];// middle right
            nodes[i].relationNodes[5] = nodes[indices[b][l]];// bottom left
            nodes[i].relationNodes[6] = nodes[indices[b][x]];// bottom center
            nodes[i].relationNodes[7] = nodes[indices[b][r]];// bottom right
        }
    }
    
    private var buffer:Vector.<Boolean>;
    public function update():void{
        var i:int = 0,node:Node;
        for(i = 0;i < length;i++){
            node = nodes[i];
            var count:int = node.getCount();
            // high life
            var status:Boolean =
                 node.status && count <= 1 ? false
                :node.status && count <= 3 ? true
                :!node.status && count == 3 ? true
                :!node.status && count == 6 ? true
                :node.status && count >= 4 ? false : false;
            buffer[i] = status;
        }
        for(i = 0;i < length;i++){
            nodes[i].status = buffer[i];
        }
    }
}

internal class Node{
    public var x:int;
    public var y:int;
    public var relationNodes:Vector.<Node>;
    public function Node(x:int,y:int){
        this.x = x;
        this.y = y;
        this.relationNodes = new Vector.<Node>;
        this.status = Math.random() < 0.1;
    }
    public var status:Boolean;
    public function getCount():int{
        var count:int = 0;
        for(var i:int = 0,iLength:int = this.relationNodes.length;i < iLength;i++){
            var node:Node = this.relationNodes[i];
            count += node.status ? 1 : 0;
        }
        return count;
    }
}