私はAndroidで水平スクロールのスペースシューティングゲーム用のホーミングミサイルに取り組んでいます。使用しているアルゴリズムから目的の動作を取得するのに問題があります。ミサイルをプレイヤーの船から水平に発射してから徐々にターゲットに戻し、アークが大きすぎるとターゲットを逃す可能性があります。ミサイルがターゲットを逃した場合を除いて、それは機能します。その場合、ミサイルは通常、画面の右側から逃げるまで正弦波の経路をたどろうとします。私が望んでいるのは、ミサイルがスプライトに当たるか、画面の端から外れるまで、現在の曲線でターゲットの周りを旋回し続けることです(ステレオタイプのホーミングミサイルのように)。爆発して画面上で回転し続けないように制限を追加する場合がありますが、
コードの例を次に示します。
public class HomingMissile extends Shot
{
Bitmap bitmap;
Rect sourceRect;
Rect destRect;
private double heading;
private Sprite target;
private int frameNumber;
private int currentFrame;
private int frameDelta;
public HomingMissile(Context context, ImageLoader imageLoader, int x,
int y, int minX, int minY, int maxX, int maxY, int dx, int dy)
{
super(context, imageLoader, x, y, minX, minY, maxX, maxY, dx, dy);
heading = 0;
frameNumber = 3;
currentFrame = 0;
frameDelta = 1;
target = new Sprite(context, imageLoader, 300, 50, minX, minY,
maxX, maxY, 0, 0);
}
@Override
public void setBitmap(int id)
{
bitmap = imageLoader.GetBitmap(id);
width = bitmap.getWidth();
height = bitmap.getHeight() / frameNumber;
sourceRect = new Rect(0, 0, width - 1, height);
destRect = new Rect(X, Y, X + width - 1, Y + height - 1);
}
public void setTarget(Sprite sprite)
{
target = sprite;
}
@Override
public void Move()
{
if (!visible)
return;
final double f = 0.03;
double oldHeading = heading;
double atanY = target.Y + (target.height / 2) - Y;
double atanX = target.Y + target.X - X;
heading = (1 - f) * oldHeading + f * Math.atan2(atanY, atanX);
X += Math.cos(heading) * 10;
Y += Math.sin(heading) * 10;
UpdateBounds();
if (currentFrame == frameNumber - 1)
frameDelta = -frameDelta;
if (currentFrame < 0)
{
frameDelta = -frameDelta;
currentFrame += frameDelta;
}
sourceRect.top = height * currentFrame;
sourceRect.bottom = sourceRect.top + height;
currentFrame += frameDelta;
if (target.Collide(destRect, bitmap))
{
visible = false;
heading = 0;
}
if (OutOfBounds())
{
visible = false;
heading = 0;
}
}
@Override
public void Draw(Canvas canvas)
{
if (visible)
{
canvas.save();
canvas.rotate((float) (heading * 180 / Math.PI) * 1.5f, X + width
/ 2, Y + height / 2);
canvas.drawBitmap(bitmap, sourceRect, destRect, paint);
canvas.restore();
}
}
}
ホーミングアルゴリズムはMove()で発生します。私が問題に対して見つけた部分的な解決策は、このチェックを追加することでした:
if (atanY >= 0 && atanX < 0)
atanY = -atanY;
方位計算の前に、ミサイルがターゲットのY位置よりも大きいY位置から発射された場合、ミサイルはまだバグアウトします。
私はこれと数日間戦ってきましたが、三角法はあまり得意ではないので、誰かが私を助けてくれることを願っています。質問をコードで乱雑にしないようにしましたが、コードや情報が必要になった場合は、提供できます。
ありがとう!
編集
行を変更しました:
double atanX = target.Y + target.X - X;
に:
double atanX = target.X - X;
しかし、ミサイルがターゲットのY位置よりも大きいY位置から発射された場合でも、ミサイルはバグアウトします。ターゲットに向かって飛び込みますが、失敗すると、ループ・デ・ループを実行するかのように突然カーブします。