Shoot downer

by hosepens forked from Wonderfl Tank Game Tank Sample 1 (diff: 140)
♥0 | Line 192 | Modified 2011-01-02 16:50:37 | MIT License | (replaced)
play

Related images

ActionScript3 source code

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

// forked from 9re's Wonderfl Tank Game Tank Sample 1
// このコードを新着タンク一覧http://flash-games.wonderfl.net/tank/list/new
// に表示させるにはinfinite-tank-entry
// というタグをつけてください
package 
{
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.utils.setTimeout;
    import flash.utils.Timer;
    
    import flash.text.TextField;
    
    import net.wonderfl.game.infinity_tank.development.*;
    import net.wonderfl.math.*;
    import net.wonderfl.utils.SequentialLoader;
    // クラス名は必ずTankにして、TankBaseクラスを拡張して下さい
    // http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/tank/TankBase.html
    public class Tank extends TankBase
    {
        private var _gunFlag:Boolean = true;
        private var _lastBulletCount:int = 0;
        private var _spTank:Sprite;
        private var _spBattery:Sprite;
        private var _spMain: Sprite;
        private var _ctfm:ColorTransform;
        private var _images:Vector.<Bitmap>;
        private var _gun:Bitmap;
        private var _arr:Array = [];
        private var _i:int = -1;
        private var _j:int = 0;
        private var _mat:Matrix = new Matrix(1, 0, 0, 1, 5, 15);
        
        private var tf: TextField;
        private var enemyBullet: int = 0;
        private var enemyFire: Boolean = false;
        private var targets: Vector.<WVector2D>;
        private var mode: int = 0;
        private var count: int = 0;
        private var gap: Number;
        
        public function Tank() 
        {
           // 弾のクラスのurlをセットしてください
            // 弾のドキュメントクラスはBulletRendererBaseクラスを拡張したBulletRendererクラスである必要があります
            // 弾の一覧は、http://flash-games.wonderfl.net/tank/list/bullets
            // にあります.
            // http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/development/BulletRendererBase.html
            _bulletRenderer = "http://swf.wonderfl.net/swf/usercode/0/04/046c/046cee45b4334c4f2dac8dfa7ec9ea2b2b2eb27d.swf";
            
            _spMain = new Sprite;
            _spTank = new Sprite;
            _spBattery = new Sprite;
            
            tf = new TextField;
            
            var url1: String = "http://assets.wonderfl.net/images/related_images/4/4d/4de3/4de3a10db14fbbb091db284e50cfe59b56d07527";
            var url2: String = "http://assets.wonderfl.net/images/related_images/e/e4/e401/e401e45f33a4d5cd31afcebac727c39d8ad95ed0";
            
            SequentialLoader.loadImages([url1, url1, url2], _arr, onImageLoaded);
            
            _ctfm = new ColorTransform(1, 1, 1, 0);
            
            targets = new Vector.<WVector2D>;           
            
            
            super();
        }
        
        // ※タンクの動きのメイン関数
        // 5フレームに1度呼ばれるcallback
        // 現在のゲームの状態を見るには、_sceneオブジェクトのプロパティーを 調べます.
        // @see http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/development/BattleScene.html
        override public function action():int
        {
            
            
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            //タンクの動きはCommandクラスにより操作します。以下Commandクラスのコマンド///////////////
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            
            // Command.FIRE           弾を撃つ
            // Command.GUN_TURN_RIGHT 砲台を右旋回
            // Command.GUN_TURN_LEFT  砲台を左旋回
            // Command.TANK_MOVE_FORWARD  前進
            // Command.TANK_MOVE_BACKWARD  後進
            // TANK_TURN_LEFT 左に旋回
            // TANK_TURN_RIGHT 右に旋回
            
            // command.addCommand(Command.コマンド);//実行する動きに追加
            // return command.action; この関数の最後で実行する
            
            // @see http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/development/Command.html
            
            
            
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            //以下AIに必要なパラメータ情報。/////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            
            //enemyDistance:Number 敵との距離
            //enemyPos:WVector2D 敵の位置を取得
            //enemySpeed:WVector2D 敵の速度を取得
            //angle:Number 自分からみた敵の方向を計算する.
            //direction:Number 敵の方向と自分のタンクの向いている方向の差
            
            
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            //以下AIに必要なパラメータ取得。編集の必要はありません。//////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            
            
            var command:Command = new Command;
            
            // 敵の位置を取得.
            var enemyPos:WVector2D = _scene.enemyTankPosition;
            // 自分の位置を敵の位置から引く.
            // 自分から見た敵の位置を計算
            enemyPos.subtract(_scene.myTankPosition);
            // 敵との距離
            var enemyDistance:Number = enemyPos.length;
            
            // 敵の速度を取得
            var enemySpeed:WVector2D = _scene.enemyTankLinearVelocity;
            // 0.5秒の位置を線形で予想
            enemySpeed.scale(0.5);
            enemyPos.add(enemySpeed);
            
            // 自分からみた敵の方向を計算する.
            var angle:Number = Math.atan2(enemyPos.y, enemyPos.x);
            // 敵の方向をコピー
            var direction:Number = angle;
            
            // 敵の方向と自分の砲台の向いている方向の差を計算
            angle -= (_scene.myTankAngle + _scene.myGunAngle);
            // 敵の方向と自分のタンクの向いている方向の差を計算
            direction -= _scene.myTankAngle;
            
            // 角度を0~2πに丸める
            angle = WMath.modulo2PI(angle);
            direction = WMath.modulo2PI(direction);
            
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            //以下AI実装部分。ここから編集してください//////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            gap = move(_scene.enemyTankPosition, command);
            if(enemyFire) {
                shoot(targets[0], command, gap);
                command.addCommand(Command.FIRE);
                targets.shift();
            }else{
                shoot(_scene.enemyTankPosition, command, gap);
            }

            enemyFire = false;
            
            
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            //AIここまで//////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
            
            // command.actionがフラグとなっている
            return command.action;
        }
        
        private function shoot(target: WVector2D, command: Command, gap: Number): void {
            var _target: WVector2D = target;
            _target.subtract(_scene.myTankPosition);
            var angle:Number = Math.atan2(_target.y, _target.x);
            var direction:Number = angle;
            angle -= (_scene.myTankAngle + _scene.myGunAngle);
            angle += gap;
            direction -= _scene.myTankAngle;
            angle = WMath.modulo2PI(angle);
            direction = WMath.modulo2PI(direction);
            if(angle < Math.PI) {
                command.addCommand(Command.GUN_TURN_RIGHT);
            }else if(angle > Math.PI) {
                command.addCommand(Command.GUN_TURN_LEFT);
            }
        }
        
        private function move(target: WVector2D, command: Command): Number {
            var gap: Number;
            var _target: WVector2D = target;
            _target.subtract(_scene.myTankPosition);
            var angle:Number = Math.atan2(_target.y, _target.x);
            var direction:Number = angle;
            angle -= (_scene.myTankAngle + _scene.myGunAngle);
            direction -= _scene.myTankAngle;
            angle = WMath.modulo2PI(angle);
            direction = WMath.modulo2PI(direction);
            if(count % 12 == 0) {
                if(direction < Math.PI / 2) {
                    mode = 0;
                }else if(direction < Math.PI) {
                    mode = 1;
                }else if(direction < Math.PI / 2 * 3) {
                    mode = 2;
                }else{
                    mode = 3;
                }
            }
            if(mode == 0) {
                command.addCommand(Command.TANK_TURN_LEFT);
                command.addCommand(Command.TANK_MOVE_FORWARD);
                gap = Math.PI / 180 * 15;
            }else if(mode == 1) {
                command.addCommand(Command.TANK_TURN_RIGHT);
                command.addCommand(Command.TANK_MOVE_BACKWARD);
                gap = - Math.PI / 180 * 15;
            }else if(mode == 2) {
                command.addCommand(Command.TANK_TURN_LEFT);
                command.addCommand(Command.TANK_MOVE_BACKWARD);
                gap = Math.PI / 180 * 15;
            }else if(mode == 3) {
                command.addCommand(Command.TANK_TURN_RIGHT);
                command.addCommand(Command.TANK_MOVE_FORWARD);
                gap = - Math.PI / 180 * 15;
            }
                
            count ++;
            return gap;
        }
        
        
        ///////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        //追加演出//////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        
        // ※被弾時に演出を入れたい時に編集してください。
        // called when a bullet hits this tank
        override public function hit():void {
            // 被弾したときに呼ばれるcallbackです.
        }
        
        // ※発射時に演出を入れたい時に編集してください。
        // called when this tank fires
        override public function fire():void 
        {
            // 弾が発射される時に呼ばれるcallbackです.
        }
        
        ///////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        //以下修正不要//////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////
        
        // ※画像読み込み用関数
        // 通常編集する必要はありません
        private function onImageLoaded():void
        {
            _images = Vector.<Bitmap>(_arr.map(function ($ldr:Loader, $index:int, $arr:Array):Bitmap {
                var mat:Matrix = new Matrix;
                var bd:BitmapData = new BitmapData($ldr.width, $ldr.height, true, 0x00ffffff);
                bd.draw($ldr, mat);
                var bm:Bitmap = new Bitmap(bd);
                bm.x = -bm.width / 2;
                bm.y = -bm.height / 2;
                
                return bm;
            }));
            
            _gun = _images.pop();
            _gun.x = -5;
            
            _gun.y = -5;
            _spBattery.addChild(_gun);
            _i = 0;
            _images.forEach(function ($bm:Bitmap, $index:int, $vec:Vector.<Bitmap>):void {
                _spTank.addChild($bm);
            });
            _spTank.addChild(_spBattery);
            //this.addChild(tf);
            tf.y = 100;
            tf.width = 400;
            tf.height = 20;
        }
        
        
        
        // ※タンクの向きを描画している関数。修正の必要はありません。
        // 毎フレームごとに呼ばれる描画callback
        // stageと同じ大きさのBitmapDataが渡されます.
        // 現在のゲームの状態を見るには、_sceneオブジェクトのプロパティーを
        // 調べます.
        // @see http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/development/BattleScene.html
        override public function draw(bitmapData:BitmapData):void
        {
            // 砲台の向きをセットします.
            // 砲台はタンクのSpriteの子供のスプライトです.
            _spBattery.rotation = _scene.myGunAngle * 180 / Math.PI;
            
            if (_i > -1) {
                _i = (_j & 1) ? 1 : 0;
                var bm:Bitmap = _images[_i];
                bm.visible = true;
                _i = 1 - _i;
                bm = _images[_i];
                bm.visible = false;
                _j++;
                _j &= 3;
            }
            
            // 単位行列にセット
            _mat.identity();
            // タンクの傾きをセット
            _mat.rotate(_scene.myTankAngle);
            // タンクの位置に平行移動. タンクのグラフィックは中心座標となっています.
            _mat.translate(_scene.myTankPosition.x, _scene.myTankPosition.y);
            
            // 一度BitmapDataをクリア
            bitmapData.colorTransform(bitmapData.rect, _ctfm);
            // BitmapDataを描画
            bitmapData.draw(_spTank, _mat, null, null, null, true);
            
            //AL
            tf.text = (_scene.myTankAngle + _scene.myGunAngle) + "";
            
            if(enemyBullet < _scene.enemyBulletCount) {
                enemyFire = true;
                targets.push(_scene.enemyTankPosition);
            }
            enemyBullet = _scene.enemyBulletCount;
            
        }
        
        // ※弾フラグ
        private function clearGunFlag():void
        {
            _gunFlag = true;
        }
    }
}