7

我试图在屏幕上直线移动一个精灵,朝向我触摸屏幕的位置,我所做的是在每个循环中的 update() 上,它检查当前精灵的位置xy == 到目的地 x ,y 。如果它没有精灵的 x++ 和 y++...问题是 ..它不是直线移动...因为在某些情况下 x 或 y 坐标首先到达目标 x 或 y...如何我是否对其进行了更改,以便 x 和 y 一起满足目的地?

我当前的 sprite 对象的伪代码

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

3 回答 3

6

查看: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

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

于 2011-09-16T18:12:52.123 回答
2

我正在处理与您类似的问题。(我有一个数组列表保存我的玩家所走位置的历史,我想用它来倒带游戏。)除了简单地将 x 和 y 位置增加 1 之外,您还可以:

  1. 计算源位置和目标位置之间的角度。
  2. 使用代表速度的变量计算新方向
  3. 使用计算的方向更新您的位置

我做了一个这样的课。我希望它是有用的。

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));
    }
}
于 2012-02-21T22:21:29.623 回答
1

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

float diffX = destX - currentX;

然后通过除以diffX和(步数)计算 xMove 和 yMove 值。diffYs

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

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

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

于 2011-09-16T18:24:35.353 回答