【问题标题】:Moving an object based on its rotation根据对象的旋转移动对象
【发布时间】:2021-11-11 12:40:22
【问题描述】:

我有这个船精灵(现在是原型),我一直试图沿着它的旋转移动它,但它运行得不太好。

https://imgur.com/a/gd1ac7O
在研究时,我看到有时余弦用于 x 位置,而正弦用于 y 位置,这让我有点困惑该怎么做。但有时我看到的不是这样,这让我想知道,因为我认为 x 应该使用正弦而 y 应该是余弦

代码:

package com.lance.seajam;

import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.Gdx;
import java.lang.Math;

public class Player {
    private final float rotSpeed;
    private final float movementSpeed;

    private final Texture texture;
    private final int textureWidth;
    private final int textureHeight;
    private final SpriteBatch batch;
    private Vector2 position;
    private int rotation;
    private float originX;
    private float originY;
    private int realRot;

    private double DEG2RAD = 180 / Math.PI;

    public Player(Texture texture, SpriteBatch batch) {
        this.texture = texture;
        this.batch = batch;
        this.rotation = 0;
        this.textureWidth = texture.getWidth();
        this.textureHeight = texture.getHeight();
        this.position = new Vector2(300, 300);

        this.originX = textureWidth/2;
        this.originY = textureHeight/2;
        this.rotSpeed = 3f;
        this.movementSpeed = 3f;
    }

    public void Movement() {
        if (Gdx.input.isKeyPressed(Keys.A)) rotation += rotSpeed;
        if (Gdx.input.isKeyPressed(Keys.D)) rotation -= rotSpeed;

        realRot = rotation;

        if (rotation >= 360) realRot = 360;
        if (rotation <= 0) realRot = 0;

        double xVel = 0;
        double yVel = 0;

        xVel += Math.cos(realRot) * movementSpeed;
        yVel += Math.sin(realRot) * movementSpeed;

        if (Gdx.input.isKeyPressed(Keys.W)) {
            position.x += xVel;
            position.y += yVel;
        }

        System.out.println(xVel);
    }

    public void DrawSprite() {
        batch.draw (
            texture, position.x, position.y,
            originX, originY, textureWidth,
            textureHeight, 1, 1,
            rotation, 1, 1, textureWidth,
            textureHeight, false, false
        );
    }
}

【问题讨论】:

  • 有些奇怪:你总是修改速度,但只有在按下按钮时才真正移动对象?这似乎完全是错误的方法:您只想在按下按钮时更改速度,但始终更改位置(假设您想要惯性,这是您的代码和视频所建议的)。
  • sin 是垂直的,cosin 是水平的(只要你从水平轴取角度)。
  • 另外:您不想将旋转“钳制”到 0/360,而是希望它从 > 360“滑过”到略高于 0。即while (rotation &gt; 360) rotation -= 360。否则你会在朝北时得到一个奇怪的“停止”,并且那里的旋转不会平滑。
  • @JoachimSauer 谢谢你提供的信息!

标签: java libgdx


【解决方案1】:

如果您在Player 类中创建一个额外的Vector2 成员direction,您可以获得libGDX 以使用rotateDeg 计算x 和y 增量Vector2上的方法:

direction.set(Vector2.X).rotateDeg(realRot);

这会将direction 设置为(1, 0),然后按您的旋转量旋转它。 然后,您只需将direction.x 和direction.y 添加到您的position。

position.x += direction.x;
position.y += direction.y;

甚至更短:

position.add(direction);

以上动画Player的完整来源是:

public class Player {
    private final float rotSpeed;
    private final float movementSpeed;

    private final Texture texture;
    private final int textureWidth;
    private final int textureHeight;
    private final SpriteBatch batch;
    private Vector2 position;
    private Vector2 direction = new Vector2(Vector2.X); // Add this
    private int rotation;
    private float originX;
    private float originY;
    private int realRot;

    private double DEG2RAD = 180 / Math.PI;

    public Player(Texture texture, SpriteBatch batch) {
        this.texture = texture;
        this.batch = batch;
        this.rotation = 0;
        this.textureWidth = texture.getWidth();
        this.textureHeight = texture.getHeight();
        this.position = new Vector2(0, 0);

        this.originX = textureWidth/2;
        this.originY = textureHeight/2;
        this.rotSpeed = 3f;
        this.movementSpeed = 3f;
    }

    public void Movement() {
        if (Gdx.input.isKeyPressed(Input.Keys.A)) rotation += rotSpeed;
        if (Gdx.input.isKeyPressed(Input.Keys.D)) rotation -= rotSpeed;

        realRot = rotation;

        // You don't really need this
        //if (rotation >= 360) realRot = 360;
        //if (rotation <= 0) realRot = 0;

        // At each update, set the direction vector to point to the right, and then rotate
        // it using your readRot variable.
        direction.set(Vector2.X).rotateDeg(realRot);

        direction.scl(movementSpeed); // Scale the direction by you speed

        if (Gdx.input.isKeyPressed(Input.Keys.W)) {
            position.x += direction.x;
            position.y += direction.y;
        }
    }

    public void DrawSprite() {
        batch.draw (
                texture, position.x, position.y,
                originX, originY, textureWidth,
                textureHeight, 1, 1,
                rotation, 1, 1, textureWidth,
                textureHeight, false, false
        );
    }
}

【讨论】:

    猜你喜欢
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    相关资源
    最近更新 更多