Moving an object from point to point in a linear path

I am trying to move the sprite across the screen in a straight line, towards the place where I touched the screen, which I did with updating () in each cycle, it checks if the current location of the sprite xy is == for destination x, y. if it does not have x ++ and y ++ sprites ... the fact is that .. it does not move in a straight line ... since there are cases when the x or y coordinate reaches the first destination x or y ... how did i change it so that both x and y match the destination together?

my current pseudo code for the sprite object

destX = destination X destY = destination Y posX = current X posY = current Y public void update(){ if(destX > posX && destY < posY) { posX++; posY--; } else if (destX > posX && destY > posY){ posX++; posY++; } else if(destX < posX && destY > posY) { posX--; posY++; } else if(destX < posX && destY < posY){ posX--; posY--; } else if(destX < posX) posX--; else if(destX > posX) posX++; else if(destY < posY) posY--; else if(destY > posY) posY++; 
+6
source share
3 answers

Check out: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

This simple algorithm will tell you every X, Y coordinate on the line between two points. You can use this algorithm to calculate all the positions that you need to visit, save the coordinates in the array and iterate through the array when updating the position.

From the article:

  function line(x0, x1, y0, y1) int deltax := x1 - x0 int deltay := y1 - y0 real error := 0 real deltaerr := abs (deltay / deltax) // Assume deltax != 0 (line is not vertical), // note that this division needs to be done in a way that preserves the fractional part int y := y0 for x from x0 to x1 plot(x,y) error := error + deltaerr if error ≥ 0.5 then y := y + 1 error := error - 1.0 

This is the most primitive version. This article contains the best generalized algorithm that you should pay attention to.

+5
source

I am dealing with a similar problem like yours. (I have an arraylist holding a history of the positions that my player left, and I want to use this to rewind the game.) Instead of simply increasing the x and y position with 1, you can:

  • Calculate the angle between the starting position and the destination of the position.
  • Calculate a new direction using a variable that represents speed
  • Update your position using calculated direction

I made a class of this. Hope this is helpful.

 import java.awt.geom.Point2D; public class MyVelocityCalculator { public static void main(String[] args) { Point2D.Double currentPosition = new Point2D.Double(); Point2D.Double destinationPosition = new Point2D.Double(); currentPosition.setLocation(100, 100); destinationPosition.setLocation(50, 50); Double speed = 0.5; Point2D.Double nextPosition = MyVelocityCalculator.getVelocity(currentPosition, destinationPosition, speed); System.out.println("player was initially at: "+currentPosition); System.out.println("player destination is at: "+destinationPosition); System.out.println("half seconds later player should be at: "+nextPosition); } public static final Point2D.Double getVelocity(Point2D.Double currentPosition, Point2D.Double destinationPosition, double speed){ Point2D.Double nextPosition = new Point2D.Double(); double angle = calcAngleBetweenPoints(currentPosition, destinationPosition); double distance = speed; Point2D.Double velocityPoint = getVelocity(angle, distance); nextPosition.x = currentPosition.x + velocityPoint.x; nextPosition.y = currentPosition.y + velocityPoint.y; return nextPosition; } public static final double calcAngleBetweenPoints(Point2D.Double p1, Point2D.Double p2) { return Math.toDegrees( Math.atan2( p2.getY()-p1.getY(), p2.getX()-p1.getX() ) ); } public static final Point2D.Double getVelocity(double angle, double speed){ double x = Math.cos(Math.toRadians(angle))*speed; double y = Math.sin(Math.toRadians(angle))*speed; return (new Point2D.Double(x, y)); } } 
+2
source

Do not use integers. This is a very bad idea for working with ints. Use floats. The basic idea is to determine the number of steps you want to complete ( s ). Calculate differences in X and Y ( diffX and diffY ). Do not take absolute values: calculate them this way

 float diffX = destX - currentX; 

Then calculate the xMove and yMove values ​​by dividing diffX and diffY by s (number of steps).

 float moveX = diffX / s; float moveY = diffY / s; 

And now you need to add for each iteration the values ​​moveX and moveY at the current position.

And to draw it you should use Graphics2D , which supports floating points. If you do not want to use Graphics2D, you can combine float into ints using Math.round(float) .

+1
source

Source: https://habr.com/ru/post/897489/


All Articles