Actually, this doesn't paint the entire picture for collision, and there are multitidue of ways to check for collision, some faster than others. While you are correct, for the purposes of Sonic, at some point, you're going to need to do this (which is really just basic trigonometry), how you check for collision, and how often is incredibly important. For example, you don't want to have to check every single point on the screen, that is what results in poor performance (and usually will make your CPU load increase by a ton). There are plenty of collision checking methods out there, from a simple axis-aligned bounding box, to complex circle collision, and a near infinite amount of methods in between. However, what is smart (and generally not talked about, and not covered at all in the physic guide) is the general approach one should probably take for collision detection. In most game programming, this involves splitting collision into two phases - a broad collision detection phase, and a narrow collision detection phase. You have described one manner of narrow collision detection, but broad collision detection is just as important. The idea behind this principle is that you have a speedier method of collision detection that checks the entire screen first, to determine where and within what range to do the slower, narrower check that you just described. Myself? I use morton encoding, it's a variant of octrees that isn't really taught very often. Moron encoding is a method where you keep a list of every object available on screen at once, be they ground tiles or enemies or whatever. By taking these objects X and Y coordinates and representing them in binary, then interleaving their bits, you arrive at a morton encoded string. To give an example, say I have 4 objects, at the following positions: 1, 2 -> 001, 010 -> 000110 2, 2 -> 010, 010 -> 001100 4, 3 -> 100, 011 -> 100101 5, 4 -> 101, 100 -> 110010 There is an interesting phenomenon regarding binary representations of space which morton encoding exploits. Due to the nature of binary spacing, each bit in a morton encoded string will divide the considered screen space in half. This means that, if you begin at 000000 and increase all the way to 111111 you will follow a Z-ordered space filling curve like so: This plays into the concept of the principle of locality, where objects near each other are stored next to each other in memory. Using such curves for general collision detection allows you, for example, to limit a range around sonic (or whatever) to ensure you only check collision around immediately relative objects. It makes no sense, for example, to use expensive narrow collision detection half-way across the screen when it'd be impossible for those two objects to collide. You could visualize the collision checks like so: Where each "box" is a collision check. You see that using a space filling curve like this drastically reduces the number of collision checks necessary. I generally use morton encoding to check for collisions among objects in my memory pool (which, again, plays into how important properly implimenting a memory pool is, because, for example, if objects spawned in your pool automatically spawn in-order then that's one more sort that you don't have to spend time doing -- I use what is known as a free list, that is -- a linked list that uses a union in memory to act as a map for the next available open slot simultaneously -- to speed up my auto sort upon creation. Also -- there are many, many ways to morton encode - some faster than others), but for ground collision detection, I use another method. The way Sonic levels are organized -- by chunk -> block -> tile -- lends itself to a method known as Data Binning. I only have to check the number of chunks visible on the screen, then check the number of blocks visible in each chunk, in order to accurately figure out where to narrow my collision detection to, rather than using narrow collision detection all over the screen at once, because if Sonic is in 1 chunk, he is assuredly not in any other. This is precisely what I mean when I say that there is no single right or wrong way to implement any of this stuff. You can get 10 programmers together and have them write the "same" collision detection routines, and wind up with 10 radically different collision detection systems, that all do precisely the same narrow logic.