tutorial spritekit game cross objective-c macos cocoa sprite-kit skview

objective-c - game - spritekit tutorial



Render/Snapshot SpriteKit Scene a NSImage (4)

Aquí estaba mi intento (en OSX) de obtener la imagen renderizada subyacente ...

Primero, SKView y en su método drawRect agarré NSBitmapImageRep un NSBitmapImageRep

if (![self cache]) [self setCache:[self bitmapImageRepForCachingDisplayInRect:[self visibleRect]]];

Luego configuré un NSTimer que periódicamente intentaba copiar el contenido de ese caché a una vista en miniatura personalizada:

MySKView *sv = ..... NSBitmapImageRep *cache = [sv cache]; if (!cache) return; NSRect srcFrame = NSMakeRect(0,0,[sv frame].size.width,[sv frame].size.height); NSRect thumbFrame = [[self thumbView] frame]; NSRect thumbRect = NSMakeRect(0,0,thumbFrame.size.width,thumbFrame.size.height); [sv cacheDisplayInRect:srcFrame toBitmapImageRep:cache]; [[self thumbView] lockFocus]; [cache drawInRect:thumbRect fromRect:srcFrame operation:NSCompositeCopy fraction:1.0 respectFlipped:YES hints:nil]; [[self thumbView] unlockFocus];

No dados. Todo lo que obtengo en mi vista de ThumbNail es negro.

Probablemente por la misma razón que esto es todo el dibujo basado en OpenGL / GPU.

Eso me llevaría en la dirección de encontrar de alguna manera el contexto subyacente de dibujo OpenGL utilizado por SKView y haciendo un glReadPixels en ese contexto.

¿Alguien sabe cómo hacer una "instantánea" de un SKView o SKScene en un NSImage ?

Hemos podido usar la API textureFromNode para crear una SKTexture desde un nodo y todos sus elementos SKTexture . Pero hasta ahora no podemos encontrar una manera de extraer los datos de la imagen en, por ejemplo, un NSImage . Estamos construyendo una aplicación mixta Cocoa / SpriteKit donde necesitamos extraer pequeñas miniaturas de escenas.

Nuevamente, esto parece posible en iOS (para obtener un UIImage ) usando drawViewHierarchyInRect :

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale); [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

¿Pero cómo hacer esto en Cocoa con NSImage ? Ayuda.


Todavía no hay acceso directo a los datos de imagen de una SKTexture. Puede presentar el nodo en una escena fuera de pantalla y capturar la jerarquía de vista. Uso este código en iOS como referencia:

class func imageFromNode(node : SKNode, inScene scene: SKScene) -> UIImage? { if let texture = scene.view?.textureFromNode(node) { let view = SKView(frame: CGRect(origin: CGPointZero, size: texture.size())) view.allowsTransparency = true view.backgroundColor = SKColor.clearColor() let scene = SKScene(size: view.bounds.size) scene.view?.allowsTransparency = true scene.backgroundColor = SKColor.clearColor() let sprite = SKSpriteNode(texture: texture) sprite.position = CGPoint(x: CGRectGetMidX(view.frame), y: CGRectGetMidY(view.frame)) scene.addChild(sprite) view.presentScene(scene) UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0) view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } return nil }


SKView es una subclase de UIView , por lo que debería poder dibujar la capa de la vista en un contexto CoreGraphics y luego obtener la imagen del contexto.

Mira usando view.layer.drawInContext .


A partir de OS X 10.11 (y iOS 9 y TVOS, pero los ignoraremos ya que está preguntando acerca de NSImage ), SKTexture puede exportar su contenido a CGImageRef . Entonces, el enfoque de textureFromNode que mencionas ahora es el primer paso en una solución de trabajo:

SKTexture *texture = [view textureFromNode: view.scene]; NSImage *image = [[NSImage alloc] initWithCGImage: texture.CGImage size: view.bounds];

Tenga en cuenta el parámetro de size para initWithCGImage: puede pasar CGSizeZero allí para hacer que el NSImage herede el tamaño de píxel de CGImage , pero dado que puede tratar con Retina Display, probablemente desee el tamaño de punto , que puede obtener de las dimensiones de la vista.