Creating and storing map data

Feanor
Unregistered
 
Post: #16
Quote:Originally posted by NCarter
Basically, whenever the player crosses a node boundary, you need to load the nodes on the opposite side of the new node. You could also cache the nodes the player has been in recently in case they keep walking back and forth, as w_reade said.

I'll describe my idea of how to do this. Untested!

This kind of thing comes up a lot, like in doing Level of Detail model swapping. Basically you want to avoid what is analogous to vertex popping in LOD swapping. In this case, you don't want to load/unload data repeatedly when the user is walking on a threshold. So the fix is to have two thresholds: near and far. So you load a map tile when the user is X tiles away, and unload when it is Y tiles away, and Y would be X+d, with d the distance between the thresholds. It's like a buffer.

How well this works depends upon how complicated your map details are. Sometimes you won't be able to avoid load pauses, in which case you want to create your maps to limit the places where loads occur, and then load a lot at once. But if you want map areas where the free movement space is bigger than the memory to hold it, you have to do thresholds.

The easy thing about thresholds is that the player can only move one square at a time East/West and one square North/South, so you in fact would load tiles in strips X tiles away in the direction movement, and unload them Y tiles away in the opposite direction. I suggest making X so it's just outside of visibility, but make Y as far away as you can. You can keep less tiles in memory if you make the thresholds octagon shaped instead of square. If this user is walking left (or West), the map tile status chart look like:
Code:
O.O.O.O.O.O.O.O.O.O.O.O
O.O.O.X.X.X.*.*.*.O.O.O
O.O.X.X.X.X.X.*.*.*.O.O
O.X.X.X.X.X.X.X.*.*.*.O
O.X.X.X.+.X.X.X.*.*.*.O
O.X.X.X.X.X.X.X.*.*.*.O
O.O.X.X.X.X.X.*.*.*.O.O
O.O.O.X.X.X.*.*.*.O.O.O
O.O.O.O.O.O.O.O.O.O.O.O

(O is not loaded, * is inside far threshold, X is in near threshold, + is player)

That just means that the load/unload algorithms are a bit more complicated, but you would probably just use a list of loads and unloads with the offsets in them already. If the user is located at grid(x,y), then when he moves one square left, do:

load( x-2, y+3);
load( x-3, y+2);
load( x-4, y+1);
load( x-4, y);
load( x-4, y-1);
load( x-3, y-2);
load( x-2, y-3);
unload( x+4, y-3);
unload( x+5, y-2);
unload( x+6, y-1);
unload( x+6, y);
unload( x+6, y+1);
unload( x+5, y+2);
unload( x+4, y+3);

Just adjust the threshold distances as necessary. The harder challenge is remembering which tiles between the thresholds are already loaded. You could have a giant grid of bits to toggle, but that seems very wasteful. I should think a linked list of linked lists of tiles would do the trick. (This would be easier with a square pattern than an octogon Smile You could have ten linked lists for East/West, and have a single list of all these lists pointing at the tiles directly North and South of the player. If she walks East or West, you are adding/removing single tiles from the East/West lists. If she walks North/South, you are adding/removing entire lists of tiles. Each time the player crosses to a new tile, you walk the lists, load/unload, and update the addresses of the centre lines.

If this is confusing, maybe I'll write some sample code in C that would demonstrate it...

--FÎanor
Quote this message in a reply
Jeff Binder
Unregistered
 
Post: #17
The code I posted automatically starts a new row once enough characters have been read. Putting the rows on separate lines is just for readability, it doesn't matter where the newlines are. So, for example, this input:
mmmmmm
mmmm
mmmmm
mm
mmmmmmmm
mmmmm

is interpreted as this array:
m m m m m
m m m m m
m m m m m
m m m m m
m m m m m

I tested the code and it worked right with stdin as the file. Could you post the code you're trying now?
Quote this message in a reply
DrKane
Unregistered
 
Post: #18
<<I tested the code and it worked right with stdin as the file. Could you post the code you're trying now? >>

You're right. It does work fine, I just wrote it slightly differently and meesed up. Thanks for the code.
Quote this message in a reply
Feanor
Unregistered
 
Post: #19
So I lied, and I wrote a program in Objective-C instead of C to demonstrate my (possibly not that interesting :o ) dynamic map-data loading/unloading algorithm. I dunno, it was kind of fun to write. It might still be buggy, but I tested it pretty thoroughly -- oh, except the colour-coding doesn't quite work the way it should, but you'll get the idea.

It will be interesting if I convert it to use a texture for the surface of the "map tiles" instead of just drawing flat green squares. But hey, it's an algorithm demo.

DynaMap!

--FÎanor
Quote this message in a reply
DrKane
Unregistered
 
Post: #20
I tried downloading the file but it will only open using a hex editor.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #21
Are you using OS X?! It worked fine for me....
Quote this message in a reply
Feanor
Unregistered
 
Post: #22
Quote:Originally posted by DrKane
I tried downloading the file but it will only open using a hex editor.
It's a .dmg disk image file -- you need Disk Copy OS X as OSC hinted. I can repackage it with Stuffit so you can read the code if necessary, but I'm trying to get away from that program now. -- FÎanor

edit - ok I've put up a .sit (so small why not?): DynaMap.sit

Also, fixed the bug with drawing some squares wrong colour -- just needed a couple more if statements.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Storing data for action replays monteboyd 4 3,847 Dec 5, 2005 04:14 PM
Last Post: Frank C.