Existe-t-il un moyen de créer un SKSpriteNode rond? J'essaie de créer un bloc de tuiles likesqaure avec des couleurs remplies SKSpriteNode:
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)];
Comment puis-je le faire arrondi?
Merci!
Pour obtenir un nœud de coin arrondi, vous pouvez utiliser deux approches. Chacune d’elles nécessite l’utilisation de SKShapeNode.
La première méthode consiste à utiliser SKShapeNode et à définir son chemin comme un rectangle arrondi, comme ceci:
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];
L'autre utilise le nœud Sprite, le nœud de recadrage et SKShapeNode avec un rectangle arrondi comme masque de nœuds de recadrage:
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];
Si vos carreaux sont d'une couleur unie, je vous suggère de choisir la première approche.
Dans Swift 3, vous pouvez créer avec:
let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
J'espère que cela t'aides:
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! )
Il n'y a rien de plus.
C'est aussi simple que cela. Utiliser SKShapeNode est un succès fou, ce n’est pas la bonne solution, c’est inutilement difficile, et le but de SKShapeNode n’a aucun rapport avec ce problème.
Regarde tous les minous!
Le code pour circleMasked est simple:
(De toute façon, tous les projets traitant d’images en auront besoin.)
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
}
C'est tout ce qu'on peut en dire.
Ceci est fortement inspiré de la réponse acceptée, mais il utilise un moyen plus lisible de créer la variable SKShapeNode
et corrige également la ligne de pixel gênante autour du rognage. Cela semble être un détail mineur, mais cela peut coûter quelques minutes à quelqu'un.
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];
Une bonne solution pourrait être créée avant que vous ne deviez ajouter votre Sprite à son parent. Je vous ai présenté une petite extension qui pourrait être corrigée à votre guise:
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)
Voici un extrait de Swift 3 basé sur la deuxième solution de la réponse acceptée.
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)
}
de la référence de classe:
"Un SKSpriteNode est un nœud qui dessine une image texturée, un carré coloré ou une image texturée mélangée à une couleur."
Il semble que le moyen le plus simple consiste à dessiner un bloc avec des angles arrondis, puis à utiliser l'une des méthodes de classe suivantes: