迎撃実験中
forked from 適当に偏差射撃 (diff: 60)
このコードを新着タンク一覧http://flash-games.wonderfl.net/tank/list/new に表示させるにはinfinite-tank-entry というタグをつけてください
♥0 |
Line 152 |
Modified 2009-10-10 01:19:55 |
MIT License
archived:2017-03-20 13:34:09
| (replaced)
ActionScript3 source code
/**
* Copyright keno42 ( http://wonderfl.net/user/keno42 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qtfG
*/
// forked from keno42's 適当に偏差射撃
// 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.Dictionary;
import net.wonderfl.game.infinity_tank.core.UserActionHandler;
import net.wonderfl.game.infinity_tank.model.*;
import net.wonderfl.game.infinity_tank.tank.TankBase;
import net.wonderfl.utils.SequentialLoader;
/**
* @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);
return bm;
}));
_gun = _images.pop();
_gun.x = -5;
_gun.y = -5;
_spBattery.addChild(_gun);
_spBattery.x = 20;
_spBattery.y = 15;
_i = 0;
_images.forEach(function ($bm:Bitmap, $index:int, $vec:Vector.<Bitmap>):void {
_spTank.addChild($bm);
});
_spTank.addChild(_spBattery);
}
private var doneList:Dictionary = new Dictionary();
private var newDoneList:Dictionary;
private var targetList:Array = [];
private var isMovingForward:Boolean = true;
// Commandクラスのフラグを立てることによって、タンクの行動を設定できます
// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/model/Command.html
override public function action():int
{
var newDoneList:Dictionary = new Dictionary();
var bullets:BoundBox = _scene.enemyBulletList;
while( bullets ){
if( doneList[bullets] ){
newDoneList[bullets] = true;
} else {
var bPos:Point = new Point(bullets.position.x, bullets.position.y);
var mPos:Point = new Point(_scene.myTankPosition.x, _scene.myTankPosition.y);
bPos = bPos.subtract(mPos);
var distance:Number = (bPos.x * bullets.linearVelocity.y - bPos.y * bullets.linearVelocity.x) / Math.sqrt( bullets.linearVelocity.x*bullets.linearVelocity.x + bullets.linearVelocity.y*bullets.linearVelocity.y);
if( Math.abs(distance) < 25 ){
targetList.push(bullets);
}
newDoneList[bullets] = true;
}
bullets = bullets.next;
}
doneList = newDoneList;
// 行動フラグ action
var action:int;
while( targetList.length && (
targetList[0].position.x < 0 ||
targetList[0].position.x > 600 ||
targetList[0].position.y < 0 ||
targetList[0].position.y > 600
) ) targetList.shift();
// 前へ進まない
// action |= Command.TANK_MOVE_FORWARD;
// action |= isMovingForward?Command.TANK_MOVE_FORWARD:Command.TANK_MOVE_BACKWARD;
// if( !targetList.length ) return action;
// _sceneオブジェクトは現在のステージの状況を保持しています
// _sceneオブジェクトはBattleSceneクラスのインスタンスです。詳しくは、
// http://flash-games.wonderfl.net/static/asdoc/net/wonderfl/game/infinity_tank/model/BattleScene.html
// 敵の現在の位置を取得する
var enemyPos:b2Vec2 = _scene.enemyTankPosition;
if( targetList.length ) enemyPos = targetList[0].position;
// 自分の現状の位置を取得する
var myPos:b2Vec2 = _scene.myTankPosition;
// 自分の位置から見た相手の相対的な位置を計算します
enemyPos.Subtract(myPos);
// 敵が等速直線運動をする仮定で偏差射撃
var enemyVec:b2Vec2 = _scene.enemyTankLinearVelocity;
if( targetList.length ) enemyVec = targetList[0].linearVelocity;
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 = 180;
var vd:Number = enemyVecNorm*enemyVecNorm;
var md:Number = bulletSpeed * bulletSpeed;
// 弾が敵にヒットする時間
var meetTime:Number = (yd * enemyVecNorm - Math.sqrt( yd * yd * vd - (x * x + yd * yd) * (vd - md) ) ) / (vd - md);
meetTime -= 0.02; // 砲身の長さを計算にいれるのが面倒なのでてきとうに・・
// meetTime後の敵の位置を狙う
var angle:Number = Math.atan2(enemyPos.y+meetTime*enemyVec.y, enemyPos.x+meetTime*enemyVec.x);
angle -= (_scene.myGunAngle + _scene.myTankAngle);
// 2πのモジュロを計算します
while( angle < -Math.PI ) angle += 2 * Math.PI;
while( angle > Math.PI ) angle -= 2 * Math.PI;
trace( angle, meetTime );
// 敵の位置が主砲が現在向いている向きより右であれば、
// 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.05 ){
action |=Command.FIRE;
if( targetList.length ) targetList.shift();
}
_enemyPos = new Point( enemyPos.x, enemyPos.y );
// 戦車の角度も調節することができます
if (angle < -0.4) action |= Command.TANK_TURN_LEFT;
else if (angle > 0.4) action |= Command.TANK_TURN_RIGHT;
return action;
}
private var _enemyPos:Point = new Point();
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;
}
// 前回の状態を一旦消す
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);
}
// called when a bullet hits this tank
override public function hit():void {
// 弾が当たったときに呼ばれます
// エフェクトをつけてみてください
}
}
}