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

適当に偏差射撃

このコードを新着タンク一覧http://flash-games.wonderfl.net/tank/list/new
に表示させるにはinfinite-tank-entry
というタグをつけてください
Get Adobe Flash player
by keno42 22 Oct 2009
  • Forked from 9re's Wonderfl Tank Game Tank Sample 1
  • Diff: 231
  • Related works: 10
  • Talk

    whaison at 27 Oct 2009 09:32
    どうしたら http://flash-games.wonderfl.net/tank/list/new にのれるのか # infinite-tank-entry # // というタグをつけてください という意味が僕には よくわかりませんでした。
    keno42 at 27 Oct 2009 09:45
    editモードでタイトル部分をクリックすると、タグの編集欄が出現しますので、そこに infinite-tank-entry と書き込めばokです
    whaison at 28 Oct 2009 14:53
    おぉっ keno42 本人さまにコメントいただけて うれしいです。 ありがとうございました。

    Tags

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

// forked from 9re's Wonderfl Tank Game Tank Sample 1
// このコードを新着タンク一覧http://flash-games.wonderfl.net/tank/list/new
// に表示させるにはinfinite-tank-entry
// というタグをつけてください
package 
{
	// ai0
	import Box2D.Common.Math.b2Vec2;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.system.Security;
	import flash.utils.setTimeout;
	import flash.utils.Timer; 
	import flash.utils.getTimer;
	
   import net.wonderfl.game.infinity_tank.development.*;
	import net.wonderfl.utils.SequentialLoader;
	import net.wonderfl.math.*;
	/**
	 * @author 9re
	 */
	// クラス名は必ずTankにして、TankBaseクラスを拡張して下さい
	// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/tank/TankBase.html
	public class Tank extends TankBase
	{
		private var _spTank:Sprite;
		private var _spBattery: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 _arrCommands:Array = [Command.FIRE, Command.GUN_TURN_LEFT, Command.GUN_TURN_RIGHT, Command.TANK_MOVE_BACKWARD, Command.TANK_MOVE_FORWARD, Command.TANK_TURN_LEFT, Command.TANK_TURN_RIGHT];
		private var _mat:Matrix = new Matrix(1, 0, 0, 1, 5, 15);
		
		public function Tank() 
		{
            // 弾のクラスのurlをセットしてください
			// 弾のドキュメントクラスはBulletRendererBaseクラスを拡張したBulletRendererクラスである必要があります
			// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/bullet/BulletRendererBase.html
			_bulletRenderer = "http://swf.wonderfl.net/swf/usercode/8/8f/8faa/8faa6f4c1148ad9a535d25bdd49b7e4d98d02030.swf";
			
			_spTank = new Sprite;
			_spBattery = new Sprite;
			
			SequentialLoader.loadImages([
			    "http://assets.wonderfl.net/images/related_images/b/b7/b7aa/b7aa7e34d862722e9d939f2c8d8c38f844b02f20",
			    "http://assets.wonderfl.net/images/related_images/7/76/76d4/76d4ef9f4c0a8172551f750a12f3bb207a0f0546",
			    "http://assets.wonderfl.net/images/related_images/f/f3/f3db/f3dbbe24d0308a857f7f3f252d488a9e6def05c6"
			], _arr, onImageLoaded);
			
			_ctfm = new ColorTransform(1, 1, 1, 0);
		}
		
		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);
		}
		private var isMovingForward:Boolean = true;
		private var changeCount:int = 5;
		private var lastPos:WVector2D = new WVector2D(-100,0);
		private var hosei:Number = 0;
		private var lastFire:Number = 0;
		// Commandクラスのフラグを立てることによって、タンクの行動を設定できます
		// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/model/Command.html
		override public function action():int
		{
            // 行動フラグ action
    		var action:int;
    		changeCount--;
    		lastPos.subtract(_scene.myTankPosition);
    		trace(lastPos.length)
    		if( lastPos.normalize() < 7 && changeCount < 0 ){
    		     isMovingForward = !isMovingForward;
    		     changeCount = 20;
    		}
    		lastPos.x = _scene.myTankPosition.x;
    		lastPos.y = _scene.myTankPosition.y;
    		/* 
    		var myfuturePos:WVector2D = _scene.myTankPosition;
    		myfuturePos.add(_scene.myTankLinearVelocity);
    		if( myfuturePos.x < 30 || myfuturePos.x > 570 ||
    		myfuturePos.y < 30 || myfuturePos.y > 520 ){
    		    if( changeCount < 0 ){
    		     isMovingForward = !isMovingForward;
    		     changeCount = 20;
    		    }
           }
           */
    		 
			// 前へ進む
//           action |= Command.TANK_MOVE_FORWARD;
           action |= isMovingForward?Command.TANK_MOVE_FORWARD:Command.TANK_MOVE_BACKWARD;
			
            // _sceneオブジェクトは現在のステージの状況を保持しています
			// _sceneオブジェクトはBattleSceneクラスのインスタンスです。詳しくは、
			// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/model/BattleScene.html
            // 敵の現在の位置を取得する
			var enemyPos:WVector2D = _scene.enemyTankPosition;
            // 自分の現状の位置を取得する
			var myPos:WVector2D = _scene.myTankPosition;
			
            // 自分の位置から見た相手の相対的な位置を計算します
			enemyPos.subtract(myPos);
            // 自分から見た敵の戦車の方向を計算します
            // これはx軸方向を見て時計回りの角度となります。
			var angle2:Number = Math.atan2(enemyPos.y, enemyPos.x);
            // 現在の敵の方向とと主砲の向きとのズレを計算
            // タンクの角度にさらに主砲の角度を足すことを忘れないで下さい
			angle2 -= (_scene.myTankAngle);
			
			// 敵が等速直線運動をする仮定で偏差射撃
			var enemyVec:WVector2D = _scene.enemyTankLinearVelocity;
			var enemyAngVel:Number = _scene.enemyTankAngularVelocity;
			var tempMat:WMatrix2D = new WMatrix2D();
			tempMat.setRotationMatrix(enemyAngVel);
			enemyVec.applyMatrix(tempMat);
			var enemyVecP:Point = new Point(enemyVec.x, enemyVec.y);
			var enemyVecNorm:Number = enemyVecP.length;
			enemyVecP.normalize(1);
			var yd:Number = enemyVecP.x * enemyPos.x + enemyVecP.y * enemyPos.y;
			var x:Number = Math.sqrt(enemyPos.x*enemyPos.x+enemyPos.y*enemyPos.y - yd*yd);
			var bulletSpeed:Number = 150+100*Math.cos(hosei); // この数字がてきとう..
			var vd:Number = enemyVecNorm*enemyVecNorm;
			var md:Number = bulletSpeed * bulletSpeed; 
			// 弾が敵にヒットする時間
           var alpha:Number = yd * yd * vd - (x * x + yd * yd) * (vd - md);
			var sign:int = (alpha>=0)?1:-1;
           	
			var meetTime:Number = sign * (yd * enemyVecNorm - Math.sqrt( sign * alpha ) ) / (vd - md);
			var limit:int = 1; 
			if( enemyPos.length < 20 ) meetTime = 0;
   			tempPoint = new WVector2D(enemyPos.x+meetTime*enemyVec.x, enemyPos.y+meetTime*enemyVec.y);
           while( (tempPoint.x > 600 || tempPoint.x < 0 || tempPoint.y > 550 || tempPoint.y < 0) && limit-- ){
                meetTime *= 0.75;
       			tempPoint = new WVector2D(enemyPos.x+meetTime*enemyVec.x, enemyPos.y+meetTime*enemyVec.y);
           } 
			// meetTime後の敵の位置を狙う
			var angle:Number = Math.atan2(tempPoint.y, tempPoint.x);
			angle -= (_scene.myGunAngle + _scene.myTankAngle);
			trace( angle, yd * yd * vd - (x * x + yd * yd) * (vd - md)  );
			 
            // 2πのモジュロを計算します
			angle %= Math.PI * 2;
			if( angle > Math.PI ) angle -= Math.PI*2;
			if( angle < -Math.PI ) angle += Math.PI*2;
						
            // 敵の位置が主砲が現在向いている向きより右であれば、
            // Command.GUN_TURN_RIGHT
			if (angle > 0) action |= Command.GUN_TURN_RIGHT;
            // 敵の位置が主砲が現在向いている向きより左であれば、
            // Command.GUN_TURN_LEFT
			else if (angle < 0) action |= Command.GUN_TURN_LEFT;
			
			// 敵を十分に狙えているか、非常に近くてほぼヒット確実なら射撃
			if( Math.abs( angle ) < 0.20 || meetTime < 0.5 ){
			    if( getTimer() - lastFire > 400 ){
    			     action |=Command.FIRE;
    			     lastFire = getTimer();
            		    hosei+=0.2;
    			 }
    			     
			     drawFlg = true;
			 } else { drawFlg = false; }
			
			angle2 += 3 * Math.PI / 2;
			if( isMovingForward ) angle2 -= 0.35 * Math.PI;
			else angle2 += 0.35 * Math.PI;
			angle2 %= Math.PI * 2; 
			if( angle2 > Math.PI ) angle2 -= Math.PI*2;
			if( angle2 < -Math.PI ) angle2 += Math.PI*2;
			
			
			// 戦車の角度も調節することができます
			if (angle2 > 0) action |= Command.TANK_TURN_LEFT;
			else if (angle2 < 0) action |= Command.TANK_TURN_RIGHT;
			
			return action;
		}
		private var tempPoint:WVector2D = new WVector2D(0,0);
		private var drawFlg:Boolean = false;
		
		override public function draw(bitmapData:BitmapData):void
		{
            // _sceneオブジェクトは現在のステージの状況を保持しています
			// _sceneオブジェクトはBattleSceneクラスのインスタンスです。詳しくは、
			// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/model/BattleScene.html
			// 主砲の角度を計算します。
			// この角度は相対的で戦車の本体から見た角度です。
			_spBattery.rotation = _scene.myGunAngle * 180 / Math.PI;
			
			// ここでは2枚のPNGをGIFアニメのように切り替えています
			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.colorTransform(bitmapData.rect, _ctfm);
			// _mat = new Matrix(1, 0, 0, 1, 5, 15)なのですが、
			// これは戦車のBitmapDataを戦車のヒットエリアよりやや大きめにしているからです
			// ビットマップのサイズは60 x 60で戦車のヒットエリアは
			// 50 x 30です。右向きを正面とするのがデフォルトの状態です
			// なので、
			// (60 - 50) / 2 = 5
			// (60 - 30) / 2 = 15
			// つまり、戦車本体はビットマップの左上隅の点から少しずれて
			// 左から5ピクセル、上から15ピクセルのところにあります
			bitmapData.draw(_spTank, _mat, null, null, null, true);
			
			if( _spTank ){
        			_spTank.graphics.clear(); 

			    var tempPoint2:WVector2D = new WVector2D(tempPoint.x, tempPoint.y);
			    var m2d:WMatrix2D = new WMatrix2D();
			    m2d.setRotationMatrix( -_scene.myTankAngle);
			    tempPoint2.applyMatrix(m2d);
			    m2d.setRotationMatrix( 0.20 ); 
			    tempPoint2.applyMatrix(m2d);
			if( drawFlg ){
			    
    			_spTank.graphics.lineStyle(0, 0x004400);
    			
       	    	} else {       	    	    
    			_spTank.graphics.lineStyle(0, 0x440000);
       	    	    
                }       	    	    
    			_spTank.graphics.lineTo(tempPoint2.x, tempPoint2.y);
			    m2d.setRotationMatrix( -0.40 );
			    tempPoint2.applyMatrix(m2d);
    			_spTank.graphics.lineTo(tempPoint2.x, tempPoint2.y);
    			_spTank.graphics.lineTo(0, 0);
            }
}    		
		
		// called when a bullet hits this tank
		override public function hit():void {
            // 弾が当たったときに呼ばれます
            // エフェクトをつけてみてください
		}

	}
}