Split 1d array into chunks

I am trying to not load my entire tile based map into memory to save RAM client side. The map will be huge and already is requriring 1GB client side (multi-layered map).

I have gotten some perspective on Game Dev SO. I am trying to Load zones/chunks of my game map into memory (ie 300x300) and then when the player moves 100 steps shift the array and load 100 new tiles depending on direction. I have tried to work on a scaled version of this and now have a generic question.


I need help when the playerX/Y coordinates are on the perimeter of the map (which causes the chunk to be outside of the map)

Here is what I have come up with so far (note: player is in center of chunk & chunk always odd number sized)... It has the following issues(when the character is on the edge of the map):

  • change characterX/Y to 0,0 and the bottom left(0,2) coordinate will incorrectly be 7

    0, 0, 0

    0, 1, 1

    7 , 1, 8

  • change characterX/Y to 8,8 and the top right(2,0) coordinate of the chunk will incorrectly be 6

    1, 1, 6

    1, 1, 0

    0, 0, 0

  • Here is the 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++;
                }
            }
    
        }
    }
    

    Thanks so much for any assistance.


    I'm not sure if this is what you are looking for, but commonly you'd check for bounds inside your nested for-loop that fills the groundLayer , rather than checking with a count variable. That way will be much more robust. Something like this:

    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++;
        }
    }
    

    Let me know if this was what you were looking for, and whether it works!


    So I think your logic for checking if count is outside the bounds is faulty.

    I think it needs to be more complex to account for that your array represents a 2D figure. I suspect for chunks larger than 3x3 you're getting a lot more errors that are really tricky to describe. Consider this map where each square's value is its index.

    0 1 2
    3 4 5
    6 7 8
    

    when in the top right corner (2) your map should look like this

    0 0 0
    1 2 0
    4 5 0
    

    but this will fail because count will in some cases be a valid index when calculating xValue*width+yValue, but you want that to be invalid (mapped to 0). Instead you need to keep track of both the X and Y components of count and make your map display a zero when either of those are out of bounds.

    int countX = characterX - (chunkWidth/2);
    int countY = characterY - (chunkHeight/2);
    int index = countX + (countY*mapWidth)
    

    then later. Instead of checking:

    if (count > -1 && count < strArr.length)
    

    check:

    if( countX + x >= mapWidth || countY + y >= mapHeight)
    

    EDIT:

    As you can imagine this also changes how you count. You will also need a way to break your loop. Something like

    if(x == chunkWidth && y == chunkWidth) break; 
    

    I would be more specific, but I'm having trouble loading your original post to use as reference.

    I think that fixes everything. Leave a comment if you have any questions. Good luck!

    链接地址: http://www.djcxy.com/p/24100.html

    上一篇: 签署本地主机的SSL证书,如何使信任

    下一篇: 将1d数组拆分为块