as3在Y轴上向功能抖动方向移动

时间:2015-10-29 13:08:50

标签: actionscript-3

正如标题所暗示的那样,我已经写出了一个完全正常的功能,除了它在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;
}

以及我用来测试它的代码:

public var c:Sprite;

public function TestZone() 
{
    // constructor code
    stage.addEventListener(Event.ENTER_FRAME, Update);
}

private function Update (e:Event):void
{
    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");
}

我已经尝试过的事情

  • 将该行转换为带有大括号和all的常规if语句,并在操作后跟踪变量thisY,targetY和toReturn。真正讨厌的事情是它有时会实际返回正确的数字,但后来再次出错了
  • 在测试中使用绝对值而不是stage.mouseY。像往常一样发生错误
  • 在X轴之前在Y轴上执行功能。没有区别
  • 更改将变量thisVar和targetVar设置为(axis!= x)并切换if / else值的条件。做差异

2 个答案:

答案 0 :(得分:0)

有些事情可能导致问题:

document.getElementById("formID").submit

这可能会导致过冲。如果[LookAt] return (rot > startRot) ? startRot + speed : startRot - speed; rot仅略有不同,则您仍在添加(或减去)完整startRot增量。如果speedrot之间的绝对距离小于startRot,则无论如何都应返回speed

这可以减少角度抖动。

rot

注意运营商优先权。您希望将此行解析为

[PointAround]
return (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);

你可以记住所有的优先规则,并确保你永远不会弄错它们,或者用括号括起来确保它做正确的事情。在这种情况下,您可以将表达式简化为

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

所以var thisVar:Number = (axis == "x") ? thisX : thisY; var targetVar:Number = (axis == "x") ? thisX : thisY; thisVar总是有相同的价值?我不明白这里应该发生什么,以后似乎没有人重新分配这些变量。

targetVar

您正在每个轴上单独更改位置。它可能有用,但它更难以容易出错。例如

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 ...); 的值,因此第一次呼叫c.x会看到与第二次呼叫不同的点。这可能是抖动仅发生在PointTowards轴上的原因。我建议立即创建一个处理box轴的函数,或者至少存储yc.x的旧值:

c.y

答案 1 :(得分:0)

我修好了!我更改了函数以返回一个点对象而不是一个数字,现在它完美地运行