Say I have a 2D tile based game engine (I don't, but I will soon). I was wondering how I would manage drawing adjacent maps. That is, imagine we have a map that is 50 by 50 tiles wide. Then next to that, we have another map which of the same size - but they are loaded via separate files. So they are visibly next to each other.

Let's call the first map (the one we are on) A, and the second map B. How would I:

  1. Draw the two maps next to each other at the combining point (provided that I have already saved data about what maps are next to each other, and at what point), so they join seamlessly, without the need for a loading screen / "teleport".
  2. Manage entity positions. Positions, currently, are managed relatively. That is, each map has it's own (0, 0) tile. How would I manage this when drawing an entity? I was thinking about storing a pointer to the map the entity, and if it happens to change map, the pointer is updated, and we - somehow - find the tile the entity would move on to.

I should mention that only the player will ever need the use for this movement.

Any ideas? Sorry if I wasn't very clear.

  • \$\begingroup\$ What are you using for drawing, OpenGL? \$\endgroup\$ – kravemir Aug 3 '12 at 19:08
  • \$\begingroup\$ Yes, I'm using the Slick2D library which uses OpenGL. \$\endgroup\$ – Dan Aug 3 '12 at 19:24

From your question I assume you're planning to create big world and to minimize ram/bandwidth usage you want to separate this world into many partitions(maps).

Entities with relative position to map can be shifted by partition position during drawing. But this isn't the best idea, because you have to shift all these entities each frame. Better idea would be to shift all entities at loading.

To manage partitions I would recommend to create class Partition for each one and store them into 2D array like tiles. To pick desired partition you'll simple divide position( in computer it should be rounded down ): partition = partitions[x/50][y/50] and to pick tile: tile = partition.tiles[x%50][y%50] or tile = partition.tiles[x-partition.x][y-partition.y]

  • \$\begingroup\$ So essentially load all maps and then divide them into 50x50 tile partitions and then use aforementioned math? \$\endgroup\$ – Dan Aug 3 '12 at 20:06
  • \$\begingroup\$ Why load all maps? You only need to load active partitions(maps). You can manage them like tiles, because they have same size. \$\endgroup\$ – kravemir Aug 3 '12 at 20:09
  • \$\begingroup\$ No problem and you're welcome :) \$\endgroup\$ – kravemir Aug 3 '12 at 20:27

One simple way to handle this is to simply use absolute positions for everything. When storing maps or entity positions you use and store them absolutely instead of relative to each individual map. This makes entities switching between maps seamless, because they're simply just moving one more position. As an example, your first map would have its bottom corner at (0,0). The next map to the right would have its bottom corner at (50,0) and so on. This does introduce the issue of negative positions. This is not a problem, as long as you're not using the position as an index into an array. If you're wanting to use the position as an index into the array, you would first subtract the offset from center. So the map you have at (50,0) would index into its tile array with tileArray[xPos - globalX][yPos - globalY] Where globalX and globalY would be 50 and 0 respectively.

  • \$\begingroup\$ This would be a good idea, I didn't think of that. But I don't know how many maps I will be using so how would I position them relatively? There could be very many. \$\endgroup\$ – Dan Aug 3 '12 at 19:24
  • \$\begingroup\$ How do I explain this in a better way - I don't know how every map will be laid out. I was thinking, taking this approach, I would load every single map, sort them "virtually" and then arranging each tile with global co-ordinates? \$\endgroup\$ – Dan Aug 3 '12 at 19:26
  • \$\begingroup\$ The suggestion here is you store the entities global cordinates - think GPS. \$\endgroup\$ – Vaughan Hilts Aug 3 '12 at 19:52
  • \$\begingroup\$ I know that, what I mean is - I can't know the global position without combining the maps in some way, shape, or form - virtual or not. \$\endgroup\$ – Dan Aug 3 '12 at 20:04
  • \$\begingroup\$ The answer you've accepted does not provide a method for determining the location of maps globally either. It is essentially the same method as I suggested. Can you explain what about the answer you accepted allows you to avoid knowing the global position of the map? I'm confused as to how you won't know the global position of each map when generating them. \$\endgroup\$ – MichaelHouse Aug 3 '12 at 20:38

I assume you want a seamless world:

  • For every Map pointers to the adjacent maps should be saved.
  • Always load the maps adjacent to the current one so that it always already loaded when you see it.
  • This loading should be done in a seperate thread so player doesn't notice the loading times.
  • When for any reason the map has not finished loading when the player reaches them, show loading screen.
  • The current and the adjacent maps should be drawn.
  • Every map should have it's own list of objects.
  • Update the entities far away maps less frequent/with less precision.
  • Moving entities should sometimes check whether they have crossed the border to a other map and be transferred from one to the other map.
  • If your objects are quite big or the map borders are a problem collision checks should include the objects of the adjacent maps, too. This can be optimized by saving how big the biggest object is and then only include the adjacent maps when the object is in a area of the map where this biggest object could possibly overlap.
  • Free very far away maps when a certain amount of maps are in memory. (Depending on platform and map-complexity)

About the actual question:
The coordinates of the entities themselves should be absolute because relative coordinates would have to be converted whenever you do position depended calculations which should also work over map borders.


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.