Java 将2d游戏世界坐标转换为屏幕位置

Java 将2d游戏世界坐标转换为屏幕位置,java,Java,我有一个生成2d游戏地图块的系统。块是16x16块,块是25x25块 区块被赋予自己的坐标,如0,0,0,1等。区块根据它们所在的区块确定它们在世界上的坐标。我已经验证了块/块都显示了正确的x/y坐标 我的问题是把它们转换成屏幕坐标。在前面的问题中,有人建议使用: (worldX*平铺宽度)%viewport\u宽度 每个磁贴的x/y将通过此计算运行,并返回屏幕x/y坐标 这适用于视口中的平铺,但它会重置屏幕外任何对象的屏幕x/y位置计算 在我的地图中,我在玩家周围的半径范围内加载块瓷砖,这样一

我有一个生成2d游戏地图块的系统。块是16x16块,块是25x25块

区块被赋予自己的坐标,如0,0,0,1等。区块根据它们所在的区块确定它们在世界上的坐标。我已经验证了块/块都显示了正确的x/y坐标

我的问题是把它们转换成屏幕坐标。在前面的问题中,有人建议使用:

(worldX*平铺宽度)%viewport\u宽度

每个磁贴的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偏移值,因此我知道如何移动地图。我可以使用这些值作为当前偏移量,如果有人保存游戏,我可以简单地存储这些值并重新使用它们。不需要方程,我只需要存储累积偏移量

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

}
接口可渲染{
无效渲染(图形2D g)
..
}
类实现可渲染{
int x,y
//其他东西
渲染(图形2D g){
如果(!屏幕内()){
返回;
}
//...
//渲染
}
布尔屏幕(){
//如果地图随播放器移动,则需要根据全局地图坐标定义当前屏幕块的边界
//您可以将其全局存储在某个位置的单例中,或者将其传递给每个磁贴的构造函数。
//currentBlock.x是player.x-屏幕宽度/2
//currentBlock.width是player.x+屏幕宽度/2;
//与y类似
if(this.xcurrentBlock.Width)
返回false;
if(this.ycurrentBlock.height)
返回false;
返回true;
//如果地图是以块为单位的(想想你从一个屏幕块到另一个屏幕块的snes上的塞尔达),你仍然需要定义边界
//currentBlock.x=(player.x/屏幕宽度)(整数除法)*屏幕宽度;
//currentBlock.width=(player.x/screenWidth)(…)*screenWidth+screenWidth;
//y也一样
//然后执行上述测试
}
模(worldX*tileWidth%屏幕宽度)是导致其重置的原因。模(%)为您提供整数除法运算的余数;因此,如果worldX*tileWidth大于屏幕宽度,它将为您提供(worldX*tileWidth)的余数/screenWidth;如果worldX*tileWidth为screenWidth+1,则余数为1:它从行的开头重新开始

如果消除模,它将继续绘制屏幕边缘的平铺。如果绘制缓冲区与屏幕大小相同,则需要在屏幕边缘添加平铺检查,以确保只绘制可见的平铺部分

如果您试图使播放机在屏幕上居中,则需要按播放机与分幅0的偏移量(以像素为单位)减去屏幕宽度的一半来偏移每个分幅:

offsetX = (playerWorldX * tileWidth) - (screenWidth / 2);
screenX = (worldX * tileWidth) - offsetX;

你的解决方案对我来说没有多大意义:如果它在屏幕外,让它画在屏幕外,如果它在屏幕上,做一个你已经证明不会做任何事情的模运算?如果worldXtileWidth不是>screenWidth,那么worldXtileWidth%screenWidth==worldXtileWidth。三元是没有意义的,就像在任何一条路径上一样,你都会得到worldXtileWidth。也就是说是的,但如果你向下滚动两行,你会看到备选解决方案,他的问题实际上没有回答他的观点是playercentric还是mapcentric,所以我提供了两种备选方案。