1

発射体を使用するゲームに取り組んでいます。そこで、Projectile クラスを作成しました。ユーザーが画面に触れると、新しいインスタンスが作成されます。

@Override
public boolean onTouch(View v, MotionEvent e){
    float touch_x = e.getX();
    float touch_y = e.getY();
    new Projectile(touch_x, touch_y);
}

そして発射物クラス:

public class Projectile{

    float target_x;
    float target_y;
    Path line;

    public Projectile(float x, float y){
        target_x = x;
        target_y = y;

        line = new Path();
        line.moveTo(MyGame.mPlayerXPos, MyGame.mPlayerYPos);
        line.lineTo(target_x, target_y);
    }
}

これにより、プレイヤーの位置とタッチ座標の 2 つのポイントを持つパスが作成されます。私の質問は - どうすればこの路線のポイントにアクセスできますか? たとえば、ラインの半分のポイントで発射体の x、y 座標を取得したい場合、または発射体が 100 ティック (X ピクセル/ティックの速度で移動) 後にあるポイントでしょうか?

また、Projectile が最終ポイントに到達した後も移動し続ける必要があります。パスを延長し続けるために line.addPath(line) を使用する必要がありますか?

編集

発射物を一直線に動かすことはできましたが、奇妙な方向に進んでいます。私はいくつかのコードをごまかす必要がありました:

private void moveProjectiles(){
        ListIterator<Projectile> it = Registry.proj.listIterator();
        while ( it.hasNext() ){
            Projectile p = it.next();
            p.TimeAlive++;

            double dist = p.TimeAlive * p.Speed;
            float dx = (float) (Math.cos(p.Angle) * dist);
            float dy = (float) (Math.sin(p.Angle) * dist);

            p.xPos += dx;
            p.yPos += -dy;
        }
    }

Angle問題があるに違いありません..私はこの方法を使用していますが、これは完全に機能します:

private double getDegreesFromTouchEvent(float x, float y){
        double delta_x = x - mCanvasWidth/2;
        double delta_y = mCanvasHeight/2 - y;
        double radians = Math.atan2(delta_y, delta_x);

        return Math.toDegrees(radians);
    }

ただし、画面中央より上のタッチでは 0 ~ 180、下のタッチでは 0 ~ -180 を返します。これは問題ですか?

4

3 に答える 3

3

これをモデル化する最良の方法は、パラメトリック方程式を使用することです。三角関数を使用する必要はありません。

class Path {
  private final float x1,y1,x2,y2,distance;

  public Path( float x1, float y1, float x2, float y2) {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    this.distance = Math.sqrt( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
  }

  public Point position( float t) {
     return new Point( (1-t)*x1 + t*x2,
                       (1-t)*y1 + t*y2);
  }

  public Point position( float ticks, float speed) {
    float t = ticks * speed / distance;
    return position( t); 
  }

}

Path p = new Path(...);
// get halfway point
p.position( 0.5);
// get position after 100 ticks at 1.5 pixels per tick
p.position( 100, 1.5);
于 2010-11-04T22:13:06.127 に答える
1

ジオメトリから、それが直線である場合、極座標を使用してその上の任意の点を計算できます。

線の角度がわかった場合:

ang = arctan((target_y - player_y) / (target_x - player_x))

次に、trig を使用して線上の任意の点を見つけることができます。

x = cos(ang) * dist_along_line
y = sin(ang) * dist_along_line

中点が必要な場合は、dist_alone_line を線の長さの半分にするだけです。

dist_along_line = line_length / 2 = (sqrt((target_y - player_y)^2 + (target_x - player_x)^2)) / 2

100 ティック後のポイントを考慮したい場合、X ピクセル/ティックの速度で移動します。

dist_along_line = 100 * X

Androidライブラリを使用して、これをより直接的に行う方法について誰かがコメントできることを願っています。

于 2010-11-04T22:00:47.340 に答える
0

まず、Path クラスは、発射体の位置の計算ではなく、描画に使用されます。

したがって、Projectile クラスは次の属性を持つことができます。

float positionX;
float positionY;
float velocityX;
float velocityY;

速度は、次のように targetX、targetY、playerX、および playerY から計算されます。

float distance = sqrt(pow(targetX - playerX, 2)+pow(targetY - playerY, 2))
velocityX = (targetX - playerX) * speed / distance;
velocityY = (targetY - playerY) * speed / distance;

20ティック後のあなたの位置は

x = positionX + 20 * velocityX;
y = positionY + 20 * velocityY;

ターゲットに到達するのにかかる時間は ticksToTarget = 距離 / 速度;

中間点の位置は

halfWayX = positionX + velocityX * (tickToTarget / 2);
halfWayY = positionY + velocityY * (tickToTarget / 2);
于 2010-11-04T22:20:38.997 に答える