davisdude wrote:Say for instance, you have non-tile-based-movement. How then would it be implemented? I guess you would check if the screen is covering the tile at all, then draw it, right? But then that would require you to loop through the tables, wouldn't it?
Not necessarily. This kind of problem has been studied already. The solution to the problem of "detecting quickly which shapes overlap with a given shape" is resolved with a family of data structures called
Spatial Databases. Quadtrees are one kind of spatial databases, but they are not the only one. Grids serve this purpose too - they are also simpler to understand and implement than quadtrees, and offer similar speeds (I have implemented both).
When you use a grid for spatial hashing, you do the following:
- The grid is formed by rows (for example grid.rows). Each row has cells(i.e. grid.row[1].cells[2]). Each cell has a list of "items touching it"(grid.row[1].cells[2].touching[item]=true).
- When you insert a new "shape" in the system, you iterate over all the cells that "touch" it, and put add the item to the "list of items touching that cell" (row[y].cell[x].touching[item] = true). I quote "touch" because you don't really need to insert exactly those cells and those cells only. In most cases it's ok to use the bunding rectangle around the shape to mark the cells. You will mark more cells than the item really touches, but that's ok. Using a rectangle, you can use the trick I showed before with the loops and the left,right,top,bottom.
- When you remove a shape from the system (for example, a killed enemy) then you just remove it from all the cells that were touching it (again, you don't have to iterate over all the cells, just the ones the were touching it when it disappeared).
- When you move a shape around, you first remove it, and then you add it again.
- When you need to draw the screen, you do the same thing you did before with the tile-based approach: you parse all the cells, and "draw" the items in them (you will probably want to have some sort of dictionary so that you don't draw the same objects more than once).
This approach also works great for doing collision testing - instead of testing "every object with every object", the spatial hash allows you to test every item with "just the objects on the same cells as the item". If you think about it, in the particular case of a camera, what you are really doing is testing that the "rectangle of the screen" collides with some of your items, and then doing an action according to that (in this case, draw the items colliding). This is the approach I use in
bump. I believe that HardonCollider uses a similar approach.