2

2D デカルト グリッドを回転および移動できるプレイヤーがいます。画面上のどこに敵を描画するかを計算する必要があります。

プレイヤーは、プレイヤーが向いている方向の前にある画面のサイズである特定の視点を持つ必要があります。(そして少し後ろ)

Bi-Polar座標とTrigを使用してこの混乱を実装する方法をたくさん試しましたが、画面上のどこに敵を描くべきかを計算する問題を解決できませんでした.

問題は、グリッドの周りを回転および移動できる長方形である視点である緑と、プレーヤーと敵を表すドットを含むグラフの形式で表すのが最適です。

青はプレイヤー、赤は敵 緑は視点を表す

そのため、プレイヤーの回転と位置に対する画面上の敵の位置を計算する必要があります。

4

1 に答える 1

2

運命のような視点を求める場合は、表示領域を長方形ではなく平行四辺形として想像する必要があります。あなたのキャラクターの後ろに、独自の位置と角度を持つカメラマンがいると想像してみてください。

カメラ錐台

敵の画面位置は、カメラと敵の間の角度に関連しています。

//indicates where on the screen an enemy should be drawn.
//-1 represents the leftmost part of the screen, 
//and 1 is the rightmost.
//Anything larger or smaller is off the edge of the screen and should not be drawn.
float calculateXPosition(camera, enemy){
    //the camera man can see anything 30 degrees to the left or right of its line of sight. 
    //This number is arbitrary; adjust to your own tastes.
    frustumWidth = 60;

    //the angle between the enemy and the camera, in relation to the x axis.
    angle = atan2(enemy.y - camera.y, enemy.x - camera.x);

    //the angle of the enemy, in relation to the camera's line of sight. If the enemy is on-camera, this should be less than frustumWidth/2.
    objectiveAngle = camera.angle - angle;

    //scale down from [-frustumWidth/2, frustumWidth/2] to [-1, 1]
    return objectiveAngle / (frustrumWidth / 2);
}

これらの図は、ここで使用している変数が何を表しているかを視覚化したものです。

<code> angle</code>の描写

ここに画像の説明を入力してください

[-1、1]の範囲の「X位置」ができたら、それをピクセル座標に変換するのは簡単です。たとえば、画面の幅が500ピクセルの場合、次のようなことができます。((calculateXPosition(camera, enemy) + 1) / 2) * 500;

編集:

ポイントの高さとカメラからの距離に基づいて、ポイントのy座標を見つけるのと同じようなことを行うことができます。(敵とカメラの高さをどのように定義する必要があるかわかりません。デカルトグリッドのxおよびy寸法によって設定されたスケールとある程度一致する限り、任意の数値で問題ありません。)

側面図-敵を見ているカメラ

//this gives you a number between -1 and 1, just as calculateXPosition does.
//-1 is the bottom of the screen, 1 is the top.
float getYPosition(pointHeight, cameraHeight, distanceFromCamera){
    frustrumWidth = 60;
    relativeHeight = pointHeight - cameraHeight;
    angle = atan2(relativeHeight, distanceFromCamera);
    return angle / (frustrumWidth / 2);
}

ここに画像の説明を入力してください

メソッドを2回呼び出して、敵の上部と下部の両方のy位置を決定できます。

distanceFromCamera = sqrt((enemy.x - camera.x)^2 + (enemy.y - camera.y)^2);
topBoundary = convertToPixels(getYPosition(enemy.height, camera.height, distanceFromCamera));
bottomBoundary = convertToPixels(getYPosition(0, camera.height, distanceFromCamera));

これにより、敵のスプライトを適切にスケーリングおよび配置するための十分な情報が得られます。

(余談ですが、2つの方法のfrustrumWidthsは同じである必要はありません。実際、描画する画面が長方形の場合は、異なる必要があります。x錐台とy錐台の比率は、比率と同じである必要があります。画面の幅と高さの。)

于 2012-02-28T13:48:32.423 に答える