Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making an rpg game. I have a Grid class which takes a char[][] to create tiles. The way I'm currently doing collision detection is by creating a Player and assigning it the grid it should be created in.

However, (because it seems to be the easiest way to do things) I want to be able to have a class that has an array of Grids that only load the map information when neccessary (i.e. when the player is close enough to the next grid).

My past implementation was when i had a Grid[][]. However, this causes problems when I want to walk off my current grid and the game gives me a ArrayIndexOutOfBoundsException. My main concern is this: I want to be able to design a system that loads information as I need it.

My questions are: How should I go about doing this? Is this the most efficient way to design things? If I have to redesign something things, I'm willing to, as I'm in the early stages of game design.

share|improve this question
    
Can't you just set it to "walk off" the current grid and "walk onto" the next grid over? Essentially you're talking about chunks or "chunking" your world. There are a number of answers on the site already about those topics. –  Byte56 Jul 11 '12 at 17:19
    
Chunking is exactly what I'm doing. Is this the best way to do it?/Is this way the only way to do it? –  user1264811 Jul 11 '12 at 17:38
    
It's hard to define best, it could be best for you, only you will know that. It's clearly not the only way to do it. You could use dynamic arrays, linked lists, one array that you shift values through or other fancy data structures. There's lots of ways of doing it, you might not find the best way for you on the first try, and that's OK. Keep going about it like you are, if you find issues you don't like, try a different method. –  Byte56 Jul 11 '12 at 18:24
    
The implementation also depends on whether you allow only movement in fixed steps (the player is only on one tile at a time) or smooth movement (the player can occupy parts of a few tiles at once). –  ChrisC Jul 11 '12 at 22:33
    
The way I do things is a combination of both. The player in reality only occupies one tile. However, when you press a directional button, the player's position is incremented over a short period of time to reach the position of the tile. –  user1264811 Jul 11 '12 at 23:53

2 Answers 2

up vote 1 down vote accepted

If I'm not mistaken, the player's position in your implementation is represented by 4 numbers: GridX, GridY, TileX and TileY. That's a way to do it, and it's completely fine, as long as you don't screw something up with the indexes (which will give you ArrayIndexOutOfBoundsException).

1 . First, whatever happens (the player moves, etc.) just make sure that:

0 <= GridX < Grid.Length

0 <= GridY < Grid[GridX].Length

0 <= TileX < Grid[GridX][GridY].Tiles.Length

0 <= TileY < Grid[GridX][GridY].Tiles[TileX].Length

2 . Only load a Grid, if any of its Tiles are about to become visible.

  (Player.TileX < ScreenWidth/2 
   || Player.TileY < ScreenHeight/2 
   || Player.TileX >= (GridWidth-ScreenWidth/2) 
   || Player.TileY >= (GridHeight-ScreenHeight/2))

Where (ScreenWidth * ScreenHeight) is the number of tiles shown on your main screen at any time, and GridWidth * GridHeight is the number of tiles your grid holds. For example, if your window shows 30x20 tiles, and your Grids hold 100x100 tiles each, then

  ScreenWidth = 30;
  ScreenHeight = 20;
  GridWidth = GridHeight = 100;

3 . Make transitions smooth (if necessary). If your grids are really large, and it takes 1 second to load one into the memory, then you might want to start loading it sooner. For example, when the Player is at a (ScreenHeight/2 + 5) distance from the edge of the Grid. However, it's only necessary if you experience lag while loading a Grid. This might happen if you're reading the Grid data from a huge file on the HDD, or from a distant server.

share|improve this answer
    
So lets say that my player's position is something like this: TileX = Grid[GridX][GridY].Tiles[0] and TileY = Grid[GridX][GridY].Tiles[0]. I move left. Should i just say something like: Player.setGrid(Grid[GridX][GridY-1].Tiles[getLargestTile()]? –  user1264811 Jul 12 '12 at 21:50
    
Nope. The Tile which you player is standing on is: Grid[Player.GridX][Player.GridY].Tiles[Player.TileX][Player.TileY] So if you move left, just do this: Player.TileX -= 1 –  Marton Jul 12 '12 at 21:54
    
Well, of course, you still have to check if that index is valid, just as I said in my answer :-) –  Marton Jul 12 '12 at 22:05

If you want dynamic map loading you need a special data structure to store the level. Easiest way is to split the level into even sized chunks.

For example you could make a chunk an area of 32x32 grid cells. Then you need another class, that takes care of loading and unloading chunks. Make sure that you have the visible chunks and the surrounding ones loaded, as it may take some time to load a chunk.

You need some logic that manages the chunks, means checks if they are enough far away to be unloaded or if they are near enough to be loaded.

Maybe it would be best to start with a fixed sized system to get the arrangement and rendering of the chunks right. If you've done that, you can extend the class so chunks can be dynamically loaded or unloaded.

btw, minecraft uses a similar system of chunks (i think its something like a 16x16x256 cube). You find some information on the internet, how the chunk system in minecraft works. You could use it as inspiration, as you want to do basically the same thing, but in 2d space.

=> http://www.minecraftwiki.net/wiki/Chunks

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.