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