Skip to content

Instantly share code, notes, and snippets.

@syuhari
Last active December 3, 2018 02:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save syuhari/6442522 to your computer and use it in GitHub Desktop.
Save syuhari/6442522 to your computer and use it in GitHub Desktop.
Pixel Perfect Collision
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