来自坐标对的 2D 射弹运动

2D projectile movement from coordinate pair

因此,我试图按照鼠标在屏幕上的位置所指示的方向移动弹丸。我已经将鼠标坐标转换为游戏中的坐标,但是我不知道如何正确地将射弹移动到正确的方向。我正在尝试使用斜坡来移动射弹,但它似乎不想抓住正确的斜坡,所以我最终让它们飞向完全错误的方向。这是我正在使用的一些代码。 任何帮助都将不胜感激,因为我对此有点不知所措。

注意:射弹不会跟随鼠标。它应该保存坐标,然后朝那个方向前进,注意它也可以以相同的速度经过给定的坐标。

实体创建

int[] mousePos = MouseManager.getCalculatedMouseCoordinates();
                float deltaX = mousePos[0] - GameManager.x;
                float deltaY = mousePos[1] - GameManager.y;
                float m = deltaY/deltaX;
                System.out.println(m);
                GameManager.currentWorld.addEntity(new EntityProjectile(GameManager.x, GameManager.y, 30, m, 50, "fireball"));

投射物Class

    package UnNamedRpg.Player.Entity;

public class EntityProjectile {

    private double x, y;
    private int entityID = -1;
    private int speed;
    private double headerX, headerY;
    private int renderHeading;
    private double range, currentRange = 0;
    private String texture;
    private double factor = -1;
    public EntityProjectile(double startX, double startY, int speed, double headerX, double headerY, double range, String texture){
        setX(startX);
        setY(startY);
        setSpeed(speed);
        setHeaderX(headerX);
        setHeaderY(headerY);
        setTexture(texture);
        setRange(range);
    }

    public void doTick(){
        double vx = this.x - this.headerX;
        double vy = this.y - this.headerY;
        if(this.factor == -1){
            double length = Math.sqrt((vx*vx) + (vy*vy));
            double factor = this.speed / length;
            this.factor = factor;
        }
        vx *= factor;
        vy *= factor;
        this.x = vx;
        this.y = vy;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getRenderHeading() {
        return renderHeading;
    }

    public void setRenderHeading(int renderHeading) {
        this.renderHeading = renderHeading;
    }

    public int getEntityID() {
        return entityID;
    }

    public void setEntityID(int entityID) {
        this.entityID = entityID;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String getTexture() {
        return texture;
    }

    public void setTexture(String texture) {
        this.texture = texture;
    }

    public double getRange() {
        return range;
    }

    public void setRange(double range) {
        this.range = range;
    }

    public double getCurrentRange() {
        return currentRange;
    }

    public void setCurrentRange(double currentRange) {
        this.currentRange = currentRange;
    }

    public double getHeaderX() {
        return headerX;
    }

    public void setHeaderX(double headerX) {
        this.headerX = headerX;
    }

    public double getHeaderY() {
        return headerY;
    }

    public void setHeaderY(double headerY) {
        this.headerY = headerY;
    }

    public double getFactor() {
        return factor;
    }

    public void setFactor(double factor) {
        this.factor = factor;
    }
}

更新位置方法

--现在在 EntityProjectile 中调用 class 每个 tick 而不是在世界 tick 中发生。

通过一些基本的矢量数学,向给定点移动相对简单。您要移动的矢量只需通过坐标减法即可计算得出:

vx = objectX - mouseX
vy = objectY - mouseY

但您可能希望将对象移动得比 bam 慢一点 ,因此您需要将矢量缩放到所需的长度(等于每个游戏刻度的速度)。 vector的current长度通过勾股sqrt(a * a + b * b)得到。要将向量缩放到给定长度,只需将分量乘以所需的因子:

double targetLength = 5.0; // chosen arbitrarily
double length = Math.sqrt(vx * vx + vy * vy);
double factor = targetLength / length;
vx *= factor;
vy *= factor;

你有你的速度分量 x,y 用作每个游戏刻度的增量。 5.0 是对象每刻移动的 "speed"。

编辑:@Cyphereion 关于向量的 长度 ,从几何学上讲三角形的底边,参见 https://en.wikipedia.org/wiki/Pythagorean_theorem(被认为是常识)。

一旦你有了它,你只需要通过计算出一个比例因子来调整每个组件的长度,使基线成为所需的 "speed" 长度。组件 (vx, vy) 的原始值表示一个 向量 (请参阅:https://en.wikipedia.org/wiki/Euclidean_vector#Representations)编码要移动到的方向。

当您将矢量分量作为增量应用到其位置(这只是矢量加法)时,缩放矢量的长度会调整对象移动的速度。我最初交换了分区 length/targetLength(现在已修复),因此速度变量具有相反的含义(更大 = 更慢而不是更大 = 更快)。

如果您的 sprite 有问题,请使用那里的 setDirection() 来增加轨迹。在这些示例中,您拥有所有好的代码,但您缺少在鼠标改变方向时保持方向。这就是我所能看到的。祝你好运!