neurona
forked from Wonderfl Tank Game Tank Sample 1 (diff: 271)
♥0 |
Line 167 |
Modified 2009-12-16 21:07:17 |
MIT License
archived:2017-03-09 11:36:52
| (replaced)
ActionScript3 source code
/**
* Copyright flik ( http://wonderfl.net/user/flik )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/aJw6
*/
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 net.wonderfl.game.infinity_tank.development.*;
import net.wonderfl.math.*;
import net.wonderfl.utils.SequentialLoader;
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 _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 weight:Number = 0.3;
private var bias:Number = 0.25;
public function Tank()
{
_bulletRenderer = "http://swf.wonderfl.net/swf/usercode/0/04/046c/046cee45b4334c4f2dac8dfa7ec9ea2b2b2eb27d.swf";
_spTank = new Sprite;
_spBattery = new Sprite;
SequentialLoader.loadImages(["http://assets.wonderfl.net/images/tank/tankA_1.png", "http://assets.wonderfl.net/images/tank/tankA_2.png", "http://assets.wonderfl.net/images/tank/tankA_cannon.png"], _arr, onImageLoaded);
_ctfm = new ColorTransform(1, 1, 1, 0);
super();
}
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);
}
override public function action():int
{
if (_lastBulletCount < _scene.myBulletCount) {
_gunFlag = false;
setTimeout(clearGunFlag, 100);
}
_lastBulletCount = _scene.myBulletCount;
var pos:WVector2D = new WVector2D(_scene.myTankPosition.x,_scene.myTankPosition.y);
var enemyPos:WVector2D = _scene.enemyTankPosition;
//Enemy relative position vetor
enemyPos.subtract(_scene.myTankPosition);
//enemy relative distance
var enemyDistance:Number = enemyPos.length;
//enemy velocity vector
var enemySpeed:WVector2D = _scene.enemyTankLinearVelocity;
//neuron estimates future position according to enemy current velocity and position
enemySpeed.scale(bias + enemyDistance/100*weight);
enemyPos.add(enemySpeed);
var enemyDistance2:Number = enemyPos.length;
var enemyPos2:WVector2D = _scene.enemyTankPosition;
enemyPos2.subtract(_scene.myTankPosition);
enemyPos2.add(enemySpeed);
var action:int;
if (_gunFlag) {
action = Command.FIRE;
//supply timeout with parameters: old enemyPos & expected enemyPos
//estimated time to collision is "enemyDistance2 * 6"
setTimeout(backPropagate , enemyDistance2 * 6, _scene.enemyTankPosition, enemyPos2);
}
else {
action = Command.DO_NOTHING;
}
//turn gun according to expected position
var angle:Number = Math.atan2(enemyPos.y, enemyPos.x);
var direction:Number = angle;
angle -= (_scene.myTankAngle + _scene.myGunAngle);
direction -= _scene.myTankAngle;
angle = WMath.modulo2PI(angle);
direction = WMath.modulo2PI(direction);
if (angle <= Math.PI) action |= Command.GUN_TURN_RIGHT;
else action |= Command.GUN_TURN_LEFT;
var centerVec:WVector2D=new WVector2D(600/2,550/2);
centerVec.subtract(pos);
if(centerVec.length>240)
{
if(Math.random()<0.15)
{
action |= Command.TANK_MOVE_BACKWARD;
}
else
{
action |= Command.TANK_MOVE_FORWARD;
}
action |= Command.TANK_TURN_LEFT;
}
else
{
var dir2:Number=WMath.modulo2PI(direction+Math.PI/2-Math.PI/3*Math.random());
if (dir2 <= Math.PI) action |= Command.TANK_TURN_RIGHT;
else action |= Command.TANK_TURN_LEFT;
if(Math.random()<0.05)
{
action |= Command.TANK_MOVE_BACKWARD;
}
else
{
action |= Command.TANK_MOVE_FORWARD;
}
}
return action;
}
//training the tank...
private function backPropagate():void {
//enemy current distance from old enemy position
var newEnemyPos:WVector2D = _scene.enemyTankPosition;
newEnemyPos.subtract(arguments[0]);
var actualDist:Number = newEnemyPos.length;
//enemy expected distance from old enemy position
var expectedPos:WVector2D = arguments[1];
expectedPos.subtract(arguments[0]);
var expectedDist:Number = expectedPos.length;
//bias += bias * (actualDist - expectedDist) / actualDist;
//weight += weight * (actualDist - expectedDist) / actualDist;
if (actualDist - expectedDist < -10) {
bias -= 0.05;
weight -= 0.05;
}
else if (actualDist - expectedDist > 10) {
bias += 0.05;
weight += 0.05;
}
}
//used to regulate gun shots
private function clearGunFlag():void
{
_gunFlag = true;
}
//not important... updates the drawing
override public function draw(bitmapData:BitmapData):void
{
_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.colorTransform(bitmapData.rect, _ctfm);
bitmapData.draw(_spTank, _mat, null, null, null, true);
}
// called when a bullet hits this tank
override public function hit():void {
}
// called when this tank fires
override public function fire():void {
}
}
}