2014-02-16 3 views
8

SKCropNode를 사용하여 SKShapeNode에 마스크를 적용하려고했지만 지금까지 성공하지 못했습니다. SpriteKit 버그라고 생각합니다. 코드 예는 다음과 같습니다.SpriteKit에서 SKCropNode는 SKShapeNode에 아무런 영향을주지 않습니다.

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)); 

누구에게이 문제에 대한 해결책이 있습니까? 고마워요!

답변

8

이것은 하루 종일 나를 괴롭 히고있었습니다. 나는 훌륭한 타이머 인 TCProgressTimer by Tony Chamblee을 만들 계획이었습니다. 그러나 내 응용 프로그램은 여러 진행 타이머를 사용하므로 다른 해상도로 사용할 수 있도록 여러 가지 다른 크기의 스프라이트를 디자인하지 않아도됩니다.

내 해결책은 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; 
} 

결과 스프라이트는 이제 SKCropNode에 의해 마스크 될 수있다. 장면이 시작되기 전에 이러한 스프라이트가 모두 생성되므로 성능에 문제가 있음을 알 수 없습니다. 그러나, 당신이 즉시 여러 노드를 생성하는 경우이 방법은 매우 비효율적이라고 생각합니다.

다른 사용자들의 의견을 듣고 싶습니다. 희망이 도움이됩니다.

-DC

+3

한숨, 나는 또한이 문제에 부딪쳤다. 나는 이것에 레이더를 제출했다. SKShapeNode를 SKCropNode와 함께 사용할 수 없다는 것은 꽤 불행한 일입니다. 다행히도 제 경우에는 사각형이 필요했기 때문에 SKSpriteNode를 사용할 수있었습니다. –

+0

@MobileBen SKShapeNode와 CAShapeLayer 모두에서 선 편집과 같이 CGPath가 해당 속성을 편집 할 수 없다는 점은 선 편집과 같이 필자가 본 2D 드로잉 및 애니메이션 기술에서 가장 놀라운 부분 중 하나입니다. 그리고 그 수준을 놓치지 않는 수준은 SpriteKit의 2D 상호 작용, 렌더링, 조작 및 사용법에 대한 설계 방식의 많은 부분을 보완합니다. 내 요리를 떠올리게한다. Bubble-n-Squeak의 반죽, 반 굽고 종이 접시에 담아 낸다. 최고의 spork와 함께 먹었어요. – Confused

+0

@Confused Apple은 대중이 제품을 생산할 수있는 일반적인 제품을 만듭니다. 불행히도 게임에서는 종종 특수한 경우가 있습니다. SK에 근무하는 팀은 게임을 제작하는 데이 게임을 사용하지 않고 데모만을 사용합니다. 그래서 그들은이 모든 항목들이 현장에서 어떻게 사용되는지 이해하지 못합니다. 그들은 단지 기능의 체크리스트를 가지고있는 것처럼 보입니다. 왜 내가 SK를 버렸을 까? SK 실적은 실제로 좋지 않습니다. 나는 또한 게임이 점점 커지면 규모가 커지지 않을 것이라고 생각합니다. 이제는 최신 엔진을 설치하고 실행 했으므로 게임 속도가 빨라졌으며 dev가 더 쉽습니다. –

2

제목이 정확합니다. 또한 CropNode의 계층 구조에서 ShapeNode를 사용하면 그 위에있는 어린이에게도 영향을주는 것으로 나타났습니다. 나는 빠른 실험을 만들었다. 새로운 게임 프로젝트를 만들고 직접 시도 할 수 있습니다. addChild : shapeContent 행 중 하나를 주석 처리하여 이것이 우주선 이미지의 자르기에 어떻게 영향을 주는지 볼 수 있습니다.

DoctorClod가 지적한 것처럼 현재 솔루션은 cropNode의 모든 하위 항목이 SpriteNodes인지 확인하는 것으로 보입니다.

-(void)didMoveToView:(SKView *)view { 

SKSpriteNode* colorBackground = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(800, 600)]; 

SKSpriteNode *spaceshipImage = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"]; 

SKShapeNode* shapeContent = [SKShapeNode shapeNodeWithRect:CGRectMake(0, 0, 200, 100)]; 
shapeContent.fillColor = [SKColor greenColor]; 

SKSpriteNode *maskShape = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(500, 100)]; 

SKCropNode *cropNode = [SKCropNode new]; 

[cropNode addChild:colorBackground]; 
[cropNode addChild:shapeContent];  // comment this one out 
[cropNode addChild:spaceshipImage]; 
[cropNode addChild:shapeContent];  // or comment this one out 

[cropNode setMaskNode:maskShape]; 

cropNode.position = CGPointMake(CGRectGetMidX (self.frame), CGRectGetMidY(self.frame)); 
[self addChild:cropNode]; 
} 
4

내 응용 프로그램에서 비슷한 작업이 있습니다. 사용자 입력을 기반으로 여러 불규칙한 도형을 그려서 자르기 노드의 마스크로 사용해야합니다.

나를 위해 작동이 솔루션은하는 것입니다

  1. 가에서 SKSpriteNode을 만들

  2. SKView 방법 textureFromNode:crop:

  3. 를 사용에서 SKTexture를 검색에 필요한 경로로 SKShapeNode를 만들 그 질감.

  4. 마스크로 SKSprite 노드를 사용하십시오.

+0

이것은 SKView가 무엇인지 명확하게하는 모범 사례입니다. textureFromNode : crop :은을위한 것입니다. ;-) – Juguang

+1

'textureFromNode : crop :'에 문제가 있습니다 : 제가 통과 한 rect가 의미있는 것이기는하지만'nil'을 리턴합니다. 사용할 수있는 크기 속성이 없도록 SKShapeNode에서 작업하고 있습니다. 나는 자르기 직사각형에 대해 미리 정해진 크기를 전달 중입니다. 반면에,'textureFromNode :'는 잘 동작 합니다만 (텍스처가 중심을 벗어납니다). –

관련 문제