1

かなり複雑な問題があります。基本的に、LOS アルゴリズムを使用して常にプレイヤーの現在の位置に向かって飛行する、プレイヤーの位置を追跡するオブジェクトがあります。

ただし、オブジェクトにプレーヤーの方向に弾丸を発射させようとしているため、問題が発生しています。オブジェクトは純粋なベクトル演算を使用してプレーヤーに向かって移動しますが、関数の動作を考慮すると、弾丸はクォータニオンを使用する必要があります。

では、オブジェクトがプレーヤーに向かって移動する場合、弾丸関数で使用できるクォータニオン回転を作成して、ソースがオブジェクトであるプレーヤーに向かって移動する弾丸を作成するにはどうすればよいですか?

プレーヤーに続くオブジェクトを描画する私の関数:

private void drawEnemy(GameTime gameTime)
{
    angle += 0.1f;

    velocity = Vector3.Normalize(xwingPosition - enemyPos) * 0.02f;

    enemyPos = enemyPos + velocity;
    enemyWorldMatrix = Matrix.CreateRotationY(angle) * Matrix.CreateTranslation(enemyPos);
    DrawObject(enemy, enemyWorldMatrix, viewMatrix, projectionMatrix);

    //enemyRotation = GetRotation(xwingPosition, enemyPos);

    //Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, -1, 0), -0.1f) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), -0.1f);
    //enemyRotation *= additionalRot;

    double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
    if (currentTime - enemyLastBulletTime > 1000)
    {
        EnemyBullet newBullet = new EnemyBullet();
        newBullet.position = new Vector3(enemyPos.X + 0.2f, 71, enemyPos.Z + 0.2f);
        newBullet.t = 0.01f;
        newBullet.proportion = newBullet.t / 120;
        newBullet.playerPosition = xwingPosition;
        newBullet.enemyPosition = enemyPos;
        newBullet.currentAccel = 0.025f;
        enemyBulletList.Add(newBullet);

        enemyLastBulletTime = currentTime;
    }
}

ご覧のとおり、ベクトル計算を使用して追跡し、プレーヤーに向かって移動します。

ご覧のとおり、弾丸を作成しようとしています。弾丸は、私が正しく作成したいと思っているクォータニオン回転を使用しています。

私が書いた最初の関数から作成されたら、弾丸の位置を更新する私の関数。

private void UpdateEnemyBulletPositions()
{
    for (int i = 0; i < enemyBulletList.Count; i++)
    {
        EnemyBullet currentBullet = enemyBulletList[i];
        currentBullet.t += 0.01f;
        currentBullet.position = enemyPos + (Vector3.Normalize(currentBullet.playerPosition - currentBullet.enemyPosition) * currentBullet.proportion);
        MoveForward(ref currentBullet.position, currentBullet.rotation, 0.04f + (currentBullet.currentAccel));
        enemyBulletList[i] = currentBullet;

        BoundingSphere bulletSphere = new BoundingSphere(currentBullet.position, 0.05f);
        CollisionType colType = CheckCollision(bulletSphere);
        if (colType != CollisionType.None)
        {
            enemyBulletList.RemoveAt(i);
            i--;

            if (colType == CollisionType.Target)
                gameSpeed *= 1.05f;
        }
    }
}

xwingPositionはプレイヤーの現在位置です。

enemyPosは、プレイヤーを追跡するオブジェクトの現在の位置です。

この問題は、ちょうど準備中のこの youtube クリップに示されています...

http://www.youtube.com/watch?v=PnkCVKdfN9Y

問題は、t を 0 から始まるカウンターではなく、合計経過ミリ秒に設定することにあると思います。つまり、弾丸が作成されるたびにカウンターを 0 から開始する方法がわかりません。

4

1 に答える 1

0

2 点 E と P (敵とプレイヤーを表す 3d ベクトル) の間の直線軌道は、次の式で計算できます。

T(t) = E + t*(P-E)

ここで、t は 0 から 1 まで変化する係数です (弾丸をアニメーション化するため)。

これはあなたが構築できるベースです。ただし、弾丸のリーチを制限したい場合があります。その場合は、次のことができます。

  1. 弾丸の方向を計算します。D = P-E
  2. その長さを計算します: len = sqrt(Dx^2 + Dy^2 + Dz^2). ここで、Dx は D などの x 座標であり、^2 は 2 乗を意味します。
  3. 方向ベクトルを正規化しND = (1/len)*Dます。(各座標を で割るだけですlen

ではND、敵からプレイヤーに向かって長さ 1 のベクトルが得られます。弾丸を発射するたびに、格納する構造体を割り当てる必要があります。

  • 現在ND
  • 弾丸が発射される位置(E敵の現在位置)
  • カウンター t = 0

ゲームのすべてのサイクルで、「生きている」弾丸ごとに (以下は疑似コードです):

bullet.t += 1
if(bullet.t < maxNumberOfCyclesABulletLives){
  bPos = bullet.E + bullet.t * coefficient * bullet.ND // coefficient is the distance the bullet should move in each cycle
  if(bPos touches P){
    damageToPlayer()
    releaseTheStructureForThisBullet()
  }
  else drawBulletInPosition(bPos) // depending on your gaming library, you may have to erase it from the previous position
}
else{
  makeTheBulletExplode()
  releaseTheStructureForThisBullet() //or rather return it to a pool, where it can be reused
}

ところで、あなたのゲームはとてもクールに見えます。あなたがそれを公開したら、私は無料のコピーを期待しています;-)

于 2012-10-13T11:18:55.910 に答える