0

私の XNA ゲームでは、A キーと D キーを使用してスプライトを回転させることができ、すべてうまく機能します。しかし、私の問題に:

スプライトが傾いている方向にスプライトを移動するために X と Y を計算する方法は次のとおりです。

 float x = (float)Math.Cos(MathHelper.ToRadians(getRotation()));
 float y = (float)Math.Sin(MathHelper.ToRadians(getRotation()));

しかし、それはまったく機能していません。Wキーを押すたびに+4ピクセルのようにスプライトを移動したい。

4

3 に答える 3

2

もう少しです:

sprite.x += ( float ) ( Math.Cos( MathHelper.ToRadians( getRotation( ) ) ) * speedX );
sprite.y += ( float ) ( Math.Sin( MathHelper.ToRadians( getRotation( ) ) ) * speedY );
于 2013-02-18T19:37:26.613 に答える
0

@BlackBearが指摘したように、回転に移動したい距離を掛ける必要があります。

この種の作業をしているときは、基本(加算、スケーリング、回転、角度の決定など)をカプセル化するポイント(またはベクトル)クラスを用意し、ベクトルの観点から動きを視覚化すると便利です。

たとえば、機能的なPoint2Dクラスがあるとします。

// define movement vector as +4 units in 'Y' axis
// rotated by player facing
Point2D MoveVector = new Point2D(0, 4).Rotate(Player.FacingAngle);

// adjust player position by movement vector:
Player.Position.Add(MoveVector);

2D座標にマッピングする必要がある場合はいつでも使用できる方向ベクトルを、プレーヤーに含めることをお勧めします。動きは次のようになります:

Player.Position.Add(Player.FacingVector * MoveSpeed);

これは、弾丸のスポーンなどに便利です。最初の向きのベクトルをプレーヤーの向きのベクトルなどに設定できるため、チェーン全体の回転操作を節約できます。

そして、あなたはあなたのコードがもう少し自己文書化するという追加のボーナスを手に入れます:P

編集-一連のコード:

これが私のPoint2D実装の一部です:

public class Point2D
{
    public double X;
    public double Y;

    public Point2D(double X = 0, double Y = 0)
    {
        this.X = X;
        this.Y = Y;
    }

    // update this Point2D by adding other
    public Point2D AddEquals(Point2D other)
    {
        X += other.X;
        Y += other.Y;
        return this;
    }

    // return a new Point2D that is the sum of this and other
    public Point2D Add(Point2D other)
    {
        return new Point2D(X + other.X, Y + other.Y);
    }

    public Point2D Multiply(double scalar)
    {
        return new Point2D(X * scalar, Y * scalar);
    }

    // rotate by angle (in radians)
    public Point2D Rotate(double angle)
    {
        double c = Math.cos(angle), s = Math.sin(angle);
        double rx = X * s - Y * c;
        double ry = Y * s + X * c;
        return new Point2D(rx, ry);
    }

    public Point2D RotateDegrees(double angle)
    {
        return Rotate(angle * Math.PI / 180);
    }

    public double Distance(Point2D other)
    {
        double dx = other.X - X, dy = other.Y - Y;
        return Math.Sqrt(dx * dx + dy * dy);
    }
}

他の操作を具体化することができます。このコードには、これらのもので十分です。

public class Player
{
    public Point2D location;
    // facing angle in degrees
    public double facing;

    public void TurnLeft(double degrees)
    {
        facing = (facing + 360 - degrees) % 360;
    }

    public void TurnRight(double degrees)
    {
        facing = (facing + degrees) % 360;
    }

    public void MoveForward(double distance)
    {
        // calculate movement vector
        Point2D move = new Point2D(0, distance).RotateDegrees(facing);

        // add to position
        this.location.AddEquals(move);
    }
}

名前は場所によっては少し不器用ですが、それはあなたにアイデアを与えるはずです。

于 2013-02-18T20:02:41.290 に答える
0
//Define what is forward when rotation is 0.
var forward = new Vector2(1f,0f);

//Create a rotation-matrix that can rotate the forward-vector
var rotater = Matrix.CreateRotationZ(MathHelper.ToRadians(getRotation()));

//rotate and normalize vector (normalizing makes the length = 1)
forward = Vector2.TransformNormal(forward, rotater);

//move in rotated forward direction times 4
Position += forward * 4f; 

しかし、1 秒あたりのピクセル値を使用し、deltatime を乗算することをお勧めします。

Position += forward * pixelsPerSecond * (float)gameTime.ElapsedGameTime.TotalSeconds;
于 2013-02-21T08:04:43.137 に答える