[英]Convert 2d game world coordinates to screen position
我有一個系統可以生成大塊的2D游戲地圖圖塊。 塊是16x16瓷磚,瓷磚是25x25。
這些塊有自己的坐標,如0,0,0,1等。這些塊根據它們所在的塊確定它們在世界中的坐標。我已經驗證了塊/塊都顯示正確x / y坐標。
我的問題是將它們轉換為屏幕坐標。 在之前的問題中有人推薦使用:
(worldX * tileWidth) % viewport_width
每個圖塊的x / y都通過此計算運行,並返回屏幕x / y坐標。
這適用於適合視口的圖塊,但它會重置屏幕x / y位置計算以用於屏幕外的任何內容。
在我的地圖中,我在玩家周圍的半徑范圍內加載了大塊的圖塊,因此一些內部圖塊將在屏幕外(直到它們四處移動,屏幕上的圖塊位置被移動)。
我嘗試了一個不在屏幕上的瓷磚測試:
Tile's x coord: 41
41 * 25 = 1025
Game window: 1024
1025 % 1024 = 1
這意味着平鋪x(如果屏幕0,0位於地圖0,0,應該位於x:1025,就在屏幕的右側),實際上是x:1,出現在頂部-剩下。
我想不出如何正確處理這個問題 - 在我看來,我需要使用tileX * tileWidth
來確定它的“初始屏幕位置”,然后以某種方式使用偏移來確定如何使它出現在屏幕上。 但有什么抵消?
更新 :當玩家移動時我已經存儲了一個x / y偏移值,所以我知道如何移動地圖。 我可以使用這些值作為當前偏移量,如果有人保存游戲,我可以簡單地存儲它們並重新使用它們。 沒有必要的等式,我只需要存儲累積偏移量。
模數(worldX * tileWidth % screenWidth)是導致它重置的原因。 模數(%)為您提供整數除法運算的余數; 所以,如果worldX * tileWidth大於screenWidth,它將為你提供(worldX * tileWidth)/ screenWidth的余數; 如果worldX * tileWidth是screenWidth + 1,則余數為1:它從行的開頭開始。
如果消除模數,它將繼續繪制超出屏幕邊緣的圖塊。 如果繪圖緩沖區的大小與屏幕大小相同,則需要在屏幕邊緣添加對切片的檢查,以確保只繪制可見的切片部分。
如果你試圖讓玩家在屏幕上居中,你需要將玩家的偏移量從平鋪0,0(以像素為單位)減去每個平鋪,減去屏幕寬度的一半:
offsetX = (playerWorldX * tileWidth) - (screenWidth / 2);
screenX = (worldX * tileWidth) - offsetX;
x = ((worldX*tileWidth) > screenWidth) ? worldX*tileWidth : (worldX*tileWidth)%screenWidth;
這應該工作。 雖然我建議實現類似界面的東西,然后讓每個圖塊決定他們想要渲染的位置。 像這樣的東西
interface Renderable {
void Render(Graphics2D g)
..
}
class Tile implements Renderable{
int x,y
//other stuff
Render(Graphics2D g){
if (!inScreen()){
return;
}
//...
//render
}
boolean inScreen(){
//if the map moves with the player you need to define the boundaries of your current screenblock in terms of the global map coordinates
//What you can do is store this globally in a singleton somewhere or pass it to the constructor of each tile.
//currentBlock.x is then player.x - screenWidth/2
//currentBlock.width is then player.x + screenWidth/2;
//similar for y
if(this.x < currentBlock.x || this.x > currentBlock.Width)
return false;
if (this.y < currentBlock.y || this.y > currentBlock.height)
return false;
return true;
//If the map are in blocks (think zelda on snes where you go from one screenblock to another) you still need to define the boundaries
//currentBlock.x = (player.x / screenWidth) (integer division) *screenWidth;
//currentBlock.width = (player.x /screenWidth) (...) * screenWidth + screenWidth;
//same for y
//Then perform above tests
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.