Original Post
I have a working 2D collision method, but it is extremely slow. I works by using a collision mask, not by using 1s and 0s, but by using a xy coordinate in a vector. Then when I check for collision, I check the bounding rects first, if they collide then I check on pixel level.
collision.h
collision.cpp
I'm not storing all the pixels in the mask, instead I got the idea of storing a outline of the image to speed it up a bit.
collision.h
[source lang ="cpp"]#ifndef _COLLISION_#define _COLLISION_#include "gfx_dx9.h"#include <vector>using namespace std;class object;class objectManager;struct bit{ bit( float bx, float by):x(bx),y(by){} float x, y;};struct mask{ vector<bit*> bits; RECT bbox; unsigned long *pBits;}; void setObjectManager( objectManager *om);mask *create_mask( sprite *index);bool collision_check( object *a, float x, float y);bool collision_check_rect( RECT a, RECT b);#endifcollision.cpp
[source = "cpp"]#include "collision.h"#include "object.h"#include "objectManager.h"objectManager *objMan;void setObjectManager( objectManager *om){ objMan = om;}mask *create_mask( sprite *index){ mask *tmp = new mask; tmp->bbox = index->bbox; D3DLOCKED_RECT rect; index->texture->LockRect( 0, ▭, NULL, D3DLOCK_READONLY); for ( DWORD y = 0; y < index->info.Height; ++y) { for ( DWORD x = 0; x < index->info.Width; ++x) { DWORD* pBits = (DWORD*)((BYTE*)rect.pBits + y*rect.Pitch); DWORD lastPixel = pBits[x-1]; DWORD pixel = pBits[x]; DWORD nextPixel = pBits[x+1]; if( pixel & 0xff000000 && ( ( y == 0 || lastPixel == 0x00) || ( y == index->info.Height || nextPixel == 0x00)) ) { tmp->bits.push_back( new bit( x, y)); //tmp->pBits[y*index->bbox.right + x] = 1; } } } index->texture->UnlockRect( NULL); return tmp;}bool collision_check( object *a, float x, float y){ mask *mask_a = a->collsion_mask; object *b; int line = 0; while (line < mask_a->bbox.bottom) { for ( int px = 0; px <= mask_a->bbox.right; ++px) { if (px >= mask_a->bbox.right) { line+=1; } b = objMan->getObjectAt( a, x+px, y+line); if (b != NULL){ break;} } if (b != NULL){break;} } if (b == NULL) { return false; } mask *mask_b = b->collsion_mask; vector<bit*> bits_a = mask_a->bits; vector<bit*> bits_b = mask_b->bits; float x1, x2, y1, y2; x1 = floor(a->x); y1 = floor(a->y); x2 = floor(b->x); y2 = floor(b->y); RECT bbox_a = { (LONG)x1, (LONG)y1, (LONG)x+mask_a->bbox.right, (LONG)y+mask_a->bbox.bottom }; RECT bbox_b = { (LONG)x2, (LONG)y2, (LONG)x2+mask_b->bbox.right, (LONG)y2+mask_b->bbox.bottom }; bool result = false; if (collision_check_rect( bbox_a, bbox_b)) { for ( UINT a = 0; a < mask_a->bits.size(); ++a) for ( UINT b = 0; b < mask_b->bits.size(); ++b) { float bx1, bx2, by1, by2; bx1 = bits_a[a]->x+floor(x1); by1 = bits_a[a]->y+floor(y1); bx2 = bits_b->x+floor(x2); by2 = bits_b->y+floor(y2); if ( (bx1 == bx2) && (by1 == by2)) { result = true; break; } } } return result;}bool collision_check_rect( RECT a, RECT b){ bool result = false; int x1, x2, y1, y2, w1, w2, h1, h2; x1 = a.left; y1 = a.top; w1 = a.right; h1 = a.bottom; x2 = b.left; y2 = b.top; w2 = b.right; h2 = b.bottom; if ( (w1 > x2 && w2 > w1) || (x1 < w2 && x2 < x1) || (x1 < x2 && w1 < w2) || (h1 > y2 && h2 > h1) || (y1 < h2 && y2 <y1) ) { result = true; } return result;}I'm not storing all the pixels in the mask, instead I got the idea of storing a outline of the image to speed it up a bit.