[英]moving an object from point to point in a linear path
I'm trying to move a sprite across the screen in a straight line, towards on the location where've I touched the screen, what i did was upon the update() in each loop , it checks to see if the current sprite's location xy is == to the destination x ,y . 我试图在屏幕上直线移动一个精灵,朝着我触摸屏幕的位置,我做的是在每个循环中更新(),它检查当前精灵的位置xy = =到目的地x,y。 if it hasn't sprite's x++ and y++... the thing is ..it ain't moving in a straight line... as there are cases where the x or y coordinate reaches the destination x or y first... how do i changed it so that the both x and y meets the destination together? 如果它没有精灵的x ++和y ++ ......那就是..它不是直线移动...因为有些情况下x或y坐标首先到达目的地x或y ...如何我是否改变它以使x和y一起与目的地相遇?
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++;
Check out: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm 查看: http : //en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
This simple algorithm will tell you each X,Y coordinate on a line between two points. 这个简单的算法将告诉你两点之间的一条线上的每个X,Y坐标。 You could use this algorithm to compute all of the positions it needs to visit, store the coordinates in an array, and iterate over the array as you update 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. 这是最原始的版本。 The article contains a better generalized algorithm that you should look at. 本文包含一个更好的通用算法,您应该看一下。
I am dealing with a similair problem as yours. 我正在处理像你这样的类似问题。 (I have an arraylist holding the history of positions my player has gone and I want to use that to rewind the game.) Instead of simply increasing x and y position with 1 you can: (我有一个arraylist持有我的玩家已经离开的位置的历史,我想用它来回放游戏。)而不是简单地用1增加x和y位置,你可以:
I made a class of that. 我做了一类。 I hope it is usefull. 我希望它有用。
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));
}
}
Don't use integers. 不要使用整数。 This is a very bad idea to work with ints. 使用整数是一个非常糟糕的主意。 Use floats. 使用浮动。 The main concept is: define the number of steps you want to perform ( s
). 主要概念是:定义要执行(步数s
)。 Compute differences in X and Y ( diffX
and diffY
). 计算X和Y的差异( diffX
和diffY
)。 Don't take absolute values: Compute them this way 不要采用绝对值:以这种方式计算它们
float diffX = destX - currentX;
Then compute the xMove and yMove values by dividing diffX
and diffY
by s
(number of steps). 然后通过将diffX
和diffY
除以s
(步数)来计算xMove和yMove值。
float moveX = diffX / s;
float moveY = diffY / s;
And now you have to add for each iteration the moveX and moveY values to the current position. 现在,您必须为每次迭代添加moveX和moveY值到当前位置。
And for drawing it, you should use Graphics2D
, which supports floating points. 为了绘制它,你应该使用支持浮点的Graphics2D
。 If you don't want to use Graphics2D, you can round the floats to ints, using Math.round(float)
. 如果您不想使用Graphics2D,可以使用Math.round(float)
将浮点数舍入为整数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.