Tuesday, February 13, 2018

c# - Loading and unloading "chunks" of tiles in a 2d tile engine with 2d camera


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



Answer



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.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...