Model View Controller

by Cheshir
♥0 | Line 349 | Modified 2014-09-18 20:29:46 | MIT License
play

ActionScript3 source code

/**
 * Copyright Cheshir ( http://wonderfl.net/user/Cheshir )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7do9
 */

package {
    import flash.geom.Point;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.events.Event;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextField;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        private static var tracetext:TextField = new TextField();
        
        public static var testTile:Tile;
        
        private var load:MyLoader;
        
        public function FlashTest() {
            // write as3 code here...
            
            load = new MyLoader(stage);
            load.addEventListener(MyLoader.ALL_LOADED, initApp);
            load.loadAll();
            // It is not finished ! --- September 9, 2014
            
            tracetext.autoSize = TextFieldAutoSize.LEFT;
            tracetext.y = 300;
            stage.addChild(tracetext);
        }
        
        private var m:Model;
        private var randCaveGen:Array;
        private function initApp(e:Event):void {
            testTile = load.getLoaded()[2];
            tracetext.textColor = 0xf0fff0;
            FlashTest.log('initApp...');
            m = new Model();
            var controll:Controller = new Controller(m, load.getLoaded());
            var view:View = new View(m, controll, stage);
            stage.addChild(tracetext);    // replace after view...
            
            randCaveGen = load.getLoaded();
            randCaveGen.push(0,0,0);
            //addEventListener(Event.ENTER_FRAME, drawRandomCave);
        }
        
        private var randPoint:Point = new Point();
        private function drawRandomCave(e:Event):void{    // it would be better to create another controller
                randPoint.x = Math.floor(Math.random()*30*Math.random());
                randPoint.y = Math.floor(Math.random()*30*Math.random());
                m.selectTile(randPoint.x, randPoint.y);
                m.setSelectTile(randCaveGen[Math.floor(Math.random()*6)]);
        }

        
        private static var numLog:Number = 0;
        public static function log(v:Object):void{
            numLog++;
            if(numLog%5 == 0){
                tracetext.text = '';
            }
            tracetext.appendText('\n'+v.toString());
        }
    }
}
import flash.events.ProgressEvent;
import flash.display.LoaderInfo;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.SecurityDomain;
import flash.system.LoaderContext;
import flash.utils.Dictionary;
import flash.geom.Matrix;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.ui.Keyboard;
import flash.geom.Point;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.display.Sprite;

Class {
    class Model extends EventDispatcher {
        
        public var mapTile:Array = [];
        private var selectPos:Point;
        private var selX:int = 0;
        private var selY:int = 0;
        
        public static var tileSize:Number = 16;
        
        public function Model() {
            selectPos = new Point();
            // Maybe... i need init start model... as Cave?
            // I need walue... to width and Height of my Map...
            for(var xi:int=0; xi<45; xi++){
                mapTile[xi] = [];
                for(var yi:int=0; yi<45; yi++){
                    mapTile[xi][yi] = 0;
                }
            }
            FlashTest.log('initTile 2-3 '+getTile(2,3));
        }
        public function setSelectTile(tile:*):void{    // what? Why here X and Y ?
            mapTile[selX][selY] = tile;
            /* hm... before i dispatch changes... I want to calculate the illuminance */
            if(tile is Tile){
                tile.numState = getIlluminance(selX,selY);
            }
            dispatchEvent(new MapEvent(MapEvent.TILE_CHANGE, tile, selX, selY));
        }
        public function getTile(x:int, y:int):* {
            return mapTile[x][y];
        }
        public function get selectX():int {
            return this.selX;
        }
        public function set selectX(v:int):void {
            this.selX = v;
            dispatchEvent(new MapEvent(MapEvent.SELECT_CHANGE, null, selX, selY));
        }
        public function selectTile(nX:int, nY:int):void{
            this.selX = nX;
            this.selY = nY;
            dispatchEvent(new MapEvent(MapEvent.SELECT_CHANGE, null, selX, selY));
        }
        
        
        public function get selectY():int {
            return this.selY;
        }
        public function set selectY(v:int):void {
            this.selY = v;
            dispatchEvent(new MapEvent(MapEvent.SELECT_CHANGE, null, selX, selY));
        }
        private function getIlluminance(toX:int,toY:int):uint{
            // illuminance is state of tile
            var nX:int = toX;
            var nY:int = toY;
            var direct:Number = -Math.PI/2;
            var step:int = 1;
            var iterRotate:int = 0;
            var iterIllum:int = 0;
            var currStep:int = 0;
            var needStep:int = 1;
            var illum:uint = 0;
            // Bitmap test spiral http://wonderfl.net/c/2BQS 
            for(var i:int=0;i<81;i++) {
                nX += Math.cos(direct);    // select tile
                nY += Math.sin(direct);
                currStep++;
                
                if(currStep==needStep){    // turn direct algoritm
                    direct += Math.PI/2;
                    iterRotate++;
                    currStep=0;
                    if(iterRotate==2){
                        iterRotate=0;
                        needStep++;
                        //illum++;
                        iterIllum++;    // change illuminace
                        if(iterIllum==3){
                            illum++;
                            iterIllum=0;
                        }
                    }
                }

                if(mapTile[nX][nY]==0){ // void find
                    return illum;
                } else {
                    FlashTest.log(mapTile[nX][nY]+" "+i);
                }

            }
            return illum;
        }
    }
}

Class {
    class View extends Sprite {
        private var model:Model;
        private var controller:Controller;
        
        private var map:Bitmap;
        private var selectTile:Sprite;
        
        private var matrix:Matrix;
        
        private var clear:Sprite;
        
        public function View(aModel:Model, oController:Controller,
                                target:Stage){
            this.model = aModel;
            this.controller = oController;
            
            map = new Bitmap(new BitmapData(455, 455, true, 0xff000000));
            target.addChild(map);
            
            matrix = new Matrix();
            matrix.scale(2,2);
            
            clear = new Sprite();
            clear.graphics.beginFill(0);
            clear.graphics.drawRect(0,0,Model.tileSize,Model.tileSize);
            
            selectTile = new Sprite();
            selectTile.graphics.lineStyle(.5, 0xfffc91);
            selectTile.graphics.drawRect(0,0,Model.tileSize,Model.tileSize);
            target.addChild(selectTile);
            
            model.addEventListener(MapEvent.TILE_CHANGE, setNewViewTile);
            model.addEventListener(MapEvent.SELECT_CHANGE, setNewSelect);
            target.addEventListener(KeyboardEvent.KEY_DOWN, delegateController);    
        }
        private function delegateController(e:KeyboardEvent):void{
            controller.keyPress(e);
        }
        
        private function setNewViewTile(e:MapEvent):void{
            matrix.tx = selectTile.x;
            matrix.ty = selectTile.y;
            FlashTest.log('newX='+e.newX+' newY='+e.newY);
            // In this moment numState already calculate in Model
            if(e.newTile is Tile){
                map.bitmapData.draw(e.newTile.draw, matrix);
            } else { // clear
                map.bitmapData.draw(clear,matrix);
            }
            //FlashTest.log('tle state '+e.newTile.numState);
        }

        private function setNewSelect(e:MapEvent):void{
            selectTile.x = e.newX * Model.tileSize;
            selectTile.y = e.newY * Model.tileSize;
        }
    }
}

Class {
    class Controller {
        private var model:Model;
        
        private var kodesToId:Array = [49,50,51];    // keys 1,2,3
        // why keys... why id? maybe... tiles need put here?
        private var tilesToView:Array;
        
        public function Controller(aModel:Model, tilesToView:Array) {
            this.model = aModel;
            this.tilesToView = tilesToView;
        }
        public function keyPress(e:KeyboardEvent):void{
            switch(e.keyCode){
                case Keyboard.LEFT:
                   model.selectX--;             
                break;
                case Keyboard.RIGHT:
                    model.selectX++;
                break;
                case Keyboard.UP:
                    model.selectY--;
                break;
                case Keyboard.DOWN:
                    model.selectY++;
                break;
                default :
                    model.setSelectTile(tilesToView[getIdTile(e.keyCode)]);
                    FlashTest.log(e.keyCode);
                break;
            }
        }
        private function getIdTile(kode:uint):uint{
            for(var i:int=0; i<kodesToId.length; i++){
                if(kodesToId[i] == kode){
                    return i;
                }
            }
            return 0;
        }
    }
}

// help classes
Class {
    class MapEvent extends Event {
        public static const TILE_CHANGE:String = 'tileChange';
        public static const SELECT_CHANGE:String = 'selectChange';
        public var newTile:Tile;
        public var newX:int;
        public var newY:int;
        public function MapEvent(type:String, tile:Tile, x:int, y:int){
            newTile = tile;
            newX = x;
            newY = y;
            super(type);
        }
    }
}

Class {
    class MyLoader extends EventDispatcher {
        
        public static const ALL_LOADED:String = 'allLoaded';
        
        // No... this is bad decision. We must load ALL before init application.
        
        private var adresses:Array = ['glay_8_8.png','stone_8_8.png','soil_8_8.png']; // download all that is in this array    // Probably worth doing tileset...
        private var loaded:Array = [];    // put your all, considering the possible states
        
        private var loadedContents:Array = [];    // animate progress loading...
        private var loadSprite:Sprite = new Sprite();
        
        private var setFeedBack:View;
        private var lastId:uint = 0;
        
        private var stageLink:Stage;
        
        public function MyLoader(stageToLoad:Stage){
            stageLink = stageToLoad;
            stageLink.addChild(loadSprite);
            //loadSprite.graphics.lineStyle(1,0x75D07B);
            //loadSprite.graphics.drawRect(20,20,102,5);
            //loadAll();
        }
        
        public function loadAll():void{
            FlashTest.log('start load...');
            var nowAdress:String = '';
            var context:LoaderContext = new LoaderContext();
            context.checkPolicyFile = true;
            context.securityDomain = SecurityDomain.currentDomain;
            for(var i:int=0; i<adresses.length; i++ ){
                FlashTest.log('new adress num '+(i+1));
                nowAdress = adresses[i];
                var url:URLRequest = new URLRequest('http://cheshir.zabix.net/footlocker/'+nowAdress);
                var img:Loader = new Loader();
                img.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedBit);
                img.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressLoad);
                loadedContents.push(img.contentLoaderInfo);
                img.load(url, context);
            }
        }
        
        public function getLoaded():Array {
            if(loaded.length == adresses.length){
               return loaded; 
            }
            return [];
        }

        
        private function progressLoad(e:ProgressEvent):void{
            var percent:Number = 0;//(e.currentTarget as LoaderInfo).bytesLoaded / (e.currentTarget as LoaderInfo).bytesTotal * 100;
            var lX:Number = 20;
            var lY:Number = 20;
            loadSprite.graphics.clear();    // clear graphitcs before draw...
            for(var i:int=0; i < loadedContents.length; i++){
                percent = (loadedContents[i] as LoaderInfo).bytesLoaded /(loadedContents[i] as LoaderInfo).bytesTotal * 100;
                //FlashTest.log(percent);
                loadSprite.graphics.lineStyle(1,0x75D07B, 0.8); 
                loadSprite.graphics.drawRect(lX,lY,102,5);           
                loadSprite.graphics.lineStyle(0);
                loadSprite.graphics.beginFill(0x9DD075,0.8);
                loadSprite.graphics.drawRect(lX+1,lY+1,percent,3);
                //FlashTest.log((lX+1)+' '+(lY+1)+' '+percent);
                lY += 12;
            }
        }

        
        private function loadedBit(e:Event):void{
            var bitmap:Bitmap = e.target.content;
            var nTile:Tile = new Tile(bitmap.bitmapData,8);
            loaded.push(nTile);
           // FlashTest.log('total loaded '+loaded.length+' bitmaps');
            //setFeedBack.setNewViewTileAfterLoad(bitmap.bitmapData);
            if(loaded.length == adresses.length){
                loadSprite.graphics.clear();    // it clear graphics if all is loaded... and...
                FlashTest.log('can I dispatch?');
                dispatchEvent(new Event(MyLoader.ALL_LOADED,true)); // why not?
            }

        }
    }
}
Class {
    class Tile {
        
        private var drawMe:Bitmap;
        private var firstBitData:BitmapData;
        private var stateMatrix:Matrix;
        private var numStates:uint = 1;
        private var currentState:uint = 0;
        private var wh:Number = 0;
       
        public function Tile(bitmapData:BitmapData, sizePix:Number) {
            firstBitData = bitmapData;
            stateMatrix = new Matrix();
            numStates = uint(bitmapData.width/sizePix);
            FlashTest.log('new Tile numStates ='+numStates);
            wh = sizePix;
            var drawable:BitmapData = new BitmapData(sizePix,sizePix,true,0);
            drawable.draw(bitmapData,stateMatrix);
            drawMe = new Bitmap(drawable);
        }
        public function set numState(n:uint):void{
            if(n>this.numStates){
                n = 0;
            }
            this.currentState = n;
            stateMatrix.tx = -this.wh * n;    // only horizontal states // okey... mistake was here...
            drawMe.bitmapData.draw(firstBitData,stateMatrix);
        }
        public function get numState():uint {
            return this.currentState;
        }
        public function get draw():Bitmap{    // only read
            return drawMe;
        }


    }
}

Forked