ios iphone objective-c sprite-kit

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.