Collision Detection by zkman 07.10.99
Collision detection is a coding technique that you will use in many facets of your
programming future. From the simplest of a side-scroller to a pixel-scrolling rpg
to a G-Radius style shooter and on into 3d, you will need to know the basic fact of
whether one object is intersecting with another. There are infinite ways of doing
"approximatations" of whether objects are touching, which is what this article is about,
since for qb's purposes, pixel-perfect collision is both extraneous and usually too
slow for the average coder.
There are 4 common types of collision detection in 2 dimension that you will use in your coding:
So, how do you do 'em
Manhattan detection essentially creates a "square diamond" around two objects, and checks to see if there is the distance from the center of one diamond to the edge of that diamond plus the distance from the center of diamond2 to the edge of that diamond is less than the "manhattan distance". It's very easy to do:
Distance = (ABS(Center1x - center2x) + ABS(center1y - center2y))
If Distance is less than the size of the tile, then it is a collision. For instance, if the tiles were 20 by 20, and Distance was less than 20, then the objects are colliding. This is the fastest method of detection (being only 3 calculations with no division or multiplication), but unfortunately, the "diamond" is not the shape of many tiles (such as a house).
Bounding BoxBounding Box detection is the method most commonly found in both qbasic games and professional 2d games on older systems because it is both easy to understand, reasonably fast, and fairly sizable. This method creates a "box" or square around a tile (and because most tiles are fairly square, the detection is pretty accurate), and checks the corners of that box with the corners of the other tile's box. It works as below:
In this example, obj1x is the x position of the first tile, obj2x is the x position of the second tile, obj1y and obj2y are the y positions of the tiles, and tilewidth and tileheight are the size of the tile (such as 16 by 16 or 20 by 20). This form allows for rectangles also by making tilewidth and tilelength different as per the size of your tile.
RadiusThe Radius detection method will be familiar to anyone with basic geometry skills, as it is simply the distance formula applied to programming. The distance formula is, of course, SQR(((x - x2)^2) + ((y - y2)^2)). This formula is applied to code by using
Dist = SQR(((tilex - circenterx)^2) + ((tiley - circentery)^2)
tilex and tiley are the center of the tile you're checkin, and circenterx/y are the center of the tile where the circle should "originate" from. To see if they're colliding, simply Check to see if Dist < (CircleTileSize - tilesize / 2) where tilesize is from the "boxed" tile and circletilesize is from the circular tile. Because this method is extremely slow in qb compared to the other two (due to three square functions, which qb is notoriously bad at), use this only when absolutely necessary.
It could be that each of these routines could be sped up significantly, as they are all from my personal experience, but as they are, they represent the base from which you should be able to code any collision routines your game needs. The only time that pixelperfect routines would be necessary that I can think of, is if you need the direction of the impact vector of two objects (such as in SpaceARoo2). Later!
I wanted Space-a-Roo 2 to have pixel-perfect hit detection and this is the best way I could think of to get well-rounded results:
UPs to this method
DOWNs to this method