Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get pixel color from SKSpriteNode or from SKTexture?

I want to get precise selection of my object on game map. Object is a sprite with which has some transparent pixels around and I want to test touch location for these transparent pixels. Any clue?

like image 595
andrey.s Avatar asked Jan 31 '26 00:01

andrey.s


2 Answers

In Sprite Kit you don't have access to texture data.

Instead you'd have to create a bit mask from the image, for example by loading the image as UIImage or CGImage and scanning for all non-transparent pixels.

like image 166
LearnCocos2D Avatar answered Feb 02 '26 15:02

LearnCocos2D


You can subclass SKSpriteNode, add a reference to the image and check the alpha of that image, when detecting touches.

1) Add an instance variable to hold your image

@implementation DraggableSprite {
    UIImage *_holdingImage;
}

2) Then in init method you can save the reference to that image

-(id)initWithImageNamed:(NSString *)name {
    if (self=[super initWithImageNamed:name]) {

        self.userInteractionEnabled = YES;//enable touches handling
        self.anchorPoint = P(0,0);
        _holdingImage = [UIImage imageNamed:name];
    }
    return self;
}

3) Detect the touches

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    CGFloat a = [UIImage getAlphaFromImage:_holdingImage atX:positionInScene.x andY:self.size.height-positionInScene.y];
    NSLog(@"alpha is %f",a);
}

4) The alpha checking function

+(CGFloat)getAlphaFromImage:(UIImage*)image atX:(NSInteger)xx andY:(NSInteger)yy {
    // Cancel if point is outside image coordinates
    if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), CGPointMake(xx,yy))) {
        return 0;
    }

    // Create a 1x1 pixel byte array and bitmap context to draw the pixel into.
    // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage
    NSInteger pointX = xx;
    NSInteger pointY = yy;
    CGImageRef cgImage = image.CGImage;
    NSUInteger width = image.size.width;
    NSUInteger height = image.size.height;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    int bytesPerPixel = 4;
    int bytesPerRow = bytesPerPixel * 1;
    NSUInteger bitsPerComponent = 8;
    unsigned char pixelData[4] = { 0, 0, 0, 0 };
    CGContextRef context = CGBitmapContextCreate(pixelData,
                                                 1,
                                                 1,
                                                 bitsPerComponent,
                                                 bytesPerRow,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    CGContextSetBlendMode(context, kCGBlendModeCopy);

    // Draw the pixel we are interested in onto the bitmap context
    CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
    CGContextRelease(context);

    CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
    return alpha;
}
like image 32
roman777 Avatar answered Feb 02 '26 14:02

roman777



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!