Actionscript 3 as3向Y轴上的函数抖动移动

Actionscript 3 as3向Y轴上的函数抖动移动,actionscript-3,Actionscript 3,正如标题所示,我已经写了一个函数,除了它在Y轴上抖动外,它工作得非常好 问题 当函数在Y轴上运行,且起始值和目标值之间的差值小于起始值和返回值之间的差值时,会发生这种情况,这意味着该值已超过其目标值。在这一点上,应该将返回值设置为目标值,但在大多数情况下不是这样。除非它在x轴上运行,在这种情况下,它工作正常。真奇怪 代码 下面是我用于函数的代码: public static function LookAt(thisX:Number, thisY:Number, targetX:Number, t

正如标题所示,我已经写了一个函数,除了它在Y轴上抖动外,它工作得非常好

问题 当函数在Y轴上运行,且起始值和目标值之间的差值小于起始值和返回值之间的差值时,会发生这种情况,这意味着该值已超过其目标值。在这一点上,应该将返回值设置为目标值,但在大多数情况下不是这样。除非它在x轴上运行,在这种情况下,它工作正常。真奇怪

代码 下面是我用于函数的代码:

public static function LookAt(thisX:Number, thisY:Number, targetX:Number, targetY:Number, speed:Number = 0, startRot:Number = 0):Number
{
    // Get the distances between the two parsed points
    var xDif:Number = targetX - thisX;
    var yDif:Number = targetY - thisY;

    // Use a tangent formula to get the rotation to return in radians, then convert to degrees
    var rot:Number = Math.atan2(xDif, yDif) * 180/Math.PI * -1 - 180;

    // If a speed has been parsed
    if (speed != 0)
    {
        // Ensure the parsed starting rotation is between -180 and 180
        while (startRot > 180)
        {startRot -= 360;}
        while (startRot < -180)
        {startRot += 360;}

        // If the rotation previously calculated is less than the parsed starting rotation, 
        // return the starting rotation minus the speed. Otherwise, return the starting rotation
        // plus the speed
        return (rot > startRot) ? startRot + speed : startRot - speed;
    }
    else
    {
        return rot;
    }
}

public static function PointAround (axisPos:Number, angle:Number, speed:Number, axis:String = "x"):Number
{
    // Convert the parsed angle into radians
    var fixedRot = angle * Math.PI / 180;

    // Return the parsed position plus speed multiplied by the sine of the angle in radians for the x axis,
    // or the cosine of the angle in radians for the y axis
    return (axis == "x") ? axisPos + speed * Math.sin(fixedRot) : axisPos + speed * Math.cos(fixedRot) * -1;
}

public static function PointTowards(thisX:Number, thisY:Number, targetX:Number, targetY:Number, speed:Number, axis:String = "x"):Number
{
    // Use the LookAt function to calculate a rotation for later use in this function
    var workingAngle:Number = ExtraMath.LookAt (thisX, thisY, targetX, targetY);
    var toReturn;

    var thisVar:Number = (axis == "x") ? thisX : thisY;
    var targetVar:Number = (axis == "x") ? thisX : thisY;

    toReturn = ExtraMath.PointAround (thisVar, workingAngle, speed);
    // BUGGY LINE
    toReturn = (thisVar >= targetVar && toReturn <= targetVar
                || thisVar <= targetVar && toReturn >= targetVar)
                ? targetVar
                : toReturn;

    return toReturn;
}
我已经试过了
  • 将该行转换为正则的if语句(带有花括号和all),并在对其进行操作后跟踪变量thisY、targetY和toReturn。真正让人恼火的是,它有时会返回正确的数字,但随后会再次出错
  • 在测试中使用绝对值而不是stage.mouseY。错误照常发生
  • 在X轴之前的Y轴上执行该功能。没有区别
  • 更改将变量thisVar和targetVar设置为(axis!=x)并切换if/else值的条件。改变

可能是一些因素造成了问题:


这可能会导致超调。如果
rot
startRot
仅略有不同,则您仍在添加(或减去)一个完整的
速度增量。如果
rot
startRot
之间的绝对距离小于
speed
,则无论如何,它都应返回
rot

这减少了角度抖动


注意运算符优先级。您希望此行被解析为

(axis == "x") ?
                (axisPos + speed * Math.sin(fixedRot)) :
                (axisPos + speed * Math.cos(fixedRot) * -1);
但情况可能并非如此。这一行可以解释为

(
 (axis == "x") ?
                 (axisPos + speed * Math.sin(fixedRot)) :
                  axisPos
)
+ speed * Math.cos(fixedRot) * -1;
你可以记住所有的优先规则,并确保你永远不会弄错它们,或者加上括号以确保它做的是正确的事情。在这种情况下,可以将表达式简化为

axisPos + speed * (axis == "x" ? Math.sin(fixedRot) ? -Math.cos(fixedRot))

那么
thisVar
targetVar
总是具有相同的值?我不明白这里应该发生什么,而且似乎没有人在以后重新分配这些变量


在每个轴上分别更改位置。它可能会起作用,但更难,更容易出错。比如说

c.x = ...PointTowards(c.x ...);
c.y = ...PointTowards(c.x ...);
您正在两次调用之间更改
c.x
的值,因此对
的第一次调用指向
查看与第二次调用不同的点。这可能就是抖动只发生在
y
轴上的原因。我建议立即创建一个处理box轴的函数,或者至少存储
c.x
c.y
的旧值:

var oldX:Number = c.x;
var oldY:Number = c.y;
c.x = ExtraMath.PointTowards(oldX, oldY, stage.mouseX, stage.mouseY, 5);
c.y = ExtraMath.PointTowards(oldX, oldY, stage.mouseX, stage.mouseY, 5, "y");

我修好了!我将函数更改为返回一个点对象而不是一个数字,现在它工作得非常好

感谢您的回答!将targetVar设置为起始变量是一个输入错误,应该将其设置为targetX或targetY我忘了提到我曾经尝试过存储旧的位置值并解析它们,但是仍然不起作用
axisPos + speed * (axis == "x" ? Math.sin(fixedRot) ? -Math.cos(fixedRot))
var thisVar:Number = (axis == "x") ? thisX : thisY;
var targetVar:Number = (axis == "x") ? thisX : thisY;
c.x = ExtraMath.PointTowards(c.x, c.y, stage.mouseX, stage.mouseY, 5);
c.y = ExtraMath.PointTowards(c.x, c.y, stage.mouseX, stage.mouseY, 5, "y");
c.x = ...PointTowards(c.x ...);
c.y = ...PointTowards(c.x ...);
var oldX:Number = c.x;
var oldY:Number = c.y;
c.x = ExtraMath.PointTowards(oldX, oldY, stage.mouseX, stage.mouseY, 5);
c.y = ExtraMath.PointTowards(oldX, oldY, stage.mouseX, stage.mouseY, 5, "y");