objective-c - 在 SpriteKit 中,SKCropNode 对 SKShapeNode 没有影响

标签 objective-c sprite-kit

我一直在尝试使用 SKCropNode 将 mask 应用于 SKShapeNode,但到目前为止没有成功。认为这是一个 SpriteKit 错误 - 这是代码片段:

SKNode* contentNode = [SKNode node];

// picture - use an image bigger than 50x50
SKSpriteNode *pictureNode = [SKSpriteNode spriteNodeWithImageNamed:@"tree"];

// triangle
SKShapeNode* triangleNode = [SKShapeNode node];
UIBezierPath* triangleNodeBezierPath = [[UIBezierPath alloc] init];
[triangleNodeBezierPath moveToPoint:CGPointMake(0.0, 0.0)];
[triangleNodeBezierPath addLineToPoint:CGPointMake(0.0, 100.0)];
[triangleNodeBezierPath addLineToPoint:CGPointMake(50.0, 100.0)];
[triangleNodeBezierPath closePath];

triangleNode.path = triangleNodeBezierPath.CGPath;
triangleNode.fillColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1];

// create a mask
SKSpriteNode *mask = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size: CGSizeMake(50, 50)]; //50 by 50 is the size of the mask

// create a SKCropNode
SKCropNode *cropNode = [SKCropNode node];

[cropNode addChild: contentNode];
[cropNode setMaskNode: mask];

[self addChild: cropNode];
[contentNode addChild:pictureNode]; // pictureNode is being cropped
[contentNode addChild:triangleNode]; // triangleNode is not

cropNode.position = CGPointMake( CGRectGetMidX (self.frame), CGRectGetMidY (self.frame));

有人能解决这个问题吗?非常感谢!

最佳答案

这件事困扰了我一天的大部分时间。我曾计划创建一个类似于出色的 TCProgressTimer by Tony Chamblee 的计时器.但是,由于我的应用程序使用多个进度计时器,所以我不想设计许多不同大小的 Sprite 以用于不同的分辨率。

我的解决方案是将 SKShapeNode 对象转换为 SKSpriteNode 对象。我最终不得不回到基础并使用 Core Graphics 来完成繁重的工作。这是一种相当困惑的做事方式,我敢肯定,但我想要快速的结果来动态创建类似于使用 SKShapeNode 时获得的结果的对象。

我目前只对制作圆形物体感兴趣,所以我是这样做的:

-(SKSpriteNode *)createSpriteMatchingSKShapeNodeWithRadius:(float)radius color:(SKColor *)color {
    CALayer *drawingLayer = [CALayer layer];
    CALayer *circleLayer = [CALayer layer];
    circleLayer.frame = CGRectMake(0,0,radius*2.0f,radius*2.0f);
    circleLayer.backgroundColor = color.CGColor;
    circleLayer.cornerRadius = circleLayer.frame.size.width/2.0;
    circleLayer.masksToBounds = YES;


    [drawingLayer addSublayer:circleLayer];

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(circleLayer.frame.size.width, circleLayer.frame.size.height), NO, [UIScreen mainScreen].scale);
    CGContextSetAllowsAntialiasing(UIGraphicsGetCurrentContext(), TRUE);
    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [UIColor clearColor].CGColor);
    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0,0,circleLayer.frame.size.width,circleLayer.frame.size.height));
    [drawingLayer renderInContext: UIGraphicsGetCurrentContext()];

    UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImage:layerImage]];


    return sprite;
}

生成的 Sprite 现在可以按预期被 SKCropNode 遮盖。由于这些 Sprite 都是在场景开始之前生成的,所以我没有注意到性能受到影响。但是,我认为如果您动态生成多个节点,这种方法效率会非常低。

我很想听听其他用户的解决方案。希望对您有所帮助。

-直流

关于objective-c - 在 SpriteKit 中,SKCropNode 对 SKShapeNode 没有影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21816079/

相关文章:

objective-c - 如何强制 iPad 启动 wifi 连接?

ios - 将 UIButton 添加到 SKScene

ios - didBegin 函数在 IOS 11.3 上不能正常工作

xcode - ConvertPointToView 函数在 Swift Xcode 7 Beta 中不起作用

Objective-C 便捷礼仪

ios - 在 Swift iOS 中将 NSString * 转换为 String 并将 Character 作为参数传递的问题

objective-c - 修改复制的 NSMutableDictionary 也会修改原始的

iphone - 如何圆化 UIImage 的边缘?

swift - 在 swift spritekit 中更改定时器的时间间隔

ios - 应用脉冲不能正常工作