Самонаводящаяся ракета в AS3 - PullRequest
4 голосов
/ 12 мая 2011

Я пытаюсь создать самонаводящуюся ракету в AS3.Достаточно легко, когда вы хотите, чтобы она просто точно следовала точке - но я пытаюсь заставить ракету развернуться, если цель (цель) обходит ее.

Вот что у меня есть - это почтиработает, но, как вы можете видеть, это довольно глючно (особенно если мышь находится на влево ракеты (кажется, работает нормально, если она движется вправо).

http://projectavian.com/rocket.swf

Вот мой класс по Ракете:

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;
        }
    }
}

Я предполагаю, что эта логика не учитывает то, что заставляет ракету действовать странно, двигаясь влево:

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

Здесьэто также код, который я использовал для создания моей ракеты, если это полезно:

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;
}

Ответы [ 2 ]

3 голосов
/ 12 мая 2011

Это должно работать для вас.

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 = f.x - p.x;
        var yp:Number = f.y - p.y;

        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;
    }
}
1 голос
/ 12 мая 2011

Я нашел этот код здесь

Missile_speed = 20;

Missile_turning = 6;

дх = Target._x-Missile._x; ду = Target._y-Missile._y;

расстояние = Math.sqrt ((дх * дх) + (* ду ду));

дх / = расстояние; д / = расстояние;

ъх + = дх * Missile_turning; уу + = ду * Missile_turning;

скорость = Math.sqrt ((ух * Vx) + (уу * уу));

if (скорость> Missile_speed) { ух = (ух * Missile_speed) / скорость; уу = (уу * Missile_speed) / скорость; }

Missile._x + = ух; Missile._y + = VY; * * тысяча двадцать один

С небольшими изменениями (вызов функций, базовые вещи вроде этого) это должно быть то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...