ios - SKSpriteNode: ¿crear un nodo de esquina circular?
iphone objective-c (7)
de la referencia de clase:
"Un SKSpriteNode es un nodo que dibuja una imagen texturizada, un cuadrado de color o una imagen texturizada mezclada con un color".
Parece que la forma más fácil es dibujar un bloque con esquinas redondeadas y luego usar uno de estos métodos de clase:
- spriteNodeWithImageNamed:
- spriteNodeWithTexture:
- spriteNodeWithTexture: tamaño:
¿Hay alguna manera de hacer una ronda SKSpriteNode acorralada? Estoy tratando de crear un bloque de Me gustaqaure con SKSpriteNode lleno de color:
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)];
¿Cómo puedo hacer que sea acorralado?
¡Gracias!
Para obtener un nodo de esquina redondeada puede usar 2 enfoques, cada uno de ellos requiere el uso de SKShapeNode.
La primera forma es usar SKShapeNode y establecer su ruta para que sea un rectángulo redondeado como este:
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];
El otro usa nodo de sprite, nodo de recorte y SKShapeNode con rectángulo redondeado como máscara de nodos de recorte:
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 sus fichas son de un solo color, le sugiero que vaya con el primer acercamiento.
Espero que esto ayude:
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];
}
Esto está fuertemente inspirado por la respuesta aceptada, pero usa una forma más legible de crear SKShapeNode
y también corrige la molesta línea de píxeles alrededor del recorte. Parece un detalle menor, pero puede costarle a alguien unos minutos.
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];
En Swift 3 puedes crear con:
let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
Aquí hay un fragmento de Swift 3 basado en la segunda solución de la respuesta aceptada.
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)
}
Es realmente así de simple .......
class YourSprite: SKSpriteNode {
func yourSetupFunction() {
texture = SKTexture( image: UIImage(named: "cat")!.circleMasked! )
No hay nada más para eso.
Realmente no puedes usar SKShapeNode.
Es así de simple. Es un golpe de rendimiento loco con SKShapeNode, no es la solución correcta, es inútil y el propósito de SKShapeNode no tiene relación con este problema.
Mire todos los gatitos!
El código para circleMasked es así de simple:
(Todos los proyectos que se ocupan de imágenes necesitarán esto de todos modos).
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'' fragment
// courtesy Leo Dabius /a/29047372/294884
}
Eso es todo al respecto.