Homing missile in AS3

I am trying to create a homing missile in AS3. It is easy enough when you want it to just perfectly follow the point - but I'm trying to make the rockets turn around if the target (target) bypasses it.

Here's what I have - it almost works, but, as you can see, it is pretty buggy (especially if the mouse is on the left rocket (it seems to work fine if it moves to the right).

http://projectavian.com/rocket.swf

Here is my Rocket class:

package { import flash.display.Sprite; import flash.geom.Point; import flash.events.Event; public class Rocket extends Sprite { // vars public var target:Point; private const _vel:Number = 5; private const _steer:Number = Math.PI / 36; private var _destAng:Number = 0; private var _ang:Number = 0; private var _xv:Number = 0; private var _yv:Number = 0; /** * Constructor */ public function Rocket() { // temp graphics graphics.lineStyle(2, 0); graphics.lineTo(26, 0); addEventListener(Event.ENTER_FRAME, _handle); } /** * Called on dispatch of Event.ENTER_FRAME */ private function _handle(e:Event):void { _destAng = _getAng(); _xv = Math.cos(_ang) * _vel; _yv = Math.sin(_ang) * _vel; x += _xv; y += _yv; if(_ang > _destAng) _ang -= _steer; if(_ang < _destAng) _ang += _steer; rotation = _ang * 180 / Math.PI; } /** * Get the angle to target */ private function _getAng():Number { if(target) { var yp:Number = target.y - y; var xp:Number = target.x - x; return Math.atan2(yp, xp); } return 0; } } } 

I assume that this logic does not support everything that makes the rocket act strangely, moving to the left:

 if(_ang > _destAng) _ang -= _steer; if(_ang < _destAng) _ang += _steer; 

Here is the code I used to create the Rocket, if useful:

 var point:Point = new Point(); var rocket:Rocket = new Rocket(); rocket.target = point; addChild(rocket); addEventListener(Event.ENTER_FRAME, _handle); function _handle(e:Event):void { point.x = mouseX; point.y = mouseY; } 
+4
source share
2 answers

This should work for you.

 public class Rocket extends Sprite { // vars public var target:Point; private const _vel:Number = 5; private const _steer:Number = Math.PI / 36; private var _destAng:Number = 0; private var _ang:Number = 0; private var _xv:Number = 0; private var _yv:Number = 0; public const SPEED:uint = 50; // TODO: get this from fixed timespet public const TIME_DELTA:Number = 0.05; public const RAD:Number = 57.2957795; public const DEG:Number = 0.0174532925; public function Rocket() { // temp graphics graphics.lineStyle(2, 0); // body should follow head graphics.moveTo(-26, 0); graphics.lineTo(0, 0); addEventListener(Event.ENTER_FRAME, _handle); } /** * Called on dispatch of Event.ENTER_FRAME */ private function _handle(e:Event):void { var a:Number = _turnToFace(new Point(x, y), target, this.rotation * Math.PI / 180, 0.1); var dirX:Number = Math.cos(a); var dirY:Number = Math.sin(a); x += (dirX) * SPEED * TIME_DELTA; y += (dirY) * SPEED * TIME_DELTA; rotation = a * RAD; } private function _turnToFace(p:Point, f:Point, ca:Number, turnSpeed:Number):Number { var xp:Number = fx - px; var yp:Number = fy - py; var desiredAngle:Number = Math.atan2(yp, xp); var difference:Number = _wrapAngle(desiredAngle - ca); difference = Math.max(-turnSpeed, Math.min(turnSpeed, difference)); return _wrapAngle(ca + difference); } private function _wrapAngle(radians:Number):Number { var pi2:Number = Math.PI * 2; while(radians < -Math.PI) radians += pi2; while(radians > Math.PI) radians -= pi2; return radians; } } 
+3
source

I found this code here

Missile_speed = 20;

Missile_turning = 6;

dx = Target._x-Missile._x; do = Target._y-Missile._y;

distance = Math.sqrt ((dx * dx) + (* do du));

dx / = distance; d / = distance;

uh + = dx * Missile_turning; yy + = do * Missile_turning;

speed = Math.sqrt ((yy * Vx) + (yy * yy));

if (speed> Missile_speed) {yh = (yh * Missile_speed) / speed; yy = (yy * Missile_speed) / speed; }

Missile._x + = wow; Missile._y + = VY;

With a little small change (calling functions, basic things like this), this should be what you need.

+1
source

All Articles