OK. here's how I made this.
first of all. load atlas as UIImage. then alloc SPTexture and init it with contents of loaded UIimage. then create usual SPTextureAtlas from this SPTexture . (only xml will be loaded here)
next. use each texture from that atlas as SPSubTexture (not just SPTexture)
you can cast like this:
SPSubTexture *fullTexture = (SPSubTexture*)[gameAtlas textureByName:pieceName];
then. For touch object I use extended SPSprite with it's own hitTestPoint.
this object knows about full UIimage and current SPSubTexture
in -(SPDisplayObject*)hitTestPoint:(SPPoint*)touchPoint
first of all we need to know if touch is even in texture bounds:
SPRectangle *frame = self.subTexture.frame;
//// need to know where texture starts on it's own canvas
if((touchPoint.x < ABS(frame.x)) ||
(touchPoint.x > ABS(frame.x) + self.subTexture.width) ||
(touchPoint.y < ABS(frame.y)) ||
(touchPoint.y > ABS(frame.y) + self.subTexture.height)) {
return nil;
}
after that. we will find where user touched the atlas (and not just a frame of texture)
SPRectangle *clipping = self.subTexture.clipping;
float x = clipping.x * self.uiimage.size.width;
float y = clipping.y * self.uiimage.size.height;
PointS localPoint = (PointS){touchPoint.x + frame.x, touchPoint.y + frame.y};
SPPoint *atlasPoint = [SPPoint pointWithX:x + localPoint.x
y:y + localPoint.y
];
almost there
the only thing left is to determinate color of touched pixel.
I had lots of nslogs with different methods found in the net. Surprisingly only one was working correctly with my atlas:
http://stackoverflow.com/a/12032147/2611255
with this method alpha is always 1.0f. but you can stick the color components instead.
something like this:
UIColor *colorAtPoint = [self colorFromImage:self.uiimage sampledAtPoint:CGPointMake(atlasPoint.x/self.uiimage.size.width, atlasPoint.y/self.uiimage.size.height)];
CGColorRef colorRef = [colorAtPoint CGColor];
int _countComponents = CGColorGetNumberOfComponents(colorRef);
if (_countComponents == 4) {
const CGFloat *_components = CGColorGetComponents(colorRef);
CGFloat red = _components[0];
CGFloat green = _components[1];
CGFloat blue = _components[2];
CGFloat alpha = _components[3];
//NSLog(@"%f,%f,%f,%f",red,green,blue,alpha);
if(red+green+blue > 0) return self;
}
Guys. please tell me if this solution is bad somehow. not rational. uses excess memory and etc.
for now I'm glad at least it works but I also don't see increasing bytes after SPTextureAtlas is created