您可以使用 Sprite Kit 的 SKCropNode 实现“从头开始查看”。 SKCropNode 对其子节点应用掩码。掩码用于隐藏裁剪节点的部分或全部子节点。对于这个应用程序,子节点是您希望通过“刮擦”来发现的图像。
基本步骤
- 从空白图像开始作为蒙版的纹理
- 在蒙版中添加圆圈,用户触摸隐藏的图像以发现下面的图片
以下是如何做到这一点的示例:
首先,定义这些属性
@property UIImage *image;
@property SKSpriteNode *maskNode;
@property SKNode *node;
然后将场景的内容添加到 didMoveToView。
-(void)didMoveToView:(SKView *)view {
self.node = [SKNode node];
_node.name = @"tree";
// Create a node that will hold the image that's hidden and later uncovered by "scratching"
CGPoint position = CGPointMake (CGRectGetWidth(self.frame)/2,CGRectGetHeight(self.frame)/2);
SKSpriteNode *imageNode = [SKSpriteNode spriteNodeWithImageNamed:@"hidden_pic.png"];
imageNode.position = CGPointZero;
CGSize size = imageNode.size;
// This is the layer that you "scatch" off
SKSpriteNode *background = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:size];
background.position = position;
background.name = @"background";
[_node addChild:background];
// This is the mask node. Initialize it with an empty image, so it completely hides the image
UIImage *image = [self blankImageWithSize:size];
self.image = image;
SKTexture *texture = [SKTexture textureWithImage:image];
SKSpriteNode *maskNode = [SKSpriteNode spriteNodeWithTexture:texture];
maskNode.position = CGPointZero;
maskNode.name = @"mask";
self.maskNode = maskNode;
[_node addChild:maskNode];
// This is the node that crops its children
SKCropNode *cropNode = [SKCropNode node];
cropNode.position = position;
cropNode.maskNode = maskNode;
cropNode.zPosition = 100;
cropNode.name = @"crop";
[_node addChild:cropNode];
[cropNode addChild:imageNode];
[self addChild:_node];
}
这会创建一个空图像。用于作为初始蒙版图片,使图片完全隐藏。
- (UIImage*) blankImageWithSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
此方法在图像上的指定点绘制一个圆。它用于更新掩码节点的图像。面具上绘制的每个圆圈都会揭示更多隐藏的图片。
#define kCircleRadius 22
- (UIImage *)imageByDrawingCircleOnImage:(UIImage *)image atPoint:(CGPoint)point
{
UIGraphicsBeginImageContext(image.size);
[image drawAtPoint:CGPointZero];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -image.size.height);
CGRect rect = CGRectMake(point.x-kCircleRadius, point.y-kCircleRadius,
kCircleRadius*2, kCircleRadius*2);
UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithOvalInRect:rect];
[[UIColor blackColor] setFill];
[roundedRectanglePath fill];
CGContextAddPath(context, roundedRectanglePath.CGPath);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
该方法将指定点转换为掩码节点的坐标,调用
一种在遮罩节点中绘制圆的方法,并更新遮罩节点的
纹理。
- (void) drawCircleInImageAtPoint:(CGPoint)point
{
CGPoint location = [self convertPoint:point toNode:_maskNode];
location = CGPointMake(location.x+_maskNode.size.width/2, location.y+_maskNode.size.height/2);
UIImage *newImage = [self imageByDrawingCircleOnImage:_image atPoint:location];
SKTexture *texture = [SKTexture textureWithImage:newImage];
self.image = newImage;
_maskNode.texture = texture;
}
这些方法处理触摸事件。它将 cicles 添加到用户触摸屏幕的遮罩节点图像中。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
NSArray *nodes = [self nodesAtPoint:location];
for (SKNode *node in nodes) {
if ([node.name isEqualToString:@"crop"]) {
[self drawCircleInImageAtPoint:location];
}
}
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
NSArray *nodes = [self nodesAtPoint:location];
for (SKNode *node in nodes) {
if ([node.name isEqualToString:@"crop"]) {
[self drawCircleInImageAtPoint:location];
}
}
}
}