在线性路径中将对象从一个点移动到另一个点

时间:2011-09-16 18:11:17

标签: java algorithm coordinates game-physics pathing

我正试图将一个精灵在屏幕上直线移动,朝向我触摸屏幕的位置,我在每个循环中执行更新(),它会检查是否当前精灵的位置xy = =到目的地x,y。如果它没有精灵的x ++和y ++ ......  事情是..它不是直线移动...因为有些情况下x或y坐标首先到达目的地x或y ...我如何改变它以便x和y都相遇目的地在一起?

我目前的精灵对象伪代码

             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++;

3 个答案:

答案 0 :(得分:5)

退房:http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

这个简单的算法会告诉你两点之间一条线上的每个X,Y坐标。您可以使用此算法计算它需要访问的所有位置,将坐标存储在数组中,并在更新位置时迭代数组。

来自文章:

  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

这是最原始的版本。本文包含一个更好的通用算法,您应该看一下。

答案 1 :(得分:2)

我正在处理类似问题的问题。 (我有一个arraylist持有我的球员已经离开的位置的历史,我想用它来回放比赛。) 您可以:

而不是简单地用1增加x和y位置
  1. 计算源位置与目的地之间的角度 位置。
  2. 使用变量计算新方向     代表速度
  3. 使用计算出的方向更新您的位置
  4. 我做了一类。我希望它很有用。

    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 :(得分:1)

不要使用整数。使用整数是一个非常糟糕的主意。使用浮动。主要概念是:定义要执行的步骤数(s)。计算X和Y的差异(diffXdiffY)。不要采用绝对值:以这种方式计算它们

float diffX = destX - currentX;

然后将diffXdiffY除以s(步数)来计算xMove和yMove值。

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

现在你必须为每次迭代添加moveX和moveY值到当前位置。

为了绘制它,你应该使用支持浮点的Graphics2D。如果您不想使用Graphics2D,可以使用Math.round(float)将浮点数舍入为整数。