7

画面を横切ってスプライトを直線で移動しようとしています。画面に触れた場所に向かって、私がしたことは各ループの update() で、現在のスプライトの場所が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++;
4

3 に答える 3

6

チェックアウト: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

この単純なアルゴリズムは、2 点間の線上の各 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

整数を使用しないでください。これは、int を操作するのは非常に悪い考えです。フロートを使用します。主な概念は、実行するステップ数を定義することです ( s)。X と Y の差を計算します (diffXdiffY)。絶対値を取らないでください。この方法で計算してください

float diffX = destX - currentX;

次に、xMove と yMove の値を (ステップ数) で割って計算しdiffXます。diffYs

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

そして今、反復ごとに moveX と moveY の値を現在の位置に追加する必要があります。

そして、それを描画するには、Graphics2D浮動小数点をサポートする を使用する必要があります。Graphics2D を使用したくない場合は、を使用して float を int に丸めることができますMath.round(float)

于 2011-09-16T18:24:35.353 に答える