4
\$\begingroup\$

I am making a 2d tile based game in C# and XNA 4.0. I am having trouble loading and unloading "chunks" of tiles(blocks). The whole world is randomly generated and is infinate on both axis. How would I go about loading and unloading chunks of tile data in the camera's view?

A pastebin to the pastebin links(I still have the 2 link cap):

http://pastebin.com/9PYr8cvC

\$\endgroup\$
5
  • 2
    \$\begingroup\$ World class: pastebin.com/K9Qfzh2z Chunk class: pastebin.com/sCknxzig Camera class: pastebin.com/JMueU0HN Player class: pastebin.com/tm4kUQUb \$\endgroup\$ Commented Mar 5, 2012 at 21:21
  • \$\begingroup\$ There's probably not enough info you gave there. Unless XNA actually has that pre-built, people don't know how you make chunks and so on. \$\endgroup\$
    – jcora
    Commented Mar 5, 2012 at 21:31
  • \$\begingroup\$ @Bane In World.cs there is a method called GetChunk(ChunkLocation location), And a *Location is a Vector2 with custom helper methods. Generator.cs: pastebin.com/PkrnZteN \$\endgroup\$
    – ceriosNerd
    Commented Mar 5, 2012 at 21:41
  • \$\begingroup\$ I get the picture, but know that I never worked with XNA. :) \$\endgroup\$
    – jcora
    Commented Mar 5, 2012 at 22:14
  • \$\begingroup\$ Kinda of already had this question here. \$\endgroup\$ Commented Mar 6, 2012 at 0:55

2 Answers 2

10
\$\begingroup\$

Basically you want to have a range around your camera. When chunks come into this range, you load/generate them. When chunks leave this range, you save/unload. Keep in mind you'll want to keep the loaded range larger than the visible range, so your chunk loading isn't seen.

At the moment it looks like you're storing your chunks in a dictionary. That's kind of a strange choice, and it may be a little more work for you to maintain your chunks with that data structure.

It looks like you've got a lot of the functions you need already, nice work. You'll want a list of chunk positions that should be loaded, your loaded list. Your update loop is going to maintain that list. As the camera moves, you update the list to include all the chunks in the range of the camera.

This is where the dictionary choice is a little strange. Essentially you'd have to loop through all your dictionary entries, unload the chunks that aren't in your loaded list and load the ones that aren't in your dictionary but are in your loaded list. The alternative is to have some sort of linked list structure. Where you can add/remove chunks from either end. This does get a little tricky when dealing with 2D linked lists, but I think you can make it work.

It would look something like this:

Starting with this scenario, where the red dot is the camera, moving in the X plus direction. All the grid squares (chunks) touching the green area are currently loaded.

enter image description here

Then the camera moves far enough to get some new chunks:

enter image description here

All the blue chunks will be loaded/generated. All the red chunks will be unloaded/saved.

As for maintaining the list, you can update whenever the camera moves past a chunk boundary. Like if it moves past the X plus boundary of the chunk it's currently over, like in the example above, the chunks to be added or removed from the list could be found like this:

for(int y = Camera.Position.Y + LoadRange.Y; y >= Camera.Position.Y - LoadRange.Y; y--){
    AddToLoadedList(GetChunkRootPositionAt(Camera.Position.X + LoadRange.X, y));
    RemoveFromLoadedList(GetChunkRootPositionAt(Camera.Position.X - LoadRange.X, y));
}

Where GetChunkRootPositionAt converts a world position into the root position of the chunk that contains that location. And the LoadedList functions take a Vector2 to add/remove from the loaded list.

Finally, you may find adding in a buffer for unloading could be nice. If someone is moving the camera around a lot right on a chunk boundary, you can save a lot of loading/unloading by just keeping it loaded. Essentially, you may find that unloading at the same time as loading isn't necessarily the best option.

\$\endgroup\$
14
  • \$\begingroup\$ why not use a dictionary with the x,y (and z if you're that way inclined) coords as your key? like: {'0:0': chunk0, '1024:0':chunk1} \$\endgroup\$ Commented Mar 5, 2012 at 23:10
  • 2
    \$\begingroup\$ Arrays have a faster look up time, use less memory as there is no hash, and are contiguous so their faster to iterate through should that ever be necessary. \$\endgroup\$ Commented Mar 5, 2012 at 23:28
  • 1
    \$\begingroup\$ Also I wouldn't suggest a 2d linked list I would suggest a graph via an adjacency list. That way finding the next chunk would only take looking at the 4 or 8 adjacent chunks and if there isn't one in the desired location you can generate it then and add it to your graph. \$\endgroup\$ Commented Mar 5, 2012 at 23:31
  • \$\begingroup\$ That's close to how the dictionary is currently being used. But the key is ChunkLocation, which I'm sure at least has the x,y(z). The reason for the linked list (or similar structure) is it's easier to keep track of where things are. For example, it's harder to iterate through all the chunks on the X-minus side of the world with a dictionary, since you'd first have to look through the entire dictionary to find all the chunks there. I think it'll save headaches in the future, but that's just my opinion. \$\endgroup\$
    – House
    Commented Mar 5, 2012 at 23:36
  • 1
    \$\begingroup\$ @Danjen In this case, since we're talking about a regular grid, the adjacency list would likely also contain information about direction. It's not strictly like a typical graph theory adjacency list. \$\endgroup\$
    – House
    Commented Oct 8, 2014 at 2:05
1
\$\begingroup\$

Find out how large your screen is and only render tiles that fall within that range. You might need a camera object to keep track of this data and some sort of x & y offset variables to keep track of movement around the world.

if(tile is inside of the window)
    render;
\$\endgroup\$
1
  • \$\begingroup\$ I understand that concept but, but I don't understand how to: A. Get center of the camera B. Check the camera window vs the viewport window \$\endgroup\$
    – ceriosNerd
    Commented Mar 5, 2012 at 20:55

You must log in to answer this question.

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