перемещение объекта из точки в точку по линейному пути - PullRequest
6 голосов
/ 16 сентября 2011

Я пытаюсь переместить спрайт по экрану по прямой линии в направлении к месту, где я коснулся экрана, что я делал при обновлении () в каждом цикле, он проверяет, есть ли текущее местоположение спрайта xy = = до места назначения 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 ]

5 голосов
/ 16 сентября 2011

Выезд: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Этот простой алгоритм подскажет вам каждую координату X, Y на линии между двумя точками.Вы можете использовать этот алгоритм, чтобы вычислить все позиции, которые ему необходимо посетить, сохранить координаты в массиве и выполнить итерацию по массиву при обновлении позиции.

Это самая примитивная версия.Статья содержит лучший обобщенный алгоритм, на который вам следует обратить внимание.

2 голосов
/ 22 февраля 2012

Я имею дело с такой же проблемой, как и ваша. (У меня есть arraylist, хранящий историю позиций моего игрока, и я хочу использовать это для перемотки игры) Вместо того, чтобы просто увеличивать 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));
    }
}
1 голос
/ 16 сентября 2011

Не используйте целые числа. Это очень плохая идея для работы с инттами. Используйте поплавки. Основная концепция: определите количество шагов, которые вы хотите выполнить (s). Вычислить различия по X и Y (diffX и diffY). Не принимайте абсолютные значения: вычислите их следующим образом

float diffX = destX - currentX;

Затем вычислите значения xMove и yMove, разделив diffX и diffY на s (количество шагов).

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

И теперь вам нужно добавить для каждой итерации значения moveX и moveY к текущей позиции.

И для рисования вы должны использовать Graphics2D, который поддерживает плавающие точки. Если вы не хотите использовать Graphics2D, вы можете округлить числа с плавающей точкой до целых, используя Math.round(float).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...