0
\$\begingroup\$

I have a 2D tile based engine with infinite procedural chunk generation.
But I can't invent an algorithm, that will fill only chunk tiles on view port (and destroy old). Pls help
ViewPort size can changing on the fly (2 - 100)
I can't load all chunks completely, because I need to analyze the tiles in the visibility zone

enter image description here

enter image description here

class Map {     
  public List<Chunk> { get; set; }
  public int viewPortWidth = 2 ... 100;
  public int viewPortHeight = viewPortWidth;
  public Vector2Int playerPosition { get; set; }
}

class Chunk {
  Tile[] Tiles { get; set; }
  public int chunkWidth = 16;
  public int chunkHeight = chunkWidth;

  public Chunk(int _leftX, int _bottomY)
  {
    for (int y = 0; y < chunkHeight; y++)
    { 
        for (int x = 0; x < chunkWidth; x++)
        {
            randomNumberGenerator.InitState(x + _leftX, y + _bottomY);
            chunk[x, y] = randomNumberGenerator.Range(100);
            Tiles.Add[chunk[x, y]];
        }
     }
}
\$\endgroup\$
1
\$\begingroup\$

If your viewport is just a rectangle, and your chunks are arranged in a 2D grid, you can simply convert your viewport's corners into chunk coordinates (that is, fine which chunk each viewport corner is in); assuming your viewport position is in pixels, this might look like:

int chunkX = viewport.X / (tileSizeInPixels.X * tilesPerChunkX);
int chunkY = viewport.Y / (tileSizeInPixels.Y * tilesPerChunkY);

The grid of chunks spanned by the four chunk coordinates you find in this fashion is the set of all chunks visible in the viewport. You can potentially unload all chunks outside that set.

In practice you may want to expand the rectangle you use for computing this to something larger than the viewport, to account for the fact that loading/unloading chunks takes time and the player may be able to move the viewport fast enough to outpace this IO.

In your example it looks like you're actually trying to unload individual tiles from a chunk, which is still doable with the same approach as above (just compute tile positions instead of chunk positions) but seems, to me, to defeat a large part of why you'd bother organizing tiles into chunks in the first place.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your reply! Yeap, I'm trying to load/unload individual tiles from a chunk(If chunks don't enter the visibility zone completely), but if viewport will have 100x100 size - check each tile will cost too much time. I think, completely visible chunks need to load all tiles without checking. But I don't understand how to do it. \$\endgroup\$ – Michael Kors Jan 9 '18 at 22:58
  • \$\begingroup\$ Your answer gave me a new idea, we can find chunk coord in center viewport like int startx = _mapCenter.x < 0 ? _mapCenter.x + (-_mapCenter.x % GameConfig.GetChunkSize) - GameConfig.GetChunkSize : _mapCenter.x - (_mapCenter.x % GameConfig.GetChunkSize); startx /= GameConfig.GetChunkSize; \$\endgroup\$ – Michael Kors Jan 9 '18 at 23:01
  • \$\begingroup\$ And we can find number of chunks in viewPort int chunksInViewPort = Mathf.CeilToInt(GameConfig.GetViewSize / (float)GameConfig.GetChunkSize); \$\endgroup\$ – Michael Kors Jan 9 '18 at 23:05
  • \$\begingroup\$ Oops, but still can't properly cut \$\endgroup\$ – Michael Kors Jan 9 '18 at 23:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.