When tile-based worlds collide...

Blitz3D Forums/Blitz3D Programming/When tile-based worlds collide...

Adam Novagen(Posted 2009) [#1]
Hey all,

Okay, so I'm getting rather frustrated with my apparent ineptitude at programming collisions in a tile-based world. Here's the story:

I have a world engine which is based on tiles 50x50 pixels in size. The maps are stored in a 200 x 200 array, allowing up to 40,000 tiles per world. The movement within these tiled worlds, however, is free and pixel-based, which is to say, you're not confined to moving one square at a time. So, you could stop on the border between two tiles if you wanted to. The enemies move the same way, freely.

The player is laways at the center of the screen, while the map moves around them. I've used an RGB pixel-based collision routine here, and it works great. However, the enemies need to be able to move even while they're offscreen, which means that a pixel-based collision routine won't work; offscreen RGB values always return 0,0,0.

So, I've been trying to figure out some kind of formula or routine for the enemies, and failing miserably. Any ideas, anyone?


SoggyP(Posted 2009) [#2]
Hello.

When offscreen do the enemies need the same level of collision detail as when on screen?

I tend to use a zonal collision system that deals with collisions in increasing levels of granularity. Ie, I'll split my world into chunks and only do collisions against those that are in the same chunk.

I think Sswift did a posting that described the same methodology very well. Perhaps have a look for that.

Goodbye.


Adam Novagen(Posted 2009) [#3]
Yeah, the enemies' collision routines need to retain the same degree of accuracy onscreen and off.


Sledge(Posted 2009) [#4]
Doing collision based on RGB is URK! Each entity should have world coordinates and from those world coordinates you can work out exactly which tile (or even which pixel of which tile) they're stood on and where to draw 'em relative to the "camera's" position.

If you really need to know which particular pixels in a tile can be collided with (rather than just the whole tile) then maintain a counterpart array for each tile and write the collision mask to it. You won't have the time overhead associated with reading pixels and the tile won't have to be on-screen to be read for collisions if you refer to the array instead.


Wings(Posted 2009) [#5]
You ned to draw in ms paint like me




Warner(Posted 2009) [#6]
Well, I suppose your collision routine is based on the fact that a the part of the gameworld that the player collides with is allready drawn to the screen. That is not the case for the offscreen enemies.
You could adapt the routine so that enemies can also use the same system:
1. scroll the gameworld towards the enemy
2. Cls
3. draw the level to the screen
4. handle enemy collisions
5. Cls
6. scroll back to the mainplayer
7. draw the gameworld
8. handle player collisions
9. Flip.
But I can imagine it would become quite slow. Instead, you could maybe better use ImagesCollide for your collisions. That way, you can check the collisions between the enemy and a certain tile on a certain location.
You would need to identify all the tiles that the enemy would overlap after it's next move, in the way that Wings drawn out, and check if the enemy collides with them.
In the code archives I posted a tile engine you could check out.


Ross C(Posted 2009) [#7]
Whenever a i did tile based games, i just checked to see whether the player/enemy was overlapping a new tile or not. If the new tile wasn't walkable, then move the player/enemy back to it's co-ords before it moved.


Adam Novagen(Posted 2009) [#8]
Yeah, me too, Ross... At least, that's the THEORY I'm working on. I can't seem to work out an accurate coordinate system for the enemies, though. The player is easy: always being center screen, it's just a question of dividing the map's X/Y coords by 50 (the tile size) and including an offset. However, since the enemies move relative to the map, which is relative to the player, I just can't get a successful coordinate formula going. T_T


Sledge(Posted 2009) [#9]
since the enemies move relative to the map, which is relative to the player, I just can't get a successful coordinate formula going
I remember this problem well -- it comes from getting logic and rendering mixed up with one another (ideally your program should function without rendering anything). Like I mentioned, everything needs a world coordinate -- tiles, enemies, the player and even the camera (because having a concept of a camera is as useful in 2D as 3D). Once you've done that you render whatever you need relative to the camera's world x/y because every object already has its own world x/y relative to it. How a world x/y translates to the screen is up to you, but I tend to have the camera render a screen's worth of tiles to the right and below it, rather than conceptualise it as rendering centrally:
|---------------|
|X              | 
|               | Camera's world x/y as screen 0,0
|               |
|---------------|

|---------------|
|               | 
|       X       | Camera's world x/y as screen gwidth/2,gheight/2
|               |
|---------------|



Adam Novagen(Posted 2009) [#10]
Guess what; I figured it out within five minutes of leaving this thread. After TWO MONTHS of grappling with the problem, I find that the solution is as simple as a division routine. A ONE-LINE division routine. I want to kick myself. >_<

Anyway, at least Midnight Hacker is back underway now. Thanks for the help guys!


Wings(Posted 2009) [#11]
My engine is only data stored in array.

has nothing to realy do with screen.



the picture theory i draw above is the sollution for fast collision detection. its not pixel perfect.


Sledge(Posted 2009) [#12]
I find that the solution is as simple as a division routine.
Out of interest, what happens when the player is situated in a corner of the map and you no longer want him displayed at the centre of the screen? ;P


Adam Novagen(Posted 2009) [#13]
Nothing; the player is always centered. See, the map is a kind of hovering "cyberspace grid," and it has an animated background under it, so it doesn't matter if the edge appears or not, it still looks good & natural. I'll post a screenshot sometime.


smilertoo(Posted 2009) [#14]
You can do a walk zone, player is in the middle as long as the map is moving...then player moves towards edge.


andy_mc(Posted 2009) [#15]
Adam, are you wanting it to look like my platform game I'm working on here?: http://www.youtube.com/amcadam26


Sledge(Posted 2009) [#16]
I'll post a screenshot sometime.
Coolio.

Adam, are you wanting it to look like my platform game I'm working on here?
Nice vids -- what did you capture them with?


Wings(Posted 2009) [#17]
the A ONE-LINE division routine. is the right path for fast 2d collisions in giantic maps even for the NPC :)