如何在AS3中使用抛物线公式来触发始终拦截给定点的箭头

Mar*_*rty 5 math flash physics actionscript-3

首先要注意:从数学上讲,我根本不熟练.

我在iPhone上玩了一个游戏,你按下了一个点,箭头从你的城堡开始,它总是与你按下的点相交.我想做一个类似的游戏,认为这将是一个简单的快速制作; 然后我意识到这个数学实际上超出了我的技能水平.

我假设他们正在使用一个抛物线公式或某些东西来确定箭头启动时所需的速度和角度,以使箭头始终与点击的点相交.

我只是模糊地记得抛物线是如何从学校工作的,没有机会制定任何公式.

任何可能更容易实现的数学帮助或想法都会很棒.

我想最终在我的城堡中使用一个函数:

package
{
    import avian.framework.objects.AvElement;

    public class Castle extends AvElement
    {
        /**
         * Fires an arrow from this
         * @param ix The x intersection point
         * @param iy The y intersection point
         */
        public function fire(ix:Number, iy:Number):void
        {
            var ar:Arrow = new Arrow();

            ar.x = x;
            ar.y = y;

            // define angle and velocity based on ix, iy
            // ar.fireAngle = ??
            // ar.fireVelocity = ??

            parent.addChild(ar);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据评论中的问题更新:

箭头没有施加任何力,例如风,摩擦等.此外,箭头的起点在整个游戏中固定(在城堡处).

这是一个示例图像,更加清晰: 箭头路径

尽可能清楚:

  1. 箭头始终从固定点开始(例如:40,120).
  2. 箭头必须始终拦截给定的坐标.
  3. 一个尽可能现实的道路是我想要达到的目标(显然我可以直接发射箭头来拦截任何一点,但目标是让箭头先上升,然后下降;通过最逼真的所需坐标指出它的旅程).

注意:为了避免存在无限可能抛物线的问题 - 箭头的速度可以固定 - 只需看看定义箭头可以留下的角度.

meo*_*ouw 8

可以通过应用运动方程来描述射弹穿过重力场的飞行路径

我将使用的方程式

1. v = u + at
2. s = ut + (at^2)/2
Run Code Online (Sandbox Code Playgroud)

哪里

s =初始位置和最终位置之间的距离
u =初始速度
v =最终速度
a =恒定加速度
t =从初始状态移动到最终状态所需的时间

好.为了给这个箭头设置动画,我们将根据之前的速度,位置和加速度,以规则的间隔(每一帧)计算出它的新速度和位置.在这种情况下加速完全是由于重力.

让我们简化并测量帧中的时间间隔而不是秒.这使得我们t = 1的上述方程允许我们将它们重写为

1. v = u + a*1           => v = u + a
2. s = u*1 + (a*1^2)/2   => s = u + a/2
Run Code Online (Sandbox Code Playgroud)

现在在x方向加速度,a = 0(我们没有考虑拖曳).在y方向a = g,由重力引起的加速度.如果我们重新编写这些方程式以便为每个轴解析

对于x:

1. vx = ux + 0        => vx = ux (no change so we'll ignore this)
2. sx = ux + 0/2      => sx = ux (convenient eh?)
Run Code Online (Sandbox Code Playgroud)

对于y:

1. vy = uy + g
2. sy = uy + g/2 
Run Code Online (Sandbox Code Playgroud)

因此,让我们将它们插入到示例脚本中

public class Arrow extends Sprite
{
    //g is constant
    //it's actually closer to 10 but this is our world
    public static const g:Number = 2;

    //our arrow
    private var arrow:Shape;

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

    public function Arrow()
    {
        arrow = new Shape();
        arrow.graphics.lineStyle( 1, 0 );
        arrow.graphics.lineTo( 30, 0 );
    }

    public function fire( vx:Number, vy:Number ):void
    {
        ux = vx;
        uy = vy;
        addChild( arrow );
        addEventListener( Event.ENTER_FRAME, fly );
    }

    private function fly( e:Event ):void
    {
        //lets use our equations
        var sx:Number = ux;       //distance moved in x dir

        var vy:Number = uy + g    //new velocity in y dir
        var sy:Number = uy + g/2  //distance moved in y dir

        //apply to arrow
        arrow.x += sx;
        arrow.y += sy;

        //save new y velocity
        uy = vy;

        //extra bonus rotation of arrow to point in the right direction
        arrow.rotation = Math.atan2( uy, ux ) * 180 / Math.PI;

    }

}
Run Code Online (Sandbox Code Playgroud)