1

これは単純なトリグの質問のように思えますが、何らかの理由で物事がうまくいきません。

ユーザーがA / Dキーを押したときに、オブジェクトを特定のポイントを中心に回転させようとしています(マウスに直面したまま、円を描くようにマウスを動かします)。

これまでに試したコードは次のとおりです(すべての数学関数はラジアンを受け取って返します):

if (_inputRef.isKeyDown(GameData.KEY_LEFT))
{
    x += 2 * Math.cos(Math.atan2(mouseY - y, mouseX - x) - Math.PI * 0.5);
    y += 2 * Math.sin(Math.atan2(mouseY - y, mouseX - x) - Math.PI * 0.5);
}
else if (_inputRef.isKeyDown(GameData.KEY_RIGHT))
{
    x += 2 * Math.cos(Math.atan2(mouseY - y, mouseX - x) + Math.PI * 0.5);
    y += 2 * Math.sin(Math.atan2(mouseY - y, mouseX - x) + Math.PI * 0.5);
}

そして、同じことを達成するよりエレガントな方法:

if (_inputRef.isKeyDown(GameData.KEY_LEFT))
{
    x += 2 * Math.sin(Math.atan2(mouseY - y, mouseX - x));
    y -= 2 * Math.cos(Math.atan2(mouseY - y, mouseX - x));
}
else if (_inputRef.isKeyDown(GameData.KEY_RIGHT))
{
    x -= 2 * Math.sin(Math.atan2(mouseY - y, mouseX - x));
    y += 2 * Math.cos(Math.atan2(mouseY - y, mouseX - x));
}

現在、どちらも機能しており、オブジェクトは常にマウスの方を向いたままマウスの周りを回転しますが、機銃掃射ボタンを十分に押し続けると、オブジェクトがマウスから離れて回転していることがますます明らかになります。押しのけました。

これがなぜなのか、それを修正する方法がわかりません。

どんな洞察も大歓迎です!

4

1 に答える 1

1

あなたの現在のアプローチは、「無限に小さい」ステップを踏む場合にのみ機能すると思います。現在のように、各動きは「to-mouse vector」に対して垂直であるため、マウスとオブジェクトの間の距離が長くなります。

解決策は、マウスを中心に位置を回転させることにより、マウスまでの距離を変更せずに新しい位置を計算することです。

// position relative to mouse
var position:Point = new Point(
    x - mouseX,
    y - mouseY);

var r:Number = position.length; // distance to mouse

// get rotation angle around mouse that moves
// us "SPEED" unit in world space
var a:Number = 0;
if (/* LEFT  PRESSED */) a = getRotationAngle( SPEED, r);
if (/* RIGHT PRESSED */) a = getRotationAngle(-SPEED, r);
if (a > 0) {

    // rotate position around mouse
    var rotation:Matrix = new Matrix();
    rotation.rotate(a);
    position = rotation.transformPoint(position);
    position.offset(mouseX, mouseY);

    x = position.x;
    y = position.y;
}

// elsewhere...

// speed is the distance to cover in world space, in a straight line.
// radius is the distance from the unit to the mouse, when rotating.
private static function getRotationAngle(speed:Number, radius:Number):Number {
    return 2 * Math.asin(speed / (2 * radius));
}

上記は aを使用して、マウス位置を中心Matrixに位置を回転させます。(x, y)もちろん、必要に応じて、使用せずに同じ原則を適用することもできますMatrix

正しい角度を得るための正しい式を考え出すために、いくつかのトリグを行う必要がありました。角度は移動円弧の半径に依存します。これは、半径が大きくても角度が一定であると移動距離が長くなるためです (望ましくない動作)。私の以前の解決策 (編集前) は、角度を半径でスケーリングすることでしたが、それでも半径が大きくなると動きがわずかに大きくなります。

現在のアプローチでは、すべてのケースで半径と速度が一定に保たれます。

于 2012-06-07T14:56:57.487 に答える