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: DRO 2

Get Adobe Flash player
by sigLo0o0 01 Sep 2011
/**
 * Copyright sigLo0o0 ( http://wonderfl.net/user/sigLo0o0 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jYpd
 */

// forked from bc.hilldan's DRO 2
/**
 * Copyright bc.hilldan ( http://wonderfl.net/user/bc.hilldan )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/96s8
 */

/**
Byrono
 */
package {
    import com.bit101.components.ProgressBar;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.filters.GlowFilter;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import net.user1.reactor.ReactorEvent;
    import net.wonderfl.utils.FontLoader;
    import flash.display.LoaderInfo;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.system.Security;
        import flash.text.TextField;
    import flash.text.TextFieldType;
      import com.bit101.components.PushButton;
        import com.bit101.components.*;
          import flash.events.*;
          import net.user1.reactor.IClient;
    
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0x000000")]
    public class Main extends Sprite {
        private var _union:Union;              
        private var _screen:BitmapData;        
        private var _hud:HUD;                   
        private var _player:Player;             
        private var _occupants:OccupantManager; 
        private var _bullets:BulletManager;     
        private var _effects:EffectManager;    
        private var _isPlaying:Boolean;
         public var greeting:TextField = createInputText(132, 400, 200, 30);
         public var bob:Boolean;
  
        public function Main() {

            _union = new Union();
            _union.reactor.addEventListener(ReactorEvent.READY, onLoaded);
            _union.reactor.addEventListener(ReactorEvent.CLOSE, function(event:ReactorEvent):void {
                addChild(new TextBuilder().align(TextBuilder.CENTER).autoSize()
                    .filters([new GlowFilter(0x000000, 1, 8, 8)])
                    .font(Const.FONT, 0, 400).fontColor(0xFF0000).fontSize(40)
                    .size(465, 465).build("Connection Lost")
                );
            });
            
            _union.reactor.connect("tryunion.com", 80);
            trace("Connected");
            //adguasdhaskjdfhaskjdfhaksjldhfkjas
            
            var asshimar:Loader = new Loader();
            asshimar.contentLoaderInfo.addEventListener(Event.INIT, onLoaded);
            asshimar.load(new URLRequest("http://assets.wonderfl.net/images/related_images/b/b1/b1ce/b1ce584a1130c823fcd9cef7224f538b5b039563"), new LoaderContext(true));
            
            
            var instructions:Loader = new Loader();
            instructions.contentLoaderInfo.addEventListener(Event.INIT, onLoaded);
            instructions.load(new URLRequest("http://assets.wonderfl.net/images/related_images/1/1d/1da5/1da5c936e7265b2388c37538e0469be4ccde238e"), new LoaderContext(true));
            
            var fontLoader:FontLoader = new FontLoader();
            fontLoader.addEventListener(Event.COMPLETE, onLoaded);
            fontLoader.load(Const.FONT);
            
            var progressBar:ProgressBar = new ProgressBar(this, 182, 227);
            progressBar.maximum = 4;
            function onLoaded(event:Event):void {
                event.target.removeEventListener(event.type, arguments.callee);
                if (++progressBar.value == progressBar.maximum) { onAllLoaded(); }
            }
            function onAllLoaded():void {
                removeChild(progressBar);
                
                Assets.images["asshimar"] = Bitmap(asshimar.content).bitmapData;
                Assets.images["instructions"] = Bitmap(instructions.content).bitmapData;
                Assets.images["beam"] = Artist.createHexBeam();
                Assets.images["bg"] = Artist.createBackground();
                for (var i:int = 0; i < Const.EFFECT_EXPLOSION_KINDS; i++) {
                    Assets.images["explosion" + i] = Artist.createExplosion(Const.EFFECT_EXPLOSION_SIZE, i);
                }
               
                initialize();
                trace("Connected");
            }
        }
                public var kongregate:*;
        
        public function loadComplete(event:Event):void {
            kongregate = event.target.content;
            kongregate.services.connect();
        }
        
        public function getMainLoaderInfo():LoaderInfo {
            var loaderInfo:LoaderInfo = root.loaderInfo;
            if (loaderInfo.loader != null) {
                loaderInfo = loaderInfo.loader.loaderInfo;
            }
            return loaderInfo;
        }
        
        private function initialize():void {
            var paramObj:Object = getMainLoaderInfo().parameters;
            var apiPath:String = paramObj.kongregate_api_path || 
            "http://www.kongregate.com/flash/API_AS3_Local.swf";
            Security.allowDomain(apiPath);
            var request:URLRequest = new URLRequest(apiPath);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
            loader.load(request);
            addChild(loader);
            Input.initialize(stage);
            LogManager.initialize();
            
            _union.initialize(root);
            addChild(new Bitmap(_screen = new BitmapData(465, 465, true, 0xFF000000)));
            addChild(_hud = new HUD());
            _player = new Player(_union);
            _occupants = new OccupantManager(_union);
            _bullets = new BulletManager(_union);
            _effects = new EffectManager(_union);
            
            observeGame();
            addEventListener(Event.ENTER_FRAME, update);
             kongregate.stats.submit("score", 1);
        }
        
        private function observeGame():void {
            _isPlaying = false;
            _union.room.observe(_union.password);
            _union.room.leave();
            
            var title:Title = new Title(_union.reactor.self());
            addChild(title);
            title.addEventListener(Event.CLOSE, function(event:Event):void {
                event.target.removeEventListener(event.type, arguments.callee);
                removeChild(title);
                
                playGame();
            });
        }
        
        public function playGame():void {
            SaveData.nickname ||= "Guest" + _union.reactor.self().getClientID();
            _player.initialize();
            _occupants.addPlayer(_player);
            _bullets.initialize();
            stage.focus = null;   
            
            _union.room.join(_union.password);
            _union.room.stopObserving();
            _isPlaying = true;

        }
        


                public function createInputText(x:Number, y:Number, width:Number, maxchars:int):TextField {
            var result:TextField = new TextBuilder()
                .font(Const.FONT, -200).fontColor(0x000000).fontSize(12)
               .pos(x, y).size(width, 18).build("");
            result.background = result.mouseEnabled = result.selectable = true;
            result.backgroundColor = 0xFFFFFF;
            result.maxChars = maxchars;
            result.type = TextFieldType.INPUT;
            return result;
        }
        
        private function update(event:Event):void {
            if (!_union.reactor.isReady()) { return; }
            _union.reactor.self().setAttribute("t", "", null, false);
            var serverTime:Number = _union.reactor.getServer().getServerTime();
            if (_isPlaying) { _player.update(Math.atan2(mouseY - 232.5, mouseX - 232.5), serverTime); }
            
            _screen.lock();
            var bg:BitmapData = Assets.images["bg"];
            _screen.copyPixels(bg, bg.rect, Utils.getSharedPoint( -50 - _player.x % 50, -50 - _player.y % 50));
            _bullets.update(_player, _screen, serverTime);
            _occupants.update(_player, _screen);
            _effects.update(_player, _screen);
            _screen.unlock();
            
            _hud.update(_union.room.getOccupants());
            
            if (_isPlaying && !_player.isAlive) { observeGame(); }
        }
    }
}
/* ------------------------------------------------------------------------------------------------
 * Union
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.DisplayObject;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import net.user1.logger.Logger;
    import net.user1.reactor.Reactor;
    import net.user1.reactor.Room;
    import net.user1.reactor.RoomSettings;
    import net.wonderfl.utils.WonderflAPI;
    

    //public 
    class Union {
        private var _reactor:Reactor;
        private var _room:Room;
        private var _api:WonderflAPI;
        private var _synchronizer:Timer;
        
        public function Union() {
            _reactor = new Reactor();
            _reactor.getConnectionMonitor().sharePing(true);
            _reactor.getConnectionMonitor().setHeartbeatFrequency(500);
            _reactor.getConnectionMonitor().setConnectionTimeout(5000);
            _reactor.getLog().setLevel(Logger.FATAL);
        }
        
        public function initialize(root:DisplayObject):void {
            _api = new WonderflAPI(root.loaderInfo.parameters);
            var settings:RoomSettings = new RoomSettings();
            settings.removeOnEmpty = false;
            settings.password = this.password;
            _room = _reactor.getRoomManager().createRoom(String(_api.appID) + "_" + Const.ROOM_NO, settings);
            
            _synchronizer = new Timer(5000, 0);
            _synchronizer.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void {
                if (_reactor.isReady()) { _reactor.getServer().syncTime(); }
            });
            _synchronizer.start();
        }
        
        public function get reactor():Reactor { return _reactor; }
        public function get room():Room { return _room; }
        public function get password():String { return String(_api.apiKey); }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * IOccupant
 * ------------------------------------------------------------------------------------------------
 */
//package {

    //public 
    interface IOccupant {
        function move(x:Number, y:Number):void;
        function get x():Number;
        function get y():Number;
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Player
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.Point;
    import net.user1.reactor.IClient;
    

    //public 
    class Player implements IOccupant {
        private var _union:Union;
        
        private var _position:Point;
        private var _velocity:Point;
        private var _posSendCount:int;    
        private var _HPSendCount:int;   
        
        private var _hitpoint:int;
        private var _energy:int;
        private var _fireTimeCount:int;
        private var _uniqueIDForBullet:int;
        
        private var _killstreak:int;   
        private var _nemesisID:String;   
        
        public function Player(union:Union) {
            _union = union;
            _uniqueIDForBullet = 0;
            
            initialize();
            _hitpoint = 0;
            
            _union.room.addMessageListener(Const.MESSAGE_HIT_BULLET, hitBulletHandler);
            _union.room.addMessageListener(Const.MESSAGE_KILLSTREAK, killstreakHandler);
        }
        
        private function hitBulletHandler(from:IClient, ownerID:String, uniqueID:String, x:String, y:String, isFin:String):void {
            if (ownerID == _union.reactor.self().getClientID() && Boolean(isFin)) { 
                _killstreak++;
                if (_killstreak == 3 || _killstreak == 5 || _killstreak >= 10) {
                    _union.room.sendMessage(Const.MESSAGE_KILLSTREAK, true, null, String(_killstreak));
                }
            }
        }
        
        private function killstreakHandler(from:IClient, amount:String):void {
            var s:String = (from.isSelf()) ? "You have " : from.getAttribute("name") + " has ";
            LogManager.addLog(new Log(s + "a killstreak of " + amount + "!!", Const.LOG_COLOR_KILLSTREAK));
        }
        
        public function initialize():void {
            _position = new Point(Const.ARENA_SIZE * Math.random(), Const.ARENA_SIZE * Math.random());
            _velocity = new Point(0, 0);
            _posSendCount = _HPSendCount = 0;
            
            _hitpoint = Const.PLAYER_HP;
            _energy = Const.ENERGY_MAX;
            _fireTimeCount = 0;
            
            _killstreak = 0;
            _nemesisID = "";
            
            var client:IClient = _union.reactor.self();
            client.setAttribute("name", SaveData.nickname);
            client.setAttribute("posX", _position.x.toFixed(3));
            client.setAttribute("posY", _position.y.toFixed(3));
            client.setAttribute("angle", "0");
            client.setAttribute("HP", String(_hitpoint));
        }
        
        public function observeNemesis(x:Number, y:Number):void {
            _position.x = x;
            _position.y = y;
        }
        
        public function update(angle:Number, serverTime:Number):void {


            // 移動
            _velocity.x *= 0.99;
            _velocity.y *= 0.99;
            if (Input.isKeyDown(Input.W)||Input.isKeyDown(Input.UP)) { _velocity.y -= Const.PLAYER_ACCEL; }
            if (Input.isKeyDown(Input.S)||Input.isKeyDown(Input.DOWN)) { _velocity.y += Const.PLAYER_ACCEL; }
            if (Input.isKeyDown(Input.A)||Input.isKeyDown(Input.LEFT)) { _velocity.x -= Const.PLAYER_ACCEL; }
            if (Input.isKeyDown(Input.D)||Input.isKeyDown(Input.RIGHT)) { _velocity.x += Const.PLAYER_ACCEL; }
            if (Utils.calculateSqLength(_velocity) > Const.SQ_PLAYER_SPEED) { _velocity.normalize(Const.PLAYER_SPEED); }
            _position.x += _velocity.x;
            _position.y += _velocity.y;
            
            // カウントアップ
            if (_hitpoint < Const.PLAYER_HP && _velocity.length < Const.PLAYER_SPEED_RESTING) {
                _hitpoint++;
            }
            if (_energy < Const.ENERGY_MAX) { _energy++; }
            _fireTimeCount++;
            
            var client:IClient = _union.reactor.self();
            if (++_posSendCount >= Const.PLAYER_POS_SEND_INTERVAL) {
                _posSendCount = 0;
                var fixedPosX:String = _position.x.toFixed(3);
                var fixedPosY:String = _position.y.toFixed(3);
                var fixedAngle:String = angle.toFixed(2);
                if (client.getAttribute("posX") != fixedPosX) { client.setAttribute("posX", fixedPosX); }
                if (client.getAttribute("posY") != fixedPosY) { client.setAttribute("posY", fixedPosY); }
                if (client.getAttribute("angle") != fixedAngle) { client.setAttribute("angle", fixedAngle); }
            }
            if (++_HPSendCount >= Const.PLAYER_HP_SEND_INTERVAL) {
                _HPSendCount = 0;
                if (int(client.getAttribute("HP")) != _hitpoint) { client.setAttribute("HP", String(_hitpoint)); }
            }
            
            // 弾の発射
            if (Input.isMouseDown() && _energy >= Const.ENERGY_COST_PER_SHOT && _fireTimeCount >= Const.FIRE_TIME) {
                _energy -= Const.ENERGY_COST_PER_SHOT;
                _fireTimeCount = 0;
                
                _union.room.sendMessage(Const.MESSAGE_SHOOT_BULLET, true, null,
                    String(_uniqueIDForBullet++),
                    String(int(_position.x)), String(int(_position.y)),
                    String(angle.toFixed(2)), String(serverTime + Const.FIRE_DELAY)
                );
            }
        }
        
        public function damage(amount:int, bulletOwnerID:String):void {
            _hitpoint -= amount;
            if (_hitpoint <= 0) { _hitpoint = 0; }
            _nemesisID = bulletOwnerID;
        }
        
        public function move(x:Number, y:Number):void { }
        
        public function get x():Number { return _position.x; }
        public function get y():Number { return _position.y; }
        public function get isAlive():Boolean { return _hitpoint > 0; }
        public function get energy():Number { return _energy; }
        public function get nemesisID():String { return _nemesisID; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Occupant
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.Point;
    

    //public 
    class Occupant implements IOccupant {
        private var _currentPosition:Point;      
        private var _averageVelocity:Point;   
        private var _attributePosition:Point;  
        private var _predictivePosition:Point;  
        private var _predictiveVelocity:Point;    
        
        public function Occupant(x:Number, y:Number) {
            _currentPosition = new Point(x, y);
            _averageVelocity = new Point(0, 0);
            _attributePosition = new Point(x, y);
            _predictivePosition = new Point(x, y);
            _predictiveVelocity = new Point(0, 0);
        }
        
        public function move(x:Number, y:Number):void {
            if (_attributePosition.x != x || _attributePosition.y != y) {
    
                _predictiveVelocity.x = (x - _attributePosition.x) / Const.PLAYER_POS_SEND_INTERVAL;
                _predictiveVelocity.y = (y - _attributePosition.y) / Const.PLAYER_POS_SEND_INTERVAL;
                if (Utils.calculateSqLength(_predictiveVelocity) > Const.SQ_OCCUPANT_PRED_SPEED) { _predictiveVelocity.normalize(Const.OCCUPANT_PRED_SPEED); }
                
                _attributePosition.x = _predictivePosition.x = x;
                _attributePosition.y = _predictivePosition.y = y;
            }
            
         
            var currentVelocity:Point = Utils.getSharedPoint(
                (_predictivePosition.x - _currentPosition.x) / Const.PLAYER_POS_SEND_INTERVAL,
                (_predictivePosition.y - _currentPosition.y) / Const.PLAYER_POS_SEND_INTERVAL
            );
            if (Utils.calculateSqLength(currentVelocity) > Const.SQ_OCCUPANT_SPEED) { currentVelocity.normalize(Const.OCCUPANT_SPEED); }
            _averageVelocity.x = (_averageVelocity.x + currentVelocity.x) / 2;
            _averageVelocity.y = (_averageVelocity.y + currentVelocity.y) / 2;
            
            _currentPosition.x += _averageVelocity.x;
            _currentPosition.y += _averageVelocity.y;
            _predictivePosition.x += _predictiveVelocity.x;
            _predictivePosition.y += _predictiveVelocity.y;
        }
        
        public function get x():Number { return _currentPosition.x; }
        public function get y():Number { return _currentPosition.y; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * OccupantManager
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.utils.Dictionary;
    import net.user1.reactor.IClient;
    import net.user1.reactor.RoomEvent;
    

    //public 
    class OccupantManager {
        private var _union:Union;
        private var _map:Dictionary;
        
        private var _occupantNameLabel:TextField;
        
        public function OccupantManager(union:Union) {
            _union = union;
            _map = new Dictionary();
            _occupantNameLabel = 
                new TextBuilder().align(TextBuilder.CENTER).autoSize()
                .font(Const.FONT, -400).fontColor(0xFFFFFF).fontSize(10)
                .size(48, 12).build("Unknown");
            
            _union.room.addEventListener(RoomEvent.ADD_OCCUPANT, addOccupantHandler);
            _union.room.addEventListener(RoomEvent.REMOVE_OCCUPANT, removeOccupantHandler);
        }
        
        private function addOccupantHandler(event:RoomEvent):void {
            var client:IClient = event.getClient();

            if (!client.isSelf()) {
                _map[client.getClientID()] = new Occupant(
                    Number(client.getAttribute("posX")),
                    Number(client.getAttribute("posY"))
                );
            }
            
    
            var message:String = client.getAttribute("message");
            if (message) { LogManager.addLog(new Log(client.getAttribute("name") + " : " + message, Const.LOG_COLOR_NORMAL)); }
            
            LogManager.addLog(new Log(
                ((client.isSelf()) ? "You have " : client.getAttribute("name") + " has ") + "joined the game.",
                Const.LOG_COLOR_NORMAL
            ));
            


        }
        
        private function removeOccupantHandler(event:RoomEvent):void {
            var client:IClient = event.getClient();
            delete _map[client.getClientID()];
            
            LogManager.addLog(new Log(
                ((client.isSelf()) ? "You have " : client.getAttribute("name") + " has ") + "left the game.",
                Const.LOG_COLOR_NORMAL
            ));
        }
        
        public function update(player:Player, screen:BitmapData):void {
            var client:IClient;
            

            for each(client in _union.room.getOccupants()) {
                _map[client.getClientID()].move(Number(client.getAttribute("posX")), Number(client.getAttribute("posY")));
            }
            
    
            if (!player.isAlive) {
                var nemesis:IOccupant = _map[player.nemesisID];
                if (nemesis) { player.observeNemesis(nemesis.x, nemesis.y); }
            }
            
 
            for each(client in _union.room.getOccupants()) {
                var occupant:IOccupant = _map[client.getClientID()];
                var relativeX:Number = Utils.normalizeComponent(occupant.x - player.x);
                var relativeY:Number = Utils.normalizeComponent(occupant.y - player.y);
                if (Math.abs(relativeX) < 256.5 && Math.abs(relativeY) < 256.5) {
            
                    var matrix:Matrix = Utils.getSharedMatrix(1, 0, 0, 1, -24, -24);
                    matrix.rotate(Number(client.getAttribute("angle")));
                    matrix.translate(relativeX + 232.5, relativeY + 232.5);
                    screen.draw(Assets.images["asshimar"], matrix, null, null, null, true);
                    
        
                    _occupantNameLabel.text = client.getAttribute("name");
                    screen.draw(_occupantNameLabel, Utils.getSharedMatrix(1, 0, 0, 1, relativeX + 208.5, relativeY + 196.5), null, null, null, true);
                    
     
                    var rect:Rectangle = Utils.getSharedRectangle(relativeX + 208.5, relativeY + 256.5, 48, 2);
                    screen.fillRect(rect, 0xFFFF0000);
                    rect.width = Number(client.getAttribute("HP")) * Const.HP_GAUGE_WIDTH_PER_ONE;
                    screen.fillRect(rect, 0xFF00FF00);
                }
            }
            
       
            if (player.isAlive) {
                rect = Utils.getSharedRectangle(208.5, 259.5, 48, 2);
                screen.fillRect(rect, 0xFF000941);
                rect.width = player.energy * Const.EN_GAUGE_WIDTH_PER_ONE;
                screen.fillRect(rect, 0xFF3350FF);
            }
        }
        
        public function addPlayer(player:Player):void { _map[_union.reactor.self().getClientID()] = player; }
        public function getNemesis(clientID:String):IOccupant { return _map[clientID]; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Bullet
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.Point;
    

    //public 
    class Bullet {
        private var _ownerID:String;        
        private var _uniqueID:String;       
        private var _currentPosition:Point; 
        private var _oldPosition:Point;     
        private var _angle:Number;       
        private var _velocityPerMS:Point;   
        
        private var _spawnPosition:Point;   
        private var _spawnTime:Number;      
        private var _exists:Boolean;       
        
        public function Bullet(ownerID:String, uniqueID:String, x:Number, y:Number, angle:Number, spawnTime:Number) {
            _ownerID = ownerID;
            _uniqueID = uniqueID;
            _currentPosition = new Point(x, y);
            _oldPosition = new Point(x, y);
            _angle = angle;
            _velocityPerMS = new Point(
                Const.BULLET_SPEED_PER_SEC * Math.cos(_angle) / 1000,
                Const.BULLET_SPEED_PER_SEC * Math.sin(_angle) / 1000
            );
            _spawnPosition = new Point(x, y);
            _spawnTime = spawnTime;
            _exists = true;
        }
        
        public function move(serverTime:Number):void {
            var elapsed:Number = Math.max(0, serverTime - _spawnTime);
            if (elapsed > Const.BULLET_LIFE) { _exists = false; }
            
            _oldPosition.x = _currentPosition.x;
            _oldPosition.y = _currentPosition.y;
            _currentPosition.x = elapsed * _velocityPerMS.x + _spawnPosition.x;
            _currentPosition.y = elapsed * _velocityPerMS.y + _spawnPosition.y;
        }
        
        public function get ownerID():String { return _ownerID; }
        public function get uniqueID():String { return _uniqueID; }
        public function get x():Number { return _currentPosition.x; }
        public function get y():Number { return _currentPosition.y; }
        public function get oldX():Number { return _oldPosition.x; }
        public function get oldY():Number { return _oldPosition.y; }
        public function get angle():Number { return _angle; }
        public function get exists():Boolean { return _exists; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * BulletManager
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.utils.Dictionary;
    import net.user1.reactor.IClient;
    
 
    //public 
    class BulletManager {
        private var _union:Union;
        private var _map:Dictionary;
        
        public function BulletManager(union:Union) {
            _union = union;
            initialize();
            
            _union.room.addMessageListener(Const.MESSAGE_SHOOT_BULLET, shootBulletHandler);
            _union.room.addMessageListener(Const.MESSAGE_HIT_BULLET, hitBulletHandler);
        }
        
        private function shootBulletHandler(from:IClient, uniqueID:String, x:String, y:String, angle:String, spawnTime:String):void {
            _map[from.getClientID() + "_" + uniqueID] = new Bullet(from.getClientID(), uniqueID, Number(x), Number(y), Number(angle), Number(spawnTime));
        }
        
        private function hitBulletHandler(from:IClient, ownerID:String, uniqueID:String, x:String, y:String, isFin:String):void {
            var bulletID:String = ownerID + "_" + uniqueID;
            if (_map[bulletID]) { delete _map[bulletID]; }
            
            var isOwnBullet:Boolean = (ownerID == _union.reactor.self().getClientID());
  
            var ownerClient:IClient = _union.room.getClient(ownerID);
            var ownerName:String = (ownerClient) ? ownerClient.getAttribute("name") : "Unknown"; 
            
            if (isOwnBullet) { LogManager.addLog(new Log("You hit " + from.getAttribute("name") + ".", Const.LOG_COLOR_GOOD)); }
            if (from.isSelf()) { LogManager.addLog(new Log(ownerName + " hit you.", Const.LOG_COLOR_BAD)); }
            

            if (Boolean(isFin)) {
                var s:String = (isOwnBullet) ? "You" : ownerName;
                var o:String = (from.isSelf()) ? "you" : from.getAttribute("name");
                var color:uint = (isOwnBullet) ? Const.LOG_COLOR_BEST : (from.isSelf()) ? Const.LOG_COLOR_WORST : Const.LOG_COLOR_OTHER;
                LogManager.addLog(new Log(s + " defeated " + o + "!", color));
            }
        }
        
        public function initialize():void {
            _map = new Dictionary();
        }
        
        public function update(player:Player, screen:BitmapData, severTime:Number):void {
            for each(var bullet:Bullet in _map) {
                bullet.move(severTime);
                
             
                if (!bullet.exists) {
                    delete _map[bullet.ownerID + "_" + bullet.uniqueID];
                    continue;
                }
                
     
                var relativeX:Number = Utils.normalizeComponent(bullet.x - player.x);
                var relativeY:Number = Utils.normalizeComponent(bullet.y - player.y);
                if (Math.abs(relativeX) < 244.5 && Math.abs(relativeY) < 244.5) {
           
                    var matrix:Matrix = Utils.getSharedMatrix(1, 0, 0, 1, -12, -12);
                    matrix.rotate(bullet.angle);
                    matrix.translate(relativeX + 232.5, relativeY + 232.5);
                    screen.draw(Assets.images["beam"], matrix, null, BlendMode.ADD, null, true);
                    
   
                    if (!player.isAlive || bullet.ownerID == _union.reactor.self().getClientID()) { continue; }
                    var relativeOldX:Number = Utils.normalizeComponent(bullet.oldX - player.x);
                    var relativeOldY:Number = Utils.normalizeComponent(bullet.oldY - player.y);
 
                    var diffX:Number = relativeX - relativeOldX;
                    var diffY:Number = relativeY - relativeOldY;
                    if ((diffX * diffX + diffY * diffY) > Const.SQ_BULLET_INVALID_SPEED) { continue; }
                    
            
                    var closestPoint:Point = Utils.getClosestSharedPointOnSegmentToOrigin(relativeOldX, relativeOldY, relativeX, relativeY);
           
                    if ((closestPoint.x * closestPoint.x + closestPoint.y * closestPoint.y) <= Const.SQ_RADIUS_SUM) {
                        player.damage(Const.BULLET_POWER, bullet.ownerID);
                        delete _map[bullet.ownerID + "_" + bullet.uniqueID];
                        
                        _union.room.sendMessage(Const.MESSAGE_HIT_BULLET, true, null,
                            bullet.ownerID, bullet.uniqueID,
                            String(int(player.x + closestPoint.x)), String(int(player.y + closestPoint.y)),
                            String((!player.isAlive) ? "t" : "")   
                        );
                    }
                }
            }
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * IEffect
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    

    //public 
    interface IEffect {
        function update():void;
        function get x():Number;
        function get y():Number;
        function get radius():Number;
        function get imageName():String;
        function get matrix():Matrix;
        function get colorTransform():ColorTransform;
        function get exists():Boolean;
    }
//}
/* ------------------------------------------------------------------------------------------------
 * ExplosionEffect
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    
   
    //public 
    class ExplosionEffect implements IEffect {
        private var _position:Point;
        private var _imageName:String;
        private var _matrix:Matrix;
        private var _colorTrans:ColorTransform;
        private var _life:int;
        
        private var _scale:Number;
        private var _colorMultiplier:Number;
        private var _colorOffset:Number;
        
        public function ExplosionEffect(x:Number, y:Number) {
            _position = new Point(x + (24 * Math.random() - 12), y + (24 * Math.random() - 12));
            _imageName = "explosion" + int(Const.EFFECT_EXPLOSION_KINDS * Math.random());
            _matrix = new Matrix();
            _colorTrans = new ColorTransform();
            _life = 30;
            
            _scale = 0.5;
            _colorMultiplier = 1;
            _colorOffset = 50;
        }
        
        public function update():void {
            _life--;
            _scale = Math.min(_scale + 0.1, 1);
            _colorMultiplier -= 0.02;
            _colorOffset -= 10;
            
            _matrix.identity();
            _matrix.translate( -Const.EFFECT_EXPLOSION_HALF_SIZE, -Const.EFFECT_EXPLOSION_HALF_SIZE);
            _matrix.scale(_scale, _scale);
            
            _colorTrans.redMultiplier = _colorTrans.greenMultiplier = _colorTrans.blueMultiplier = _colorMultiplier;
            _colorTrans.alphaMultiplier = _life / 30;
            _colorTrans.redOffset = _colorTrans.greenOffset = _colorTrans.blueOffset = _colorOffset;
        }
        
        public function get x():Number { return _position.x; }
        public function get y():Number { return _position.y; }
        public function get radius():Number { return Const.EFFECT_EXPLOSION_HALF_SIZE; }
        public function get imageName():String { return _imageName; }
        public function get matrix():Matrix { return _matrix; }
        public function get colorTransform():ColorTransform { return _colorTrans; }
        public function get exists():Boolean { return _life > 0; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * EffectManager
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.geom.Matrix;
    import net.user1.reactor.IClient;
    
 
    //public 
    class EffectManager {
        private var _union:Union;
        private var _list:Vector.<IEffect>;
        
        public function EffectManager(union:Union) {
            _union = union;
            _list = new Vector.<IEffect>();
            
            _union.room.addMessageListener(Const.MESSAGE_HIT_BULLET, hitBulletHandler);
        }
        
        private function hitBulletHandler(from:IClient, ownerID:String, uniqueID:String, x:String, y:String, isFin:String):void {
            _list.push(new ExplosionEffect(Number(x), Number(y)));
        }
        
        public function update(player:Player, screen:BitmapData):void {
            for (var i:int = _list.length - 1; i >= 0; i--) {
                var effect:IEffect = _list[i];
                effect.update();
                
        
                if (!effect.exists) {
                    _list.splice(i, 1);
                    continue;
                }
                
            
                var relativeX:Number = Utils.normalizeComponent(effect.x - player.x);
                var relativeY:Number = Utils.normalizeComponent(effect.y - player.y);
                var distToBounds:Number = 232.5 + effect.radius;
                if (Math.abs(relativeX) < distToBounds && Math.abs(relativeY) < distToBounds) {
                    var matrix:Matrix = effect.matrix;
                    matrix = Utils.getSharedMatrix(
                        matrix.a, matrix.b, matrix.c, matrix.d, 
                        matrix.tx + relativeX + 232.5, 
                        matrix.ty + relativeY + 232.5
                    );
                    screen.draw(Assets.images[effect.imageName], matrix, effect.colorTransform, BlendMode.SCREEN, null, true);
                }
            }
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Log
 * ------------------------------------------------------------------------------------------------
 */
//package {
 
    //public 
    class Log {
        private var _text:String;
        private var _color:uint;
        
        public function Log(text:String, color:uint) {
            _text = text;
            _color = color;
        }
        
        public function get text():String { return _text; }
        public function get color():uint { return _color; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * LogManager
 * ------------------------------------------------------------------------------------------------
 */
//package {    
 
    //public 
    class LogManager {
        private static var _logList:Vector.<Log> = new Vector.<Log>();
        
        public static function initialize():void {
            for (var i:int = 0; i < Const.LOG_MAX_LENGTH; i++) {
                _logList[i] = new Log("", 0x000000);
            }
        }
        
        public static function getLog(index:int):Log { return _logList[index]; }
        public static function addLog(log:Log):void {
            _logList.push(log);
            if (_logList.length > Const.LOG_MAX_LENGTH) { _logList.shift(); }
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * HUD
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.filters.GlowFilter;
    import flash.text.TextField;
    import net.user1.reactor.IClient;
    
  
    //public 
    class HUD extends Sprite {
        private var _radar:BitmapData;
        private var _logDisplays:Vector.<TextField>;
        
        public function HUD() {
      
            var radarBitmap:Bitmap = new Bitmap(_radar = new BitmapData(Const.RADAR_SIZE, Const.RADAR_SIZE, true, 0x00FFFFFF));
            radarBitmap.x = 465 - _radar.width;
            addChild(radarBitmap);
            
      
            _logDisplays = new Vector.<TextField>(Const.LOG_MAX_LENGTH, true);
            var builder:TextBuilder = 
                new TextBuilder().align(TextBuilder.LEFT).autoSize()
                .filters([new GlowFilter(0x000000, 1, 4, 4)])
                .font(Const.FONT, -400).fontSize(10).size(100, 12);
            for (var i:int = 0; i < Const.LOG_MAX_LENGTH; i++) {
                var log:Log = LogManager.getLog(i);
                addChild(_logDisplays[i] = builder.fontColor(log.color).pos(0, 455 - ((Const.LOG_MAX_LENGTH - i) * 12)).build(log.text));
                _logDisplays[i].alpha = (i + 3) / Const.LOG_MAX_LENGTH;
            }
        }
        
        public function update(clients:Array):void {
         
            _radar.lock();
            _radar.fillRect(_radar.rect, 0x80808080);
            for each(var client:IClient in clients) {
                var radarPosX:int = (Utils.normalizeComponent(Number(client.getAttribute("posX"))) + Const.ARENA_HALF_SIZE) * Const.RADAR_SCALE;
                var radarPosY:int = (Utils.normalizeComponent(Number(client.getAttribute("posY"))) + Const.ARENA_HALF_SIZE) * Const.RADAR_SCALE;
                var color:uint = (client.isSelf()) ? 0xFFFFFFFF : 0xFFFF0000;
                _radar.fillRect(Utils.getSharedRectangle(radarPosX - 1, radarPosY - 1, 2, 2), color);
            }
            _radar.unlock();
            
         
            for (var i:int = 0; i < Const.LOG_MAX_LENGTH; i++) {
                var log:Log = LogManager.getLog(i);
                var logDisplay:TextField = _logDisplays[i];
                
                logDisplay.text = log.text;
                logDisplay.textColor = log.color;
            }
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Title
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import com.bit101.components.PushButton;
        import com.bit101.components.*;
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.net.*;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.GlowFilter;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import net.user1.reactor.IClient;
    
    [Event(name = "close", type = "flash.events.Event")]
  
    //public 
    class Title extends Sprite {
         public var bob:Boolean;
        
      
        
        public function Title(client:IClient) {
            graphics.beginFill(0x000000, 0.3);
            graphics.drawRect(0, 0, 465, 465);
            graphics.endFill();
            
         
            var builder:TextBuilder = new TextBuilder().align(TextBuilder.CENTER).autoSize().fontColor(0xFFFFFF);
            addChild(builder.font(Const.FONT, 0, 400).fontSize(24).pos(132, 140).size(200, 30).build("Darkness Realm Online"));
            addChild(builder.font(Const.FONT).fontSize(13).pos(132, 170).size(200, 15).build("A Multiplayer Shooter"));

                   
            
         
            addChild(new TextBuilder().font(Const.FONT).fontColor(0xFFFFFF).fontSize(12).pos(132, 222).size(100, 20).build("Nickname"));
            var nickname:TextField = createInputText(202, 222, 130, 12);
            nickname.text = SaveData.nickname;
            nickname.addEventListener(Event.CHANGE, function(event:Event):void {
                SaveData.nickname = nickname.text;
            });
            addChild(nickname);
            
            // test
            //addChild(new TextBuilder().font(Const.FONT).fontColor(0xFFFFFF).fontSize(12).pos(132, 242).size(200, 20).build("Message (optional)"));
            var greeting:TextField = createInputText(132, 400, 200, 30);
           //addChild(greeting);
                      new PushButton(this,200, 400, "Chat", function(event:MouseEvent):void {
           
                client.setAttribute("message", greeting.text);
          

           });
            if(bob == true){
                client.setAttribute("message", greeting.text);
            }

            
          
            new PushButton(this, 180, 260, "Play", function(event:MouseEvent):void {
                event.target.removeEventListener(event.type, arguments.callee);
                //client.setAttribute("message", greeting.text);
                dispatchEvent(new Event(Event.CLOSE));

            });
            
          
            var instructions:Bitmap = new Bitmap(Assets.images["instructions"]);
            instructions.x = int((465 - instructions.width) / 2);
            instructions.y = int(420 - instructions.height);
            addChild(instructions);
            addChild(
                new TextBuilder().align(TextBuilder.CENTER).autoSize()
                .filters([new GlowFilter(0x000000, 1, 4, 4, 8)])
                .font(Const.FONT).fontColor(0xFFFFFF).fontSize(12)
                .pos(0, 430).size(465, 15)
                .build(Const.HINTS[int(Const.HINTS.length * Math.random())])
            );
            
          
            addChild(
                new TextBuilder().align(TextBuilder.RIGHT)
                .font(Const.FONT, 0, -400).fontColor(0xFFFFFF).fontSize(10)
                .pos(360, 445).size(100, 20).build(Const.VERSION)
            );
            addChild(
                new TextBuilder().align(TextBuilder.LEFT)
                .font(Const.FONT, 0, -400).fontColor(0xFFFFFF).fontSize(10)
                .pos(0, 445).size(100, 20).build("A Byrono Production")
            );
        }
        
        public function createInputText(x:Number, y:Number, width:Number, maxchars:int):TextField {
            var result:TextField = new TextBuilder()
                .font(Const.FONT, -200).fontColor(0x000000).fontSize(12)
                .pos(x, y).size(width, 18).build("");
            result.background = result.mouseEnabled = result.selectable = true;
            result.backgroundColor = 0xFFFFFF;
            result.maxChars = maxchars;
            result.type = TextFieldType.INPUT;
            return result;
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Assets
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.utils.Dictionary;
    
   
    //public 
    class Assets {
        public static var images:Dictionary = new Dictionary();
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Artist
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.GradientType;
    import flash.display.Sprite;
    import flash.filters.BitmapFilter;
    import flash.filters.DisplacementMapFilter;
    import flash.filters.DisplacementMapFilterMode;
    import flash.filters.GlowFilter;
    import flash.geom.Matrix;
    import flash.geom.Point;
    
  
    //public 
    class Artist {
        
        /** ビーム画像を生成します。 */
        public static function createHexBeam():BitmapData {
            var sp:Sprite = new Sprite();
            var verticesX:Array = [ -3, 3, 8, 3, -3, -8];
            var verticesY:Array = [ -3, -3, 0, 3, 3, 0];
            sp.graphics.beginFill(0xFFFFFF);
            sp.graphics.moveTo(verticesX[5], verticesY[5]);
            for (var i:int = 0; i < 6; i++) { sp.graphics.lineTo(verticesX[i], verticesY[i]); }
            sp.graphics.endFill();
            sp.filters = [new GlowFilter(0xFF0000, 1, 8, 0)];
            
            var result:BitmapData = new BitmapData(24, 24, true, 0x00FFFFFF);
            result.draw(sp, new Matrix(1, 0, 0, 1, 12, 12));
            return result;
        }
        

        public static function createBackground():BitmapData {
            var sp:Sprite = new Sprite();
            sp.graphics.lineStyle(0, 0x006600);
            for (var i:int = 0; i < 600; i += 50) {
                sp.graphics.moveTo(i, 0);
                sp.graphics.lineTo(i, 600);
                sp.graphics.moveTo(0, i);
                sp.graphics.lineTo(600, i);
            }
            
            var result:BitmapData = new BitmapData(600, 600, true, 0xFF000000);
            result.draw(sp);
            return result;
        }
        
        
        public static function createExplosion(size:int, seed:int):BitmapData {
            var result:BitmapData = new BitmapData(size, size, true, 0x00FFFFFF);
            
   
            var base:Number = size / 3;
            var noise:BitmapData = result.clone(); 
            noise.perlinNoise(base, base, 4, seed, false, false, BitmapDataChannel.RED | BitmapDataChannel.GREEN);
            var scale:Number = size / 3;
            var filter:BitmapFilter = new DisplacementMapFilter(noise, new Point(), BitmapDataChannel.RED, BitmapDataChannel.GREEN, scale, scale, DisplacementMapFilterMode.CLAMP);
            
          
            var offset:Number = scale / 2;
            var spSize:Number = size - scale;
            var sp:Sprite = new Sprite();
            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(spSize, spSize, 0, offset, offset);
            sp.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFDD99, 0xFFBB33, 0xCC0000, 0x660000], [1, 1, 1, 1, 0], [32, 96, 160, 224, 255], matrix);
            sp.graphics.drawRect(offset, offset, spSize, spSize);
            sp.graphics.endFill();
            
        
            result.draw(sp);
            result.applyFilter(result, result.rect, new Point(), filter);
            return result;
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Input
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Stage;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    
   
    //public 
    class Input {
        private static var _isKeyDown:Vector.<Boolean> = new Vector.<Boolean>(256, true);
        private static var _isMouseDown:Boolean = false;
        
        public static const W:uint = 87;
        public static const A:uint = 65;
        public static const S:uint = 83;
        public static const D:uint = 68;
         public static const UP:uint = 38;
        public static const LEFT:uint = 37;
        public static const DOWN:uint = 40;
        public static const RIGHT:uint = 39;
        
        public static function initialize(stage:Stage):void {
            stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
                _isKeyDown[event.keyCode] = true;
            });
            stage.addEventListener(KeyboardEvent.KEY_UP, function(event:KeyboardEvent):void { 
                _isKeyDown[event.keyCode] = false;
            });
            stage.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void {
                _isMouseDown = true;
            });
            stage.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void {
                _isMouseDown = false;
            });
        }
        
        public static function isKeyDown(keyCode:uint):Boolean { return _isKeyDown[keyCode]; }
        public static function isMouseDown():Boolean { return _isMouseDown; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Utils
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    
   
    //public 
    class Utils {
        private static var _sharedMatrix:Matrix = new Matrix();
        private static var _sharedPoint:Point = new Point();
        private static var _sharedRectangle:Rectangle = new Rectangle();
        
   
        public static function getSharedMatrix(a:Number = 1, b:Number = 0, c:Number = 0, d:Number = 1, tx:Number = 0, ty:Number = 0):Matrix {
            _sharedMatrix.a = a;
            _sharedMatrix.b = b;
            _sharedMatrix.c = c;
            _sharedMatrix.d = d;
            _sharedMatrix.tx = tx;
            _sharedMatrix.ty = ty;
            return _sharedMatrix;
        }
        
    
        public static function getSharedPoint(x:Number, y:Number):Point {
            _sharedPoint.x = x;
            _sharedPoint.y = y;
            return _sharedPoint;
        }
        
    
        public static function getSharedRectangle(x:Number, y:Number, width:Number, height:Number):Rectangle {
            _sharedRectangle.x = x;
            _sharedRectangle.y = y;
            _sharedRectangle.width = width;
            _sharedRectangle.height = height;
            return _sharedRectangle;
        }
        
     
        public static function normalizeComponent(component:Number):Number {
            component %= Const.ARENA_SIZE;
            if (component < -Const.ARENA_HALF_SIZE) {
                component += Const.ARENA_SIZE;
            }else if (component > Const.ARENA_HALF_SIZE) {
                component -= Const.ARENA_SIZE;
            }
            return component;
        }
        
   
        public static function calculateSqLength(point:Point):Number {
            return point.x * point.x + point.y * point.y;
        }
        
   
        public static function getClosestSharedPointOnSegmentToOrigin(startX:Number, startY:Number, endX:Number, endY:Number):Point {
            var startToEnd:Point = Utils.getSharedPoint(endX - startX, endY - startY);
            var t:Number = (( -startX * startToEnd.x) + ( -startY * startToEnd.y)) / (startToEnd.x * startToEnd.x + startToEnd.y * startToEnd.y);
            t = Math.min(Math.max(0, t), 1);
            // s + (so.se / se.se)se
            return Utils.getSharedPoint(startX + t * startToEnd.x, startY + t * startToEnd.y);
        }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * SaveData
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.net.SharedObject;
    

    //public 
    class SaveData {
        private static var _sharedObject:SharedObject = SharedObject.getLocal("Byrono");
        
        public static function get nickname():String { return _sharedObject.data.nickname || ""; }
        public static function set nickname(value:String):void { _sharedObject.data.nickname = value; }
    }
//}
/* ------------------------------------------------------------------------------------------------
 * Const
 * ------------------------------------------------------------------------------------------------
 */
//package {
  
    //public 
    class Const {
        
        public static const ARENA_SIZE:int = 1500;    
        
        public static const PLAYER_HP:int = 2000;    
        public static const PLAYER_SPEED:Number = 3;    
        public static const PLAYER_ACCEL:Number = 0.2;   
        public static const PLAYER_RADIUS:int = 16;    
        public static const PLAYER_SPEED_RESTING:Number = 1;    
        public static const PLAYER_POS_SEND_INTERVAL:int = 4;    
        public static const PLAYER_HP_SEND_INTERVAL:int = 20;   
        
        public static const ENERGY_MAX:int = 200;    
        public static const ENERGY_COST_PER_SHOT:int = 15;    

        public static const FIRE_TIME:int = 6;    
        public static const FIRE_DELAY:int = 150;    //milliseconds
        
        public static const BULLET_POWER:int = 200;    
        public static const BULLET_LIFE:int = 2000;    //miliseconds
        public static const BULLET_SPEED:Number = 6;   //px per sec
        public static const BULLET_RADIUS:int = 4;    
        
        public static const EFFECT_EXPLOSION_SIZE:int = 72;    
        public static const EFFECT_EXPLOSION_KINDS:int = 20;    
        
        public static const MESSAGE_SHOOT_BULLET:String = "S";
        public static const MESSAGE_HIT_BULLET:String = "H";
        public static const MESSAGE_KILLSTREAK:String = "K";
        
        public static const RADAR_SIZE:int = 100;    
        
        public static const LOG_MAX_LENGTH:int = 15;    
        public static const LOG_COLOR_BEST:uint = 0x99FF99;
        public static const LOG_COLOR_GOOD:uint = 0x33FF33;
        public static const LOG_COLOR_NORMAL:uint = 0xFFFFFF;
        public static const LOG_COLOR_BAD:uint = 0xFF3333;
        public static const LOG_COLOR_WORST:uint = 0xFF9999;
        public static const LOG_COLOR_OTHER:uint = 0xFFDD99;
        public static const LOG_COLOR_KILLSTREAK:uint = 0xFFFF00;
        
        public static const ARENA_HALF_SIZE:int = ARENA_SIZE / 2;
        public static const PLAYER_MAX_DIST_PER_INTERVAL:Number = PLAYER_SPEED * PLAYER_POS_SEND_INTERVAL;
        public static const SQ_PLAYER_MAX_DIST_PER_INTERVAL:Number = PLAYER_MAX_DIST_PER_INTERVAL * PLAYER_MAX_DIST_PER_INTERVAL;
        public static const SQ_PLAYER_SPEED:Number = PLAYER_SPEED * PLAYER_SPEED;
        public static const OCCUPANT_SPEED:Number = PLAYER_SPEED + 1;
        public static const OCCUPANT_PRED_SPEED:Number = OCCUPANT_SPEED / 2;
        public static const SQ_OCCUPANT_SPEED:Number = OCCUPANT_SPEED * OCCUPANT_SPEED;
        public static const SQ_OCCUPANT_PRED_SPEED:Number = OCCUPANT_PRED_SPEED * OCCUPANT_PRED_SPEED;
        public static const BULLET_SPEED_PER_SEC:Number = BULLET_SPEED * 60;
        public static const BULLET_INVALID_SPEED:Number = BULLET_SPEED * PLAYER_POS_SEND_INTERVAL * 2;
        public static const SQ_BULLET_INVALID_SPEED:Number = BULLET_INVALID_SPEED * BULLET_INVALID_SPEED;
        public static const EFFECT_EXPLOSION_HALF_SIZE:int = EFFECT_EXPLOSION_SIZE / 2;
        public static const RADAR_SCALE:Number = RADAR_SIZE / ARENA_SIZE;
        public static const HP_GAUGE_WIDTH_PER_ONE:Number = 48 / PLAYER_HP;
        public static const EN_GAUGE_WIDTH_PER_ONE:Number = 48 / ENERGY_MAX;
        public static const SQ_RADIUS_SUM:int = (PLAYER_RADIUS + BULLET_RADIUS) * (PLAYER_RADIUS + BULLET_RADIUS);
        public static const FONT:String = "IPAGP";
        
        public static const ROOM_NO:String = "4";
        public static const VERSION:String = "ver 1.0";
        public static const HINTS:Array = [
            "Each bullet can fire continuously at Hold down the mouse key!",
            "Still In Beta",
            "Only On Kongregate",
            "Better Than Nothing",
            "BYRONO RULES!",
            "who lives in a Pineapple under the sea",
            "As seen on TV!",
            "May contain nuts!",
            "more pixels than minecraft",
            "Not on steam!",
            "12 herbs and spices!",
            "Water proof!",
            //sdfsdfsfsd
        ];
    }
//}
/* ------------------------------------------------------------------------------------------------
 * TextBuilder
 * ------------------------------------------------------------------------------------------------
 */
//package {
    import flash.geom.Point;
    import flash.text.AntiAliasType;
    import flash.text.GridFitType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    
 
    //public 
    class TextBuilder {
        private var _align:String;
        private var _autoSize:Boolean;
        private var _bold:Boolean;
        private var _filters:Array;
        private var _fontName:String;
        private var _sharpness:Number;
        private var _thickness:Number;
        private var _fontColor:uint;
        private var _fontSize:int;
        private var _position:Point;
        private var _size:Point;
        
        public static const LEFT:String = "left";
        public static const RIGHT:String = "right";
        public static const CENTER:String = "center";
        
        public function TextBuilder() {
            _align = TextBuilder.LEFT;
            _autoSize = _bold = false;
            _filters = [];
            _fontName = "Minecraft";
            _sharpness = _thickness = 0;
            _fontColor = 0x000000;
            _fontSize = 12;
            _position = new Point(0, 0);
            _size = new Point(100, 100);
        }
        
        public function align(value:String):TextBuilder { _align = value; return this; }        
        public function autoSize(enabled:Boolean = true):TextBuilder { _autoSize = enabled; return this; }
        public function bold(enabled:Boolean = true):TextBuilder { _bold = enabled; return this; }
        public function filters(value:Array):TextBuilder { _filters = value; return this; }
        public function font(name:String, sharpness:Number = 0, thickness:Number = 0):TextBuilder {
            _fontName = name;
            _sharpness = sharpness; _thickness = thickness;
            return this;
        }
        public function fontColor(value:uint):TextBuilder { _fontColor = value; return this; }
        public function fontSize(value:int):TextBuilder { _fontSize = value; return this; }
        public function pos(x:Number, y:Number, relative:Boolean = false):TextBuilder {
            _position.x = ((relative) ? _position.x : 0) + x;
            _position.y = ((relative) ? _position.y : 0) + y;
            return this;
        }
        public function size(width:Number, height:Number):TextBuilder {
            _size.x = width;
            _size.y = height;
            return this;
        }
        
        public function build(text:String):TextField {
            var tf:TextField = new TextField();
            var format:TextFormat = new TextFormat(_fontName, _fontSize, _fontColor, _bold);
            if (_fontName) {
                tf.embedFonts = true;
                tf.antiAliasType = AntiAliasType.ADVANCED;
                tf.gridFitType = (_align == TextBuilder.LEFT) ? GridFitType.PIXEL : GridFitType.SUBPIXEL;
                tf.sharpness = _sharpness;
                tf.thickness = _thickness;
            }
            
            tf.x = _position.x;
            tf.width = _size.x;
            tf.height = _size.y;
            if (_autoSize) {
                switch(_align) {
                    case TextBuilder.LEFT: { tf.autoSize = TextFieldAutoSize.LEFT; break; }
                    case TextBuilder.RIGHT: { tf.autoSize = TextFieldAutoSize.RIGHT; break; }
                    case TextBuilder.CENTER: { tf.autoSize = TextFieldAutoSize.CENTER; break; }
                }
            }else {
                switch(_align) {
                    case TextBuilder.LEFT: { format.align = TextFormatAlign.LEFT; break; }
                    case TextBuilder.RIGHT: { format.align = TextFormatAlign.RIGHT; break; }
                    case TextBuilder.CENTER: { format.align = TextFormatAlign.CENTER; break; }
                }
            }
            
            tf.defaultTextFormat = format;
            tf.text = text;
            tf.y = _position.y + ((_autoSize) ? Math.max(0, int((_size.y - (tf.textHeight + 4)) / 2)) : 0);
            tf.filters = _filters.concat();
            tf.mouseEnabled = tf.selectable = false;
            
            return tf;AVM1Movie
        }
        
        public function clone():TextBuilder {
            return new TextBuilder().align(_align).autoSize(_autoSize).bold(_bold).filters(_filters)
            .font(_fontName, _sharpness, _thickness).fontColor(_fontColor).fontSize(_fontSize)
            .pos(_position.x, _position.y).size(_size.x, _size.y);
        }
    }
//}