sample2

by wh0
retired
♥0 | Line 157 | Modified 2011-05-15 06:50:40 | MIT License | (replaced)
play

ActionScript3 source code

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

package {
    import net.wonderfl.game.infinity_tank.development.*;
    import net.wonderfl.math.*;
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Graphics;
    import flash.text.TextField;
    import flash.geom.Matrix;
    import flash.display.Sprite;
    [SWF(backgroundColor="#000000")]
    public class Tank extends TankBase {
        
        private static const tankColor:int = 0x00ff00;
        private static const gunColor:int = 0x00ff00;
        private static const tacticsColor:int = 0x00ff00;
        
        private const m:Matrix = new Matrix(); // prevents reallocation
        private const tank:Shape = new Shape();
        private const gun:Shape = new Shape();
        private const tactics:Sprite = new Sprite();
        private const t:TextField = new TextField();
        
        private static const bulletSpeed:Number = 240; // determined empirically
        private static const bulletSquared:Number = bulletSpeed * bulletSpeed;
        private static const arenaWidth:Number = 600;
        private static const arenaHeight:Number = 550;
        
        private var fv:WVector2D = new WVector2D();
        private var exit:int = Command.DO_NOTHING;
        
        public function Tank() {
            _bulletRenderer = 'http://swf.wonderfl.net/swf/usercode/6/6e/6e5b/6e5bc3edbe5524cec05da6038f5d6b1bc8d77bfd.swf';
            super();
            
            var g:Graphics;
            g = tank.graphics;
            g.lineStyle(0, tankColor);
            g.drawRect(-25, -15, 50, 30);
            g.lineStyle(2, tankColor, 0.5);
            g.moveTo(15, 5);
            g.lineTo(20, 0);
            g.lineTo(15, -5);
            g = gun.graphics;
            g.lineStyle(4, gunColor);
            g.moveTo(0, 0);
            g.lineTo(28, 0);
            t.y = 200;
            t.textColor = tacticsColor;
            tactics.addChild(t);
        }
        
        // called every 5 frames
        override public function action():int {
            var c:Command = new Command();
            var g:Graphics = tactics.graphics;
            g.clear();
            g.lineStyle(0, tacticsColor, 0.5);
            
            var mp:WVector2D = _scene.myTankPosition;
            t.x = mp.x; t.y = mp.y;
            var mt:Number = _scene.myTankAngle;
            var mg:Number = mt + _scene.myGunAngle;
            var mv:WVector2D = _scene.myTankLinearVelocity;
            var ep:WVector2D = _scene.enemyTankPosition;
            var et:Number = _scene.enemyTankAngle;
            var ev:WVector2D = _scene.enemyTankLinearVelocity;
            fv.scale(7); fv.add(ev); fv.scale(0.125);
            g.moveTo(ep.x, ep.y); g.lineTo(ep.x + fv.x, ep.y + fv.y);
            var fp:WVector2D;
            var closeQuarters:Number;
            if (WMath.distanceSquared(mp, ep) < 40000) {
                closeQuarters = -1;
                fp = ep;
                g.moveTo((mp.x + ep.x + mp.y - ep.y) / 2, (mp.y + ep.y - mp.x + ep.x) / 2);
                g.lineTo((mp.x + ep.x - mp.y + ep.y) / 2, (mp.y + ep.y + mp.x - ep.x) / 2);
            } else {
                closeQuarters = 1;
                fp = predict(mp, ep, fv);
            }
            g.moveTo(fp.x - 5, fp.y - 5); g.lineTo(fp.x + 5, fp.y + 5);
            g.moveTo(fp.x - 5, fp.y + 5); g.lineTo(fp.x + 5, fp.y - 5);
            
            var zmgf:WVector2D = view(mp, mg, fp);
            c.addCommand(zmgf.y < 0 ? Command.GUN_TURN_RIGHT : Command.GUN_TURN_LEFT);
            
            var zmtf:WVector2D = view(mp, mt, ep);
            c.addCommand(zmtf.x * zmtf.y < 0 ? Command.TANK_TURN_LEFT : Command.TANK_TURN_RIGHT);
            
            var danger:Boolean = false;
            var ahead:Number = walls(mp, mt, 50);
            var behind:Number = walls(mp, mt, -50);
            
            for (var b:BoundBox = _scene.enemyBulletList; b; b = b.next) {
                var zbm:WVector2D = view(b.position, b.rotation, mp);
                if (zbm.x < -40 || zbm.x > 400)
                    continue;
                var zmbt:WVector2D = view(mp, mt, b.position);
                if (zbm.y * zmbt.y < 0)
                    ahead += 200 / (zbm.x + 50);
                else
                    behind += 200 / (zbm.x + 50);
                if (Math.abs(zbm.y) < 50) {
                    danger = true;
                    g.drawCircle(b.position.x, b.position.y, 2000 / (zbm.x + 50));
                }
            }
            
            if (danger) {
                if (exit == Command.TANK_MOVE_FORWARD && behind < 1 && ahead > behind)
                    exit = Command.TANK_MOVE_BACKWARD;
                else if (exit == Command.TANK_MOVE_BACKWARD && ahead < 1 && behind > ahead)
                    exit = Command.TANK_MOVE_FORWARD;
                else if (exit == Command.DO_NOTHING)
                    exit = ahead > behind ? Command.TANK_MOVE_BACKWARD : Command.TANK_MOVE_FORWARD;
                c.addCommand(exit);
            } else {
                var zetm:WVector2D = view(ep, et, mp);
                if (closeQuarters * zetm.x * zetm.y * zmtf.y < 30 && ahead < 0.8)
                    c.addCommand(Command.TANK_MOVE_FORWARD);
                else if (closeQuarters * zetm.x * zetm.y * zmtf.y > 30 && behind < 0.8)
                    c.addCommand(Command.TANK_MOVE_BACKWARD);
                exit = 0;
            }
            
            t.text = ahead.toFixed(3) + '/' + behind.toFixed(3);
            
            if (Math.abs(zmgf.y) < 35 || _scene.myBulletCount < 0)
                c.addCommand(Command.FIRE);
            
            return c.action;
        }
        
        private static function predict(mp:WVector2D, ep:WVector2D, ev:WVector2D):WVector2D {
            var a:Number = ev.x * ev.x + ev.y * ev.y - bulletSquared;
            var b:Number = 2 * (ep.x * ev.x + ep.y * ev.y);
            var c:Number = ep.x * ep.x + ep.y * ep.y;
            var r:Number = Math.max(0.6, (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a));
            return new WVector2D(Math.max(20, Math.min(580, ep.x + ev.x * r)), Math.max(20, Math.min(530, ep.y + ev.y * r)));
        }
        
        private static function view(src:WVector2D, angle:Number, dst:WVector2D):WVector2D {
            var dx:Number = dst.x - src.x;
            var dy:Number = dst.y - src.y;
            var ax:Number = Math.cos(angle);
            var ay:Number = Math.sin(angle);
            return new WVector2D(dx * ax + dy * ay, dx * ay - dy * ax);
        }
        
        private static function walls(p:WVector2D, t:Number, d:Number):Number {
            var tx:Number = Math.cos(t);
            var ty:Number = Math.sin(t);
            var x:Number = Math.max(15, Math.min(arenaWidth - 15, p.x + d * tx));
            var y:Number = Math.max(15, Math.min(arenaHeight - 15, p.y + d * ty));
            var r:Number = 0;
            return 35 / (tx * d < 0 ? x : arenaWidth - x) * Math.abs(tx) + 35 / (ty * d < 0 ? y : arenaHeight - y) * Math.abs(ty);
        }
        
        // called when a bullet hits this tank
        override public function hit():void {
        }
        
        // called when this tank fires
        override public function fire():void {
        }
        /*
        // bullet cheat :D
        private namespace tank_internal = 'http://flash-games.wonderfl.net/tank';
        override tank_internal function __setScene(b:BattleScene):void {
            super.tank_internal::__setScene(b);
            var sentinel:BoundBox = new BoundBox(null, null, 0, new WVector2D());
            for (var i:int = 0; i < 30; i++)
                _scene.tank_internal::removeBullet(sentinel, _scene.tank_internal::id);
        }
        */
        override public function draw(b:BitmapData):void {
            var p:WVector2D = _scene.myTankPosition;
            b.lock();
            b.fillRect(b.rect, 0);
            
            m.identity();
            m.rotate(_scene.myTankAngle);
            m.translate(p.x, p.y);
            b.draw(tank, m);
            
            m.identity();
            m.rotate(_scene.myGunAngle + _scene.myTankAngle);
            m.translate(p.x, p.y);
            b.draw(gun, m);
            
            b.draw(tactics);
            
            b.unlock();
        }
        
    }
}