1
\$\begingroup\$

Hello I have a game where circles rotate around the centre of the frame. When I click on two circles a line is drawn between the two circles. The circles are always moving and so is the line. I have an image at the start of the line and I want it to move along the line at stop at the end of the line. I knowhow to start the image at the start but I don't know how to move the image along the line. How can I move the image along the line?

Here is my code:

   public class ship {

public int sx,sy,ex,ey;
public boolean arrived,sel1,sel2;
public int amountOfPop = 0;

public int fc = -1,sc = -1;

public ship(int sx,int sy,int ex,int ey,int aop){
    this.sx = sx;
    this.sy =sy;
    this.ex = ex;
    this.ey =ey;
    this.amountOfPop = aop;



}

public void tick(){


}

public void render(Graphics g){
    g.setColor(Color.blue);
    g.drawLine(sx, sy, ex, ey);
}
 }

sx and sy are the starting x and starting y. ex and ey is where the image should finish. Please help me.

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

I'm going to explain this using Vector mathematics. I would also recommend to store your x and y values as such, as it makes it easier to maintain. Here's an example:

public class Vector2 {

    public float x;
    public float y;

    public Vector2(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public static float length(float x, float y) {
        return Math.sqrt(x * x + y * y);
    }

    public static float distance(Vector2 first, Vector2 second) {
        return length(second.x - first.x, second.y - first.y);
    }

    public static Vector2 direction(float x, float y) {
        return new Vector2(x / length(x, y), y / length(x, y));
    }
}

You'll want to give your ship a Vector2 to indicate its current position, the start position, the target position, and one for the direction. You'll also need a speed variable which indicates the rate at which your image will move (you could just use 1f if you like), and a distance variable to indicate the distance from the current position:

private Vector2 position;
private Vector2 start;
private Vector2 target;
private Vector2 direction;

private float speed;

private float distance;

...

public Ship(Vector2 position, Vector2 target, float speed, ...) {
    this.position = position;

    // Initialize start as a new Vector2 with the same x and y coordinates as position
    this.start = new Vector2(position.x, position.y);
    this.target = target;

    distance = Vector2.distance(start, end);
    direction = Vector2.direction(end.x - start.x, end.y - start.y);

    ...
}

public void tick() {
    position.x += direction.x * speed;
    position.y += direction.y * speed;

    if (Vector2.distance(start, position) >= distance) {
        // The ship has reached the target
    }

    ...
}

I'm assuming your tick() method is where you're performing your logic. What we're doing here is adding the distance * speed to the current position of the ship, making it travel along the imaginary line between the start position and the target.

If your start and target points are changing as you say, all you need to do is update the distance and direction variables in your tick() method:

public void tick() {
    distance = Vector2.distance(start, end);
    direction = Vector2.direction(end.x - start.x, end.y - start.y);

    ...
}

Equations:

Length: Length equation

Distance: Distance equation

Direction: Direction equation


The Vector2 class in this example is very basic and can definitely be improved upon. I suggest learning more about Vector mathematics, as well as taking a look at existing implementations of Vector mathematics and calculations to get a better idea on the subject. Here's one such implementation of a Vector2 class in libGDX.

\$\endgroup\$
6
  • \$\begingroup\$ is "end" the same as "target" \$\endgroup\$ Jul 12, 2015 at 15:58
  • \$\begingroup\$ @user2279603 yes, it seemed like a more descriptive name. \$\endgroup\$
    – driima
    Jul 12, 2015 at 15:59
  • \$\begingroup\$ here is my old constructor for adding a new ship to the array \$\endgroup\$ Jul 12, 2015 at 16:01
  • \$\begingroup\$ s.add(new ship((int) p.get(firstclicked).x + 25, (int) p.get(firstclicked).y + 25, (int) p.get(secondclicked).x + 25, (int) p.get(secondclicked).y + 25, 100)); \$\endgroup\$ Jul 12, 2015 at 16:01
  • \$\begingroup\$ what would the new one be? \$\endgroup\$ Jul 12, 2015 at 16:01
0
\$\begingroup\$

What you need to do is keep track of what distance or what percent the image has traveled down the path, and increase that amount by a small amount (based on your frame rate) in your update function.

When you want the image to start moving from start to end, you might set a percent variable to zero.

Then, in your update you might say: percent = percent + 0.01. For better results you would multiply that 0.01 by the number of milliseconds since the last update. Percent = percent + 0.01 * deltaTime. You will need to adjust that 0.01 to be larger or smaller depending on the desired speed.

Lastly, to actually calculate the location of the object so you can draw it, you just use a lerp (linear interpolation) between start and end.

PosX = startx * (1 - percent) + endx * percent

PosY = starty * (1-percent) + endy * percent

If you want to get fancy, you could make it so the object isnt a constant speed down the path. You can do this by using the squared percent in the lerp, instead of the raw percent, or you could use something like bias and gain.

\$\endgroup\$
3
  • \$\begingroup\$ Here's more info about bias and gain: blog.demofox.org/2012/09/24/bias-and-gain-are-your-friend \$\endgroup\$
    – Alan Wolfe
    Jul 12, 2015 at 14:59
  • \$\begingroup\$ how can I write this in code. I am not the greatest at taking instructions and turning them into code. \$\endgroup\$ Jul 12, 2015 at 15:06
  • \$\begingroup\$ I can't write it for you, especially since I don't have all your source code, but give it a try and see how it goes, this is a skill you are going to need as you do more advanced stuff (: \$\endgroup\$
    – Alan Wolfe
    Jul 12, 2015 at 15:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .