iPhone でゲームを開発しています。ピクセル パーフェクト コリジョンは、1 つのスプライトがシーンに表示される場合にのみ機能します。それ以外の場合は機能しません。情報を提供していただけますか?
このコードは、アニメーション化されたスプライト (スプライトシート) 間のピクセルの完全な衝突に使用されました。
-(BOOL) isCollisionBetweenSpriteA:(CCSprite*)spr1 spriteB:(CCSprite*)spr2 pixelPerfect:(BOOL)pp
{
BOOL isCollision = NO;
CGRect intersection = CGRectIntersection([spr1 boundingBox], [spr2 boundingBox]);
// Look for simple bounding box collision
if (!CGRectIsEmpty(intersection))
{
// If we're not checking for pixel perfect collisions, return true
if (!pp) {return YES;}
CGPoint spr1OldPosition = spr1.position;
CGPoint spr2OldPosition = spr2.position;
spr1.position = CGPointMake(spr1.position.x - intersection.origin.x, spr1.position.y - intersection.origin.y);
spr2.position = CGPointMake(spr2.position.x - intersection.origin.x, spr2.position.y - intersection.origin.y);
intersection = CGRectIntersection([spr1 boundingBox], [spr2 boundingBox]);
// Assuming that the spritebatchnode of both sprites is the same, I just use one. If each sprite has a different sprite batch node as parent you should modify the code to get the spriteBatchNode for each sprite and visit them.
CCSpriteBatchNode* _sbnMain =(CCSpriteBatchNode*) spr1.parent;
//NOTE: We are assuming that the spritebatchnode is always at 0,0
// Get intersection info
unsigned int x = (intersection.origin.x)* CC_CONTENT_SCALE_FACTOR();
unsigned int y = (intersection.origin.y)* CC_CONTENT_SCALE_FACTOR();
unsigned int w = intersection.size.width* CC_CONTENT_SCALE_FACTOR();
unsigned int h = intersection.size.height* CC_CONTENT_SCALE_FACTOR();
unsigned int numPixels = w * h;// * CC_CONTENT_SCALE_FACTOR();
// create render texture and make it visible for testing purposes
int renderWidth = w+1;
int renderHeight = h+1;
if(renderWidth<32)
{
renderWidth =32;
}
if(renderHeight < 32)
{
renderHeight =32;
}
renderTexture = [[CCRenderTexture alloc] initWithWidth:renderWidth height:renderHeight pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
//rt is always going to be at 0,0 - can't change it.
renderTexture.position = CGPointMake(0, 0);
[self addChild:renderTexture];
renderTexture.visible = NO;
//NSLog(@"\nintersection = (%u,%u,%u,%u), area = %u",x,y,w,h,numPixels);
// Draw into the RenderTexture
[renderTexture beginWithClear:0 g:0 b:0 a:0];
// Render both sprites: first one in RED and second one in GREEN
glColorMask(1, 0, 0, 1);
[_sbnMain visitSprite:spr1];
glColorMask(0, 1, 0, 1);
[_sbnMain visitSprite:spr2];
glColorMask(1, 1, 1, 1);
// Get color values of intersection area
ccColor4B *buffer = malloc( sizeof(ccColor4B) * numPixels );
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
[renderTexture end];
// Read buffer
unsigned int step = 1;
for(unsigned int i=0; i<numPixels; i+=step)
{
ccColor4B color = buffer[i];
if (color.r > 0 && color.g > 0)
{
isCollision = YES;
break;
}
}
// Free buffer memory
free(buffer);
spr1.position = spr1OldPosition;
spr2.position = spr2OldPosition;
[renderTexture release];
[self removeChild:renderTexture cleanup:YES];
} return isCollision;}