0
\$\begingroup\$

I am working on a platformer that is going to have a map that is randomly generated and infinite in 3 directions: left, right, and down.

I've figured out that I will need to separate this world into chunks, as otherwise it will be impossible to pull off. Each chunk currently consists of 512x512 tiles. (This may change in the future.) There will be set points on each chunk where the game will check whether or not a chunk exists in the direction the player is heading. If there isn't, one (or a few more) will be generated. If there is, it will be loaded into memory.

Now, my problem is, say I have a chunk and I am near the bottom left corner of it. If the camera moves diagonally down and to the left, I will be intersecting 3 additional chunks. Is my only option to calculate the tiles from each chunk and determine where they need to be drawn on screen? It seems like this will be a little nuisance of a problem to deal with. If this is the only way to do it, I guess I will have no choice but to tackle it, but I'm wondering if there's an alternative solution to this.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Is my only option to calculate the tiles from each chunk and determine where they need to be drawn on screen? It seems like this will be a little nuisance of a problem to deal with.

If that seems hard, then you should change how you do it so that it's easy. It's not clear from your question what makes the case problematic, but I suspect that it's that you're trying to load chunks based on how the player/camera is moving. This is a bad idea, as it's much simpler to do something which works independently of movement.

First, if you don't have it already, you should have a data structure which stores loaded chunks keyed on their chunk coordinates. Example of chunk coordinates: The chunk containing the "middle" of your world is at coordinates (0, 0). Then the chunk immediately to the right of that one is (1, 0), and the one below that one is (1, 1), and so on. Then you can use those coordinates as keys in a hash-table or similar to keep references to the chunks you've loaded.

Every frame, do the following:

  1. Figure out the coordinates of the chunk which should be visible in the upper left corner of the screen. For example, if the upper left corner has screen coordinates (0, 0), and your camera position is expressed in pixels (likely in a sprite-based game), then divide the camera position by the tile size, and the chunk size, to obtain chunk coordinates. On the other hand, if you're using 3D-style graphics and the tile size is just 1, then you just divide by the chunk size.

  2. Do the same for the bottom-right corner of the screen (same computation but offset by the screen size). You now have four chunk coordinates which can be interpreted as the corners of a rectangle of chunks which will be always at least the size of the screen.

  3. Loop over the coordinates of each chunk in the rectangle (just two nested loops). Look it up in the table of loaded chunks; if not found, load/generate it. Draw the chunk, positioning it according to its coordinates and the camera position.

  4. Each chunk which is loaded but was not drawn in the previous step (you can use a "was drawn" flag on each chunk to figure this out) may be unloaded (but you probably want to keep some around as a cache in case the player is moving back and forth near a boundary).

This is a general algorithm for 2D rectangular chunks and a 2D rectangular camera view. It sounds like in your case your chunks are larger than the camera, so you always have at at most four chunks visible; this could simplify things, but I recommend using this algorithm which avoids having any special cases until you're more confident in how to tweak things.

Note that this algorithm does not care how the camera is moving, or when it crosses a boundary. It only makes sure that the current frame is drawn correctly, regardless of what happened before. (I suspect trying to make use of the previous position/movement is part of your original problem.) This also means that it can handle arbitrary movement like teleporting or respawning.

\$\endgroup\$
3
  • \$\begingroup\$ You should probably find the chunks in an area a little larger than the visible rectangle, so you can load chunks with NPCs that are just offscreen and to load/generate chunks before you immediately need them. Bonus points for putting loading and generation on separate threads. \$\endgroup\$ Commented Jul 6, 2013 at 20:28
  • \$\begingroup\$ Oh, yes, good point. If you have active NPCs, you definitely want to load and simulate a larger region. The original algorithm is still appropriate for deciding which chunks to draw. \$\endgroup\$
    – Kevin Reid
    Commented Jul 6, 2013 at 20:42
  • \$\begingroup\$ This is excellent information. You are correct, I was going about this using movement and that's what complicated everything. I will begin to implement this later tonight! \$\endgroup\$
    – Steven B.
    Commented Jul 7, 2013 at 1:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .