SKSpriteNodeの角を丸くする方法はありますか?私は色で塗りつぶされたSKSpriteNodeでタイル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)];
角を丸くするにはどうすればよいですか?
ありがとう!
角の丸いノードを取得するには、2つのアプローチを使用できます。それぞれのアプローチでSKShapeNodeを使用する必要があります。
最初の方法は、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];
もう1つは、スプライトノード、クロップノード、およびクロップノードマスクとして角丸長方形の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];
タイルが単色の場合は、最初のアプローチをお勧めします。
Swift 3では、次を使用して作成できます。
let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
お役に立てれば:
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];
}
class YourSprite: SKSpriteNode {
func yourSetupFunction() {
texture = SKTexture( image: UIImage(named: "cat")!.circleMasked! )
それ以上のものはありません。
とても簡単です。 SKShapeNodeを使用すると非常にパフォーマンスが低下しますが、これは適切な解決策ではなく、無意味に難しく、SKShapeNodeの目的はこの問題とは関係ありません。
それらすべての子猫を見てください!
CircleMaskedのコードは次のとおりです。
(画像を扱うすべてのプロジェクトは、とにかくこれを必要とします。)
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
}
これですべてです。
これは受け入れられた答えに大きく触発されていますが、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];
あなたのスプライトを彼の親に追加する前に良い解決策を作成することができました。私はあなたが望むように修正できる小さな拡張を作成しました:
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)
}
}
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)
クラス参照から:
「SKSpriteNodeは、テクスチャ画像、色付きの正方形、または色とブレンドされたテクスチャ画像を描画するノードです。」
最も簡単な方法は、角の丸いブロックを描画してから、次のクラスメソッドのいずれかを使用することです。
受け入れられた答えの2番目のソリューションに基づく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)
}