Let me start by saying, this tutorial will be short and sweet.. and somewhat advanced! I'm not going to bother explaining how to initialize and terminate DirectDraw, load surfaces, detect rectangle collisions, etc, etc. If you don't know how to do these things, then I don't think you're quite ready for pixel manipulation techniques!
So let's get down to it!
We'll be using the DirectDrawSurface7.GetLockedArray method to extract per-pixel colour values from our surfaces. Clearly, we must first call DirectDrawSurface7.Lock, and this method accepts a couple of arguments:
- r as RECT - The rectangle within the surface you'd like to lock... in theory! In actuality, no matter
how you size this rectangle, you end up locking the whole surface! But this matters little, as you'll see.
- desc As DDSURFACEDESC2 - After the Lock call, this will be filled with a description of the locked surface.
- flags As CONST_DDLOCKFLAGS - We'll use the flags DDLOCK_READONLY and DDLOCK_WAIT since we're only going
to be reading data, and since we don't want to cause any errors (by accessing an un-prepared surface).
- hnd As Long - The SDK says this parameter isn't used, so we set it to zero.
The GetLockedArray method itself only takes one argument, an array of bytes (Note: the array MUST BE DYNAMIC!) to be filled with the surface data. An example:
Dim bytMoving() As Byte
msurfMovingObj.GetLockedArray bytMoving
If we execute this code after having locked the surface, we'll end up with an array POINTING TO the surface memory. Notice, this is merely a pointer.. the array will no longer contain this data after we unlock the surface! This might seem annoying, but it's actually useful. It allows us to access only those pixels whose values we require.. the others we can ignore. Since examining a pixel's data is somewhat costly we can make use of this feature of the GetLockedArray method to minimize the cost of performing the collision detection.
How? Simply lock both surfaces and step through the overlapping area within each of them examining pixel values. By discarding the non-overlapping area we clearly save time (the overlapping RECT is easily obtained through use of the IntersectRect API), and by stepping through each surface's pixels simultaneously, we can cease the exercise as soon as a single overlap is encountered! This is the most efficient algorithm available to you for detecting collisions between irregular objects (regular objects may have properties that allow you to further optimize).
I won't go into the implementation here, it is a simple matter of determining overlapping RECT sizes and performing pixel data comparison. Examine the source code, and it'll all become clear to you!
I hope :) Good luck!