2012-02-28 17 views
2

2Dデカルトグリッドの周りを回転して移動できるプレーヤーがあります。敵を画面上で描画する場所を計算する必要があります。グリッドの周りの矩形を回転させてプレイヤービューを計算する

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

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

問題は、グリッドの周りを回転して動くことができる矩形である視点である緑色と、プレイヤーと敵を表す点で最もよく表現されます。

Blue is player, Red is Enemy Green represents viewpoint

だから私は、選手の回転や位置に対するスクリーン上の敵の位置をうまくする必要があります。

答えて

2

パノラマのようなパースペクティブの場合は、表示領域を四角形ではなく平行四辺形として考える必要があります。あなたのキャラクターの背後には、自分の位置と角度を持つカメラマンがいると想像してください。

The camera frustum

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

depiction of <code>angle</code>

enter image description here

あなたは[-1の範囲内で "X位置" を持っていたら:

//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); 
} 

これらの図は、私がここで使っている変数が何を表しているか視覚化1]に変換するには、それをピクセル座標に変換するだけで十分です。あなたがポイントの高さと距離からに基づいて、y座標点を見つけるために、類似した何かを行うことができます

:あなたの画面は500個のピクセル幅である場合たとえば、あなたは編集

((calculateXPosition(camera, enemy) + 1)/2) * 500;ような何かを行うことができますカメラ。 (私は敵とカメラの高さをどのように定義すればよいかわかりません - デカルトグリッドのxとyの寸法で設定された縮尺と多少一致していれば問題ありません)

side view - camera looking at enemy

//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); 
} 

enter image description here

あなたはトップと敵の下部の両方の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 frustrumとy frustrumの比率は、画面の幅と高さの比に等しくする必要があります。

+0

本当に信じられないほどの答えです、私は確かに自分自身のようなものには到着しませんでした。あなたは大変です。私はこれを実装しようとしています – Joel

+0

私はこれからXを得ることに成功しましたが、Yを得ることにも苦労しています。 – Joel

+0

@Joel、Y座標の計算に関するいくつかの情報を追加しました。 – Kevin

関連する問題