简体   繁体   中英

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. 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). I make use of the linear function 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. 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)

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.

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

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

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

For calculating the direction: Math.atan(slope)

You should add the fields direction and speed to your class and declare them as doubles.

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)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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