-
-
Save mquaker/2d9f51305b16e9cd41a715c688bd6f57 to your computer and use it in GitHub Desktop.
Pixel Perfect Collision
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool HelloWorld::areSpritesColliding(cocos2d::CCSprite *spr1, cocos2d::CCSprite *spr2, bool pp) { | |
bool isColliding = false; | |
CCRect intersection; | |
CCRect r1 = spr1->boundingBox(); | |
CCRect r2 = spr2->boundingBox(); | |
// Look for simple bounding box collision | |
if (r1.intersectsRect(r2)) { | |
// If we're not checking for pixel perfect collisions, return true | |
if (!pp) { | |
return true; | |
} | |
CCLog("Bounding Box Collision"); | |
float tempX; | |
float tempY; | |
float tempWidth; | |
float tempHeight; | |
if (r1.getMaxX() > r2.getMinX()) { | |
tempX = r2.getMinX(); | |
tempWidth = r1.getMaxX() - r2.getMinX(); | |
} else { | |
tempX = r1.getMinX(); | |
tempWidth = r2.getMaxX() - r1.getMinX(); | |
} | |
if (r1.getMinY() < r2.getMaxY()) { | |
tempY = r1.getMinY(); | |
tempHeight = r2.getMaxY() - r1.getMinY(); | |
} else { | |
tempY = r2.getMinY(); | |
tempHeight = r1.getMaxY() - r2.getMinY(); | |
} | |
intersection = CCRectMake(tempX * CC_CONTENT_SCALE_FACTOR(), tempY * CC_CONTENT_SCALE_FACTOR(), tempWidth * CC_CONTENT_SCALE_FACTOR(), tempHeight * CC_CONTENT_SCALE_FACTOR()); | |
unsigned int x = intersection.origin.x; | |
unsigned int y = intersection.origin.y; | |
unsigned int w = intersection.size.width; | |
unsigned int h = intersection.size.height; | |
unsigned int numPixels = w * h; | |
if (numPixels<=0) return false; | |
// Draw into the RenderTexture | |
CCSize size = CCDirector::sharedDirector()->getWinSize(); | |
CCRenderTexture *rt = CCRenderTexture::create(size.width, size.height, kCCTexture2DPixelFormat_RGBA8888); | |
rt->beginWithClear(0, 0, 0, 0); | |
// Render both sprites: first one in RED and second one in GREEN | |
glColorMask(1, 0, 0, 1); | |
spr1->visit(); | |
glColorMask(0, 1, 0, 1); | |
spr2->visit(); | |
glColorMask(1, 1, 1, 1); | |
// Get color values of intersection area | |
ccColor4B *buffer = (ccColor4B *)malloc( sizeof(ccColor4B) * numPixels ); | |
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer); | |
rt->end(); | |
// Read buffer | |
unsigned int step = 1; | |
for(unsigned int i=0; i<numPixels; i+=step) { | |
ccColor4B color = buffer[i]; | |
//CCLog("Pixel color: %d, %d, %d", color.r, color.g, color.b); | |
if (color.r > 0 && color.g > 0) { | |
isColliding = true; | |
CCLog("Colliding"); | |
break; | |
} | |
} | |
// Free buffer memory | |
free(buffer); | |
} | |
return isColliding; | |
} | |
bool HelloWorld::collideAtPoint(cocos2d::CCSprite* pSprite, cocos2d::CCPoint point) { | |
bool bCollision = false; | |
int searchWidth = 1; | |
int searchHeight = 1; | |
unsigned int numPixels = searchWidth * searchHeight; | |
CCSize size = CCDirector::sharedDirector()->getWinSize(); | |
CCRenderTexture *rt = CCRenderTexture::create(size.width, size.height, kCCTexture2DPixelFormat_RGBA8888); | |
rt->beginWithClear(0, 0, 0, 0); | |
// Render both sprites: first one in RED and second one in GREEN | |
glColorMask(1, 0, 0, 1); | |
pSprite->visit(); | |
glColorMask(1, 1, 1, 1); | |
// Get color values of intersection area | |
ccColor4B *buffer = (ccColor4B *)malloc( sizeof(ccColor4B) * numPixels ); | |
glReadPixels(point.x, point.y, searchWidth, searchHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); | |
unsigned int step = 1; | |
for(unsigned int i=0; i<numPixels; i+=step) { | |
ccColor4B color = buffer[i]; | |
//CCLog("Pixel color: %d, %d, %d", color.r, color.g, color.b); | |
if (color.r > 0) { | |
bCollision = true; | |
CCLog("Colliding"); | |
break; | |
} | |
} | |
rt->end(); | |
return bCollision; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment