Рассчитать траекторию объекта, зная угол и скорость во вспышке.

Я пытаюсь запустить пушечное ядро ​​​​из пушки и заставить его следовать реалистичному пути. Угол обстрела меняется в зависимости от ориентации пушки (автоматически ориентируется на указатель мыши). Итак, я пытаюсь понять, как двигать пушечное ядро ​​по параболической траектории, имея заданный угол и заданную скорость.

Я читал, что это можно сделать без сложной тригонометрии (никогда не слушал ее в старшей школе), и можно рассчитать, просто добавляя гравитацию к yVelocity каждый тик. Однако на данный момент я не знаю, как рассчитать начальную скорость yVelocity (опять же, в зависимости от ориентации пушки).

Текущую анимацию можно посмотреть здесь: http://kate.ict.op.ac.nz/~welfajw1/portfolio/videos/task3-assignment2.swf

Все это делается в AS3, и у меня есть следующий код:

Код основной временной шкалы:

import flash.display.*;
import flash.events.*;
import flash.geom.*;

var cannonball:ball_mc;
var angleDegree;

myCannon.addEventListener(Event.ENTER_FRAME, cannonEnterFrame);

function cannonEnterFrame(pEvt)
{
    var mc = myCannon;
    var mg = myCannon.myGun;

    //find angle for orientation
    var angleRadian = Math.atan2(mouseY - mc.y, mouseX - mc.x);

    //convert to degrees
    angleDegree = angleRadian * 180 / Math.PI;

    //limit rotation
    if(angleDegree > -63 && angleDegree < 20)
        mg.rotation = angleDegree;
}

stage.addEventListener(Event.ENTER_FRAME, stageRefresh);

function stageRefresh(pEvt)
{
    if (cannonball)
    {
        //move every "tick"
        cannonball.move();
    }
}

stage.addEventListener(MouseEvent.CLICK, mouseClicked);

function mouseClicked(pEvt)
{
    //starting position of the ball
    cannonball = new ball_mc(100, 475);

    //SEND IN INITIAL x, y VELOCITIES
    cannonball.fire(20, angleDegree);

    //add to stage
    stage.addChild(cannonball);
}

код ball_mc:

package 
{

    import flash.display.MovieClip;
    import flash.sensors.Accelerometer;
    import flashx.textLayout.formats.Float;


    public class ball_mc extends MovieClip
    {
        //constant gravity
        public static const g:Number = 2;

        //starting velocities
        private var ux:Number;
        private var uy:Number;

        public function ball_mc(startX:int, startY:int)
        {
            x = startX;
            y = startY;
        }

        public function fire(vx:Number, vy:Number):void
        {
            ux = vx;
            uy = vy;
        }

        public function move():void
        {
            //distance moved in x dir
            var sx:Number = ux; 
            //new velocity in y dir
            var vy:Number = uy + g;
            //distance moved in y dir
            var sy:Number = uy + g/2;

            //apply movement
            x += sx;
            y += sy;

            //save new y velocity
            uy = vy;
        }
    }
}

person JohnW    schedule 16.09.2012    source источник


Ответы (1)


Вам нужно немного физики.

Начальная скорость должна быть рассчитана с использованием некоторых критериев, которые вы добавляете самостоятельно. Одним из примеров является вычисление начальной скорости с использованием расстояния между мышью и пушкой в ​​момент нажатия кнопки мыши. Если расстояние больше, снаряд будет иметь большую скорость, а если расстояние меньше, снаряд будет иметь меньшую скорость.

Вы добавляете прослушиватель событий с типом ENTER_FRAME.

Я предполагаю, что это двухмерная анимация, поэтому вам нужно найти текущие x и y в любой момент времени.

Вот немного кода:

var TimeperFrame:Number = 1/fps //fps is not a constant, here you should add a number, a value that you previously added in fla. document properties. I usualy use 60 fps
var Time:Number = 0;

addEventListener(ENTER_FRAME, movingCannonBall);
function movingCannonBall(e:Event):void
{
   Time += TimeperFrame;
}

Теперь вот уравнение траектории снаряда.

х = хо + vxo·t

y = yo + vyo·t - 0,5·g·t^2

yo = начальная высота вашего пушечного ядра

vyo = начальная скорость y; vyo = vo·sin θ

t = прошло время, мы контролируем это по верхнему коду

g = ускорение (9,81 м/с^2) у поверхности Земли

xo = начальное расстояние для старта

vxo = начальная скорость x; vxo = vo·cos θ

Теперь в верхнем коде мы добавляем эти уравнения, и это должно выглядеть так:

var TimeperFrame:Number = 1/fps
var Time:Number = 0;
var initx: Number = cannonball.x;
var inity: Number = cannonball.y;
var initVelocity: Number = (you define initial Velocity by your criteria)
var G: Number = 9.81;

addEventListener(ENTER_FRAME, movingCannonBall);
function movingCannonBall(e:Event):void
{
   Time += TimeperFrame;
   cannonball.x = initx + Math.cos(angle) * initVelocity * Time;
   cannonball.y = inity + Math.sin(angle) * initVelocity * Time - G * Time * Time * 0.5
}

Это должно работать. Я использовал этот код много раз, и он эффективен, а также прост.

person Stefan4024    schedule 16.09.2012
comment
Вроде работает. Проблема с этим кодом заключается в том, что во Flash используется система координат, противоположная генерируемым дугам. Следовательно, объект выстрела опускается вниз (во время восходящей дуги, когда пушечное ядро ​​y увеличивается), а затем вверх (когда пушечное ядро ​​y уменьшается). Должен быть способ перевода в систему координат Flash. - person Factor Three; 28.03.2014