将一维数组拆分成块

7

我试图为了节省客户端内存而不将整个基于瓷砖的地图加载到内存中。这张地图非常巨大,已经需要1GB客户端内存(多层地图)。

我在Game Dev SO上获得了一些建议。我正在尝试把游戏地图的区域/块加载到内存中(例如300x300),然后当玩家移动100步时,移动数组并根据方向加载100个新瓦片。我已经尝试了一个比例缩小版本,并且现在有一个通用问题。


当玩家X/Y坐标位于地图的边缘时(导致块在地图之外),我需要帮助。

目前我想到的方法是(注意:玩家位于块的中心位置,块总是奇数大小)... 它存在以下问题(当角色位于地图边缘时):

  • 将角色X/Y更改为0,0,底部左侧(0,2)坐标将不正确为7

    0, 0, 0

    0, 1, 1

    7, 1, 8

  • 将角色X/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++;
            }
        }

    }
}

非常感谢您的任何帮助。

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - John Cipponeri
1
抱歉,我以为我表达得更清楚了...我会修改。当玩家的X/Y坐标在地图的周边(导致区块在地图外)时,我需要帮助。 - KisnardOnline
你付出了很多努力(也许有点过头了,但没关系),因此我给你点了个赞。 - niceman
2个回答

2
所以我认为你检查计数是否超出范围的逻辑是有误的。我认为它需要更复杂,以考虑到你的数组代表一个二维图形。我怀疑对于大于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

我不确定这是否是您要查找的内容,但通常您会在填充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++;
    }
}

请告诉我这是否是您正在寻找的内容,以及它是否有效!


1
您真是个天才(我现在脑袋一团糟):D 请确保编辑此内容...以防其他人想要用于学习。groundLayer[arrayIndex] = Short.parseShort(strArr[cellX + (cellY * mapWidth)]); - KisnardOnline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接