ios SKSpriteNode - 创建一个圆角节点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21695305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SKSpriteNode - create a round corner node?
提问by Haris Hussain
Is there a way to make a SKSpriteNode round cornered? I am trying to create a Tile likesqaure blocks with color filled SKSpriteNode:
有没有办法让 SKSpriteNode 圆角?我正在尝试创建一个带有颜色填充 SKSpriteNode 的 Tile likesqaure 块:
SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.0/255.0
green:128.0/255.0
blue:255.0/255.0
alpha:1.0] size:CGSizeMake(30, 30)];
How can I make it round cornered?
我怎样才能使它圆角?
Thanks!
谢谢!
回答by Dobro?udni Tapir
To get a rounded corner node you can use 2 approaches, each of them requires use of SKShapeNode.
要获得圆角节点,您可以使用 2 种方法,每种方法都需要使用 SKShapeNode。
First way is to use SKShapeNode and set its path to be a rounded rectangle like this:
第一种方法是使用 SKShapeNode 并将其路径设置为圆角矩形,如下所示:
SKShapeNode* tile = [SKShapeNode node];
[tile setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)];
tile.strokeColor = tile.fillColor = [UIColor colorWithRed:0.0/255.0
green:128.0/255.0
blue:255.0/255.0
alpha:1.0];
The other one uses sprite node,crop node and SKShapeNode with rounded rectangle as crop nodes mask:
另一个使用精灵节点、裁剪节点和带有圆角矩形的 SKShapeNode 作为裁剪节点掩码:
SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.0/255.0
green:128.0/255.0
blue:255.0/255.0
alpha:1.0] size:CGSizeMake(30, 30)];
SKCropNode* cropNode = [SKCropNode node];
SKShapeNode* mask = [SKShapeNode node];
[mask setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)];
[mask setFillColor:[SKColor whiteColor]];
[cropNode setMaskNode:mask];
[cropNode addChild:tile];
If your tiles are one solid colour, i suggest you go with the first approach.
如果您的瓷砖是一种纯色,我建议您使用第一种方法。
回答by Zoltan Vinkler
In Swift 3 you can create with:
在 Swift 3 中,您可以创建:
let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
回答by Krzysztof Gabis
Hope this helps:
希望这可以帮助:
SKSpriteNode *make_rounded_rectangle(UIColor *color, CGSize size, float radius)
{
UIGraphicsBeginImageContext(size);
[color setFill];
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
[path fill];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
SKTexture *texture = [SKTexture textureWithImage:image];
return [SKSpriteNode spriteNodeWithTexture:texture];
}
回答by Thomas Johannesmeyer
This is heavily inspired by the accepted answer, yet it uses a more readable way to create the SKShapeNode
and also fixes the annoying pixel line around the crop. Seems like a minor detail, but it may cost someone a few minutes.
这在很大程度上受到了公认答案的启发,但它使用了一种更具可读性的方式来创建SKShapeNode
并修复了作物周围恼人的像素线。似乎是一个小细节,但可能会花费某人几分钟。
CGFloat cornerRadius = 15;
SKCropNode *cropNode = [SKCropNode node];
SKShapeNode *maskNode = [SKShapeNode shapeNodeWithRectOfSize:scoreNode.size cornerRadius:cornerRadius];
[maskNode setLineWidth:0.0];
[maskNode setFillColor:[UIColor whiteColor]];
[cropNode setMaskNode:maskNode];
[cropNode addChild:scoreNode];
回答by Fattie
It's really this simple.......
真的是这么简单......
class YourSprite: SKSpriteNode {
func yourSetupFunction() {
texture = SKTexture( image: UIImage(named: "cat")!.circleMasked! )
There's nothing more to it.
没有更多了。
You really can not useSKShapeNode.
你真的不能使用SKShapeNode。
It's just that simple. It's an insane performance hit using SKShapeNode, it's not the right solution, it's pointlessly difficult, and the purpose of SKShapeNode just has no relation to this problem.
就是这么简单。使用 SKShapeNode 是一个疯狂的性能打击,它不是正确的解决方案,它毫无意义地困难,而 SKShapeNode 的目的与这个问题无关。
Look at all them kitties!
看看他们所有的小猫!
The code for circleMasked is this simple:
circleMasked 的代码很简单:
(All projects that deal with images will need this anyway.)
(无论如何,所有处理图像的项目都需要这个。)
extension UIImage {
var isPortrait: Bool { return size.height > size.width }
var isLandscape: Bool { return size.width > size.height }
var breadth: CGFloat { return min(size.width, size.height) }
var breadthSize: CGSize { return CGSize(width: breadth, height: breadth) }
var breadthRect: CGRect { return CGRect(origin: .zero, size: breadthSize) }
var circleMasked: UIImage? {
UIGraphicsBeginImageContextWithOptions(breadthSize, false, scale)
defer { UIGraphicsEndImageContext() }
guard let cgImage = cgImage?.cropping(to: CGRect(origin:
CGPoint(
x: isLandscape ? floor((size.width - size.height) / 2) : 0,
y: isPortrait ? floor((size.height - size.width) / 2) : 0),
size: breadthSize))
else { return nil }
UIBezierPath(ovalIn: breadthRect).addClip()
UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation)
.draw(in: breadthRect)
return UIGraphicsGetImageFromCurrentImageContext()
}
// classic 'circleMasked' stackoverflow fragment
// courtesy Leo Dabius /a/29047372/294884
}
That's all there is to it.
这里的所有都是它的。
回答by Alessandro Ornano
Swift 4:
斯威夫特 4:
A good solution could be created before you should add your sprite to his parent, I've maded a little extension that could be corrected as you wish:
在您将精灵添加到他的父级之前,可以创建一个很好的解决方案,我做了一些扩展,可以根据需要进行更正:
extension SKSpriteNode {
func addTo(parent:SKNode?, withRadius:CGFloat) {
guard parent != nil else { return }
guard withRadius>0.0 else {
parent!.addChild(self)
return
}
let radiusShape = SKShapeNode.init(rect: CGRect.init(origin: CGPoint.zero, size: size), cornerRadius: withRadius)
radiusShape.position = CGPoint.zero
radiusShape.lineWidth = 2.0
radiusShape.fillColor = UIColor.red
radiusShape.strokeColor = UIColor.red
radiusShape.zPosition = 2
radiusShape.position = CGPoint.zero
let cropNode = SKCropNode()
cropNode.position = self.position
cropNode.zPosition = 3
cropNode.addChild(self)
cropNode.maskNode = radiusShape
parent!.addChild(cropNode)
}
}
Usage:
用法:
let rootNode = SKSpriteNode(color: .white, size: self.size)
rootNode.alpha = 1.0
rootNode.anchorPoint = CGPoint.zero
rootNode.position = CGPoint.zero
rootNode.zPosition = 1
rootNode.name = "rootNode"
rootNode.addTo(parent: self, withRadius: 40.0)
回答by Thorsten
from the class reference:
从类参考:
"An SKSpriteNode is a node that draws a textured image, a colored square, or a textured image blended with a color."
“SKSpriteNode 是绘制纹理图像、彩色方块或与颜色混合的纹理图像的节点。”
It seems the easiest way is to draw a block with rounded corners and then use one of these class methods:
似乎最简单的方法是绘制一个带圆角的块,然后使用以下类方法之一:
- spriteNodeWithImageNamed:
- spriteNodeWithTexture:
- spriteNodeWithTexture:size:
- spriteNodeWithImageNamed:
- spriteNodeWithTexture:
- spriteNodeWithTexture:size:
回答by JP Aquino
Here's a Swift 3 snippet based on the second solution of the accepted answer.
这是基于已接受答案的第二个解决方案的 Swift 3 片段。
func createPlayerRoundedNode(){
let tile = SKSpriteNode(color: .white, size: CGSize(width: 30, height: 30))
tile.zPosition = 3
tile.name = "tile node"
let cropNode = SKCropNode()
cropNode.zPosition = 2
cropNode.name = "crop node"
let mask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
mask.fillColor = SKColor.darkGray
mask.zPosition = 2
mask.name = "mask node"
cropNode.maskNode = mask
self.addChild(cropNode)
cropNode.addChild(tile)
}