我有一個玩家可以圍繞2D笛卡爾網格旋轉和移動,我需要計算在屏幕上繪製敵人的位置。圍繞網格旋轉矩形來計算玩家視圖
玩家應該有一個特定的視角,就是玩家面對的方向前面的屏幕尺寸。 (並稍微落後)
我已經嘗試了很多方法來實現這個與雙極座標和Trig混淆的方法,但我還是無法解決計算屏幕上敵人應該在哪裏的問題被畫下來。
問題最好用綠色圖形的形式來表示,它是一個可以圍繞網格旋轉和移動的矩形,以及表示玩家和敵人的點。
所以我需要在相對於玩家旋轉和位置的屏幕制定出敵人的位置。
我有一個玩家可以圍繞2D笛卡爾網格旋轉和移動,我需要計算在屏幕上繪製敵人的位置。圍繞網格旋轉矩形來計算玩家視圖
玩家應該有一個特定的視角,就是玩家面對的方向前面的屏幕尺寸。 (並稍微落後)
我已經嘗試了很多方法來實現這個與雙極座標和Trig混淆的方法,但我還是無法解決計算屏幕上敵人應該在哪裏的問題被畫下來。
問題最好用綠色圖形的形式來表示,它是一個可以圍繞網格旋轉和移動的矩形,以及表示玩家和敵人的點。
所以我需要在相對於玩家旋轉和位置的屏幕制定出敵人的位置。
如果您打算採用類似Doom的視角,您應該將觀看區域想象爲平行四邊形,而不是矩形。想象一下,你的角色背後是一個擁有自己位置和角度的攝影師。
敵人的屏幕位置與相機和敵人之間的角度。
//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的範圍內的 「X位置」, 1],它應該很容易將其轉換爲像素座標。例如,如果你的屏幕是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);
}
您可以調用該方法兩次,以確定這兩個頂部的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));
這應該給你足夠的信息來正確縮放和定位敵人的精靈。 (除此之外:兩種方法中的frustrumWidths不需要相同 - 事實上,如果您正在繪製的屏幕是矩形的,它們應該是不同的。這個比例應該等於屏幕的寬度和高度的比率。)
這真是一個令人難以置信的答案,我當然不會得到像我這樣的東西,所以謝謝你非常。我現在開始工作實現 – Joel 2012-02-28 14:12:47
我已經設法從這個X中獲得X,但是我也在努力獲得Y – Joel 2012-02-28 20:18:22
@Joel,我已經添加了一些關於計算Y座標的信息。 – Kevin 2012-02-28 21:29:59