Fill SKShapeNode with pattern image

2019-05-10 16:48发布

问题:

I'm trying to fill a SKShapeNode with an Image/pattern but I'm still unsuccessfull.

Can you help me solving this or giving me an alternative? I want to create a collidable custom shape (from any SpriteKit kind) filled with a pattern image.

I've tried the following:

UIBezierPath *path = [[UIBezierPath alloc] init];
    [path addArcWithCenter:CGPointMake(0.0, 0.0) radius:50.0 startAngle:0.0 endAngle:(M_PI*2.0) clockwise:YES];
SKShapeNode *shape = [[SKShapeNode alloc] init];
UIImage *patternImg = [UIImage imageNamed:@"pattern"];
shape.path = path.CGPath;
shape.fillColor = [[SKColor alloc] initWithCGColor:[[UIColor alloc] initWithPatternImage:patternImg].CGColor];

and also:

shape.fillColor = [[SKColor alloc] initWithPatternImage:[[UIImage alloc] initWithCGImage:[UIImage imageNamed:@"Basketball"].CGImage]];

This works (but it isn't what I'm looking for):

shape.fillColor =  [SKColor redColor];

Thank you!

回答1:

i had the sample problem in my game, finally my solution was to add a SKSpriteNode as a child of the SKShapeNode and it worked fine.

SKSpriteNode* node = [[SKSpriteNode alloc] initWithImageNamed:@"bombIcon.png"];
node.name = @"bomb";
node.size = CGSizeMake(10, 10);
[self.bombNode addChild:node];

Where self.bombNode is a SKShapeNode.

Hope it helps



回答2:

Starting from iOS 8.0 there is fillTexture property in the SKShapeNode.



回答3:

You could try to achieve that with SKCropNode. However, I've seen several questions here that SKShapeNode cannot act as maskNode for SKCropNode, but I haven't tested it myself. In this case you probably have to use SKSpriteNode instead of SKShapeNode.



回答4:

Well, using modern Swift (you're using Swift by now, right?), you could try:

var marbleNode: SKSpriteNode!

Then later, in your init method:

marbleNode = SKSpriteNode(imageNamed: "SmallerSwirl");

marbleNode.physicsBody = SKPhysicsBody(circleOfRadius: 35.0)

marbleNode.physicsBody?.dynamic = true
marbleNode.physicsBody?.affectedByGravity = true
print(marbleNode.physicsBody)

marbleNode.position = CGPointMake(centerPoint.position.x + 10.0,   centerPoint.position.y + 10.0)

self.addChild(marbleNode)

Okay, so that gives us a round sprite node to work with. The Sprite node is responsive to physics, because you set up its physics body separately. So far, so good. Now we need to address the glossed-over part, namely the introduction of the SmallerSwirl .png image.

When you set up your project, it included an Assets.xcassets (pronounced, "x c assets") entry. Click on it, then click on the "+" sign at the middle/bottom of the first column, by the word filter. From the menu that appears, select "New Image Set". A new entry labeled "Image" appears. Click on the word "Image" to change it to "SmallerSwirl".

Next to the SmallerSwirl entry, you see blanks labeled 1x, 2x, and 3x. They are for different screen resolutions. Start by dragging your preferred .png image into the 1x square. That image can be named whatever you want it to be named. It doesn't have to be named SmallerSwirl, though it can be. Drag other images to the 2x and 3x slots if you like.

Run, and you should see your preferred image embodied as a sprite, dancing around the screen.