简体   繁体   English

以A,B的一致速度移动对象

[英]Moving an object at a consistent speed from point A to B

I'm attempting to create my own primitive 2D graphics based game engine. 我正在尝试创建自己的原始2D图形游戏引擎。 The core component of the game is firing different projectiles at enemies. 游戏的核心部分是向敌人发射不同的射弹。 I need to get this component working before I can continue working. 在我继续工作之前,我需要让这个组件工作。

What I have now moves my projectile along a line going through the Starting point (x, y) and the Target point (x1, x2). 我现在所拥有的是沿着穿过起点(x,y)和目标点(x1,x2)的线移动我的射弹。 I make use of the linear function y = mx + b . 我使用线性函数y = mx + b The problem is that how I update the position of the projectile causes an inconsistent velocity depending on the slope of the line. 问题在于我如何更新射弹的位置会导致速度不一致,具体取决于线的斜率。 (greater slopes cause it to move away more quickly). (更大的斜坡使它更快地移开)。

Here's the core structure of the game loop I'm running: 这是我正在运行的游戏循环的核心结构:

    private void executeGameLoop() 
    {

        long nextFrameStart = System.nanoTime();
        while(panel.getRunning()) 
        {
            do 
            {
                panel.update();
                nextFrameStart += FRAME_PERIOD;
            } while(nextFrameStart < System.nanoTime());

            long remaining = nextFrameStart - System.nanoTime();
            panel.repaint();

            if (remaining > 0) 
            {
                try 
                {
                    Thread.sleep(remaining / 1000000);
                } 
                catch(Throwable e) 
                {
                System.out.println(e.getMessage()); 
                }
            }
        }
    }

This is just the mechanism for updating the structure and graphics. 这只是更新结构和图形的机制。 Every time this calls panel.update the projectile updates its position, given certain circumstances. 每次调用panel.update ,在特定情况下,射弹会更新其位置。 Here are the methods that update the projectile: 以下是更新射弹的方法:

This tells the projectile it has a target and sets up information about the line. 这告诉射弹它有一个目标并设置有关该线的信息。

public void setHasTarget(boolean hasTargetIn)
    {
        if(hasTargetIn)
        {
            deltaX = getTargetX() - getX();
            deltaY = getTargetY() - getY();
            slope = deltaY / deltaX;
            intercept = getY();
            System.out.println("y = " + slope + "x + " + intercept); //line the projectile will follow
        }
        hasTarget = hasTargetIn;
    }

This next method sets the position to the next step on the line. 下一个方法将位置设置为该行的下一步。 (X is updated by velocity, y is updated dependent on x) (X由速度更新,y根据x更新)

public void setNext()
        {
            float temp = (slope) * (getX() + velocity) + intercept;
            System.out.println("Slope: " + (slope) * (getX() + velocity));
            System.out.println("Current: (" + getX() + ", " + getY() + ")");
            System.out.println("Next: (" + (getX() + velocity)  + ", " + (getY() + temp) + ")");
            setX(getX() + velocity);
            setY(temp);
        }

This last method calls setNext() and is called by the main loop. 最后一个方法调用setNext()并由主循环调用。

public void update()
        {
            if(hasTarget)
                setNext();
        }

As I've said, given my current code, the result when I run is a projectile that moves on the screen at inconsistent speeds dependent on the slope of the line. 正如我所说,根据我目前的代码,我运行时的结果是一个弹丸,它以不一致的速度在屏幕上移动,这取决于线的斜率。 I would like to be able to change my code so that the projectile moves on the screen at a consistent rate over any trajectory. 我希望能够改变我的代码,以便射弹在任何轨迹上以一致的速率在屏幕上移动。 Thank you in advance for any help. 预先感谢您的任何帮助。

In general the best way to handle directional movement is using trigonometry. 通常,处理定向运动的最佳方法是使用三角法。 Your projectile needs two things for this: direction (in radians) and speed. 你的射弹需要两件事:方向(弧度)和速度。

The three trig functions you need are sin, cos, and arctan 你需要的三个三角函数是sin,cos和arctan

For updating your X: setX(getX() + (speed * Math.cos(direction))); 更新你的X: setX(getX() + (speed * Math.cos(direction)));

For updating your Y: setY(getY() + (speed * Math.sin(direction))); 更新你的Y: setY(getY() + (speed * Math.sin(direction)));

For calculating the direction: Math.atan(slope) 用于计算方向: Math.atan(slope)

You should add the fields direction and speed to your class and declare them as doubles. 您应该将字段directionspeed添加到您的类中,并将它们声明为双精度数。

public void setHasTarget(boolean hasTargetIn)
{
    if (hasTargetIn)
    {
        deltaX = getTargetX() - getX();
        deltaY = getTargetY() - getY();
        direction = Math.atan(deltaY / deltaX); // Math.atan2(deltaY, deltaX) does the same thing but checks for deltaX being zero to prevent divide-by-zero exceptions
        speed = 5.0;
    }
    hasTarget = hasTargetIn;
}

public void setNext()
{
    setX(getX() + (speed * Math.cos(direction)));
    setY(getY() + (speed * Math.sin(direction)));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM