我试图不将我的整个基于图块的地图加载到内存中以节省RAM客户端。地图将是巨大的,并且已经需要1GB客户端(多层地图)。
我对Game Dev SO有了一些看法。我试图将我的游戏地图的区域/块加载到内存中(即300x300),然后当玩家移动100步时移动阵列并根据方向加载100个新的图块。我试图制作一个缩放版本,现在有一个通用的问题。
当玩家X / Y坐标位于地图周边时(这会导致地块位于地图之外),我需要帮助
这是我到目前为止所提出的内容(注意:玩家位于chunk& chunk的中心总是奇数号)...它有以下问题(当角色位于地图的边缘时) :
将characterX / Y更改为0,0,左下角(0,2)坐标将错误地为7
0,0,0
0,1,1
7 ,1,8
将characterX / Y更改为8,8,并且该块的右上角(2,0)坐标将错误地为6
1,1, 6
1,1,0
0,0,0
以下是SSCCE:
public class MapChunkLoad {
public static void main(String[] args) {
short[] groundLayer;
int mapWidth = 9;
int mapHeight = 9;
int chunkWidth = mapWidth / 3; //3
int chunkHeight = mapHeight / 3; //3
int characterX = 8;
int characterY = 8;
String map = "1, 1, 1, 1, 1, 1, 1, 1, 7, " +
"1, 8, 8, 1, 1, 1, 1, 1, 1, " +
"1, 8, 9, 9, 1, 1, 1, 1, 1, " +
"1, 1, 9, 9, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"6, 1, 1, 1, 1, 1, 1, 1, 1";
String[] strArr = map.split(", ");
groundLayer = new short[chunkWidth * chunkHeight];
//load chunk into groundLayer
int arrayIndex = 0;
int count = (characterX - (chunkWidth/2)) + ((characterY - (chunkHeight/2)) * mapWidth); //top left tile within chunk
for (int y = 0; y < chunkHeight; y++){
for (int x = 0; x < chunkWidth; x++){
if (count > -1 && count < strArr.length){
groundLayer[arrayIndex] = Short.parseShort(strArr[count]);
System.out.println("arrayIndex[" + arrayIndex + "] = " + strArr[count]);
} else {
groundLayer[arrayIndex] = 0;
System.out.println("arrayIndex[" + arrayIndex + "] = " + 0);
}
arrayIndex++;
count++;
}
count += (mapWidth - chunkWidth);
}
System.out.println("");
//print map grid
int printcount = 0;
for (int y = 0; y < chunkHeight; y++){
for (int x = 0; x < chunkWidth; x++){
if (x == chunkWidth - 1){
System.out.println(groundLayer[printcount]);
} else {
System.out.print(groundLayer[printcount] + ", ");
}
printcount++;
}
}
}
}
非常感谢您的帮助。
答案 0 :(得分:2)
所以我认为你检查计数是否超出界限的逻辑是错误的。
我认为要说明你的数组代表2D数字需要更加复杂。我怀疑大于3x3的块你会得到更多的错误,这些错误很难描述。考虑这个地图,其中每个方格的值都是其索引。
0 1 2
3 4 5
6 7 8
当在右上角(2)时,您的地图应该如下所示
0 0 0
1 2 0
4 5 0
但是这会失败,因为在计算xValue * width + yValue时,count在某些情况下会是一个有效的索引,但是你希望它无效(映射到0)。相反,您需要跟踪计数的X和Y分量,并在其中任何一个超出界限时使地图显示为零。
int countX = characterX - (chunkWidth/2);
int countY = characterY - (chunkHeight/2);
int index = countX + (countY*mapWidth)
然后。而不是检查:
if (count > -1 && count < strArr.length)
检查:
if( countX + x >= mapWidth || countY + y >= mapHeight)
编辑:
你可以想象这也会改变你的计算方式。你还需要一种方法来打破你的循环。像
这样的东西if(x == chunkWidth && y == chunkWidth) break;
我会更具体,但我在加载原始帖子时无法作为参考。
我认为这可以解决所有问题。如果您有任何疑问,请发表评论。祝你好运!
答案 1 :(得分:1)
我不确定这是否是您正在寻找的内容,但通常您需要检查填充groundLayer
的嵌套for循环中的边界,而不是检查计数变量。这种方式会更加强大。像这样:
for(int y = 0;y < chunkHeight;y++) {
for(int x = 0;x < chunkWidth;x++) {
//Get the absolute position of the cell.
int cellX = characterX + x - chunkWidth / 2; //Please check if this is correctly lined out.
int cellY = characterY + y - chunkHeight / 2;
if(cellX >= 0 && cellX < mapWidth && cellY >= 0 && cellY < mapHeight) { //Within bounds.
groundLayer[arrayIndex] = Short.parseShort(strArr[cellX + (cellY * mapWidth)]);
} else { //Out of bounds, put down a placeholder.
groundLayer[arrayIndex] = 0;
}
arrayIndex++;
}
}
让我知道这是否是您正在寻找的,以及它是否有效!