SpriteKit: How to draw custom shapes without SKShapeNode? - ios

From Apples class reference for SKShapeNode's but also from many developers i hear that using SKShapeNode for drawing custom shapes you want to draw often on the view is a bad idea because it performs bad.
Its true, a simple app with some custom shapes is spiking my CPU up to 80% and using like 80MB RAM (on devices its a bit better).
So then, how do i draw shapes like arrows without using SKShapeNode, because i like the idea to draw with bezierpaths since i do not need to care about display size.
How to draw an arrow with a texture without getting a bad quality, since it would stretch my image when i move my touch stretching the arrow. Doing this with SKShapeNode works perfect but performs bad.

You can always have one SKShapeNode node available that you use for creating shapes, and use the path property to design the shape. Then create a texture out of the SKShapeNode from the scenes view with let texture = scene.view.textureFromNode(shapeNode) and place the new texture into an SKSpriteNode

Related

Drawing on a plane in SceneKit

I created a SCNPlane in my scene. I set the diffuse content of the SCNPlane to an image. Now I need to display other details on the plane (e.g. the name of the plane, and other simple drawings like an arrow).
This seems like a simple task but I could not find any relevant information. Should I create other geometries and attach them to the plane? If so, how do I do that without z-fighting occurring?
Materials in SceneKit are very flexible. When you are assigning something to the diffuse or ambient property you are assigning a SCNMaterialProperty. From Apples docs you can assign:
An image object, or a path or URL to an image file
A specially formatted image or array of six images to be used as a cube map
A Core Animation layer or layer hierarchy, which itself may contain animated content
A SpriteKit texture providing a static image, or an entire SpriteKit scene rendering animated 2D content.
I haven't got the Core Animations layers to work properly, maybe someone else can give more information on it, but I have been using SpriteKit and it is really easy to set up.
Create a SKScene and add animate it as much as you want
Set the size of your scene. SceneKit will scale this up if your plane is bigger than your size.
Add it to your materials diffuse property

iOS - Adding a 2D image to a scenekit game

Hello i can't for the life of me work out how to add a 2D image in the scene using scenekit is it even possible? What I'm trying to accomplish is have a 3D flying plane over a 2D background image but the background image can't cover the whole screen. Thanks to anyone that can help
Others have said plenty good suggestions above.
Let me summarize each solution with different scenarios:
Using scnScene.background: Easiest, but fullscreen and static. You cannot display in a smaller area of the scene, nor can you customize the transformations.
Using scnScene.overlaySKScene to display a 2D SKScene and adding image sprite. This is probably what fits your scenario. If you want static but with configurable transformations, this is a good choice. Notably overlaySKScene is recommended by Apple to create HUD in your 3D scene.
However, if you want the 2D content to track the 3D movement, you need to do some coordinate conversion from 3D space to 2D space every frame. Bad news is the job is done by CPU, which will add performance drag. (Believe me, this frustrate me too!)
Using SCNNode with SCNPlane geometry and set the diffuse.content with the image; add SCNBillBoardConstraint to the node to ensure it's always facing the camera.
Most flexible. However if your camera is not orthographic, the picture is going to zoom as the fov of camera changes, which doesn't look 2D but rather a hanging 3D billboard.
SceneKit and SpriteKit play very nicely together.
Implement the background 2D image as a SceneKit node with SCNPlane geometry, using your image as the plane's material. If you want to get fancier, use a full, live SpriteKit scene as the SCNPlane's material. Place that node at the far end of your camera's frustum, with your 3D aircraft in front of it.
You might also consider providing a cube map (skybox) as your scene's background. See SCNScene.background.
You can use the background property on SCNScene to set a background image.
scnScene.background.contents = UIImage(named: "myImage")
Contents
You can set a value for this property using any of the following
types:
A color (NSColor/UIColor or CGColorRef), specifying a constant color
across the material’s surface
An image (NSImage/UIImage or CGImageRef), specifying a texture to be
mapped across the material’s surface
An NSString or NSURL object specifying the location of an image file
An array of six images (NSArray), specifying the faces of a cube map
A Core Animation layer (CALayer)
A texture (SKTexture, MDLTexture, MTLTexture, or GLKTextureInfo)
A Sprite Kit scene (SKScene)

SKSpriteNode - How do I write to the pixels that make up the image of a sprite?

I would like to be able to write pixels to the image of an SKSprite in iOS7. How do I do this?
Applications? Graphing for example. Random images. Applying damage effects perhaps to a sprite.
You can't directly write to an SKSpriteNode's pixel data in iOS 7. (This is called out explicitly in Apple's WWDC 2013 videos about sprite kit, which I highly recommend.) The only thing you can do is to change its texture member. The Apple docs on sprites give a variety of techniques to do that.
If you really need to programmatically create an image, you can always do so with a pixel buffer and then make it into an SKTexture with textureWithData:size: and related methods. For explosions and damage effects, though, there are probably better ways to do this, such as particle systems or masking out or combining the underlying sprite with other sprites.
How to draw a line in Sprite-kit
I didn't know you could draw lines and such directly onto nodes or scenes. This works for my purposes.

Is there are way to draw a pixel in SpriteKit?

I am trying to put together ray tracing routine and the width/shade of every pixel in a single ray will change over the length of the line. Is there a way in SpriteKit to draw a single pixel on the screen? or should I be doing this using UIImage?
SpriteKit isn't a pixel drawing API. It's more of a "moving pictures around on the screen" API. There are a couple of cases, though, where it makes sense to do custom drawing, and SpriteKit (as of iOS 8 and OS X 10.10) has a few facilities for this.
If you want to create custom art to apply to sprites, with that art being mostly static (that is, not needing to be redrawn frequently as SpriteKit animates the scene), just use the drawing API of your choice — Core Graphics, OpenGL, emacs, whatever — to create an image. Then you can stick that image in an SKTexture object to apply to sprites in your scene.
To directly munge the bits inside a texture, use SKMutableTexture. This doesn't really provide drawing facilities — you just get to work with the raw image data. (And while you could layer drawing tools on top of that — for example, by creating a CG image context from the data and rewriting the data with CG results — that'd slow you down too much to keep up with the animation framerate.)
If you need high-framerate, per-pixel drawing, your best bet is to do that entirely on the GPU. Use SKShader for that.
If your application is redrawing every frame, then you can use an offscreen buffer to dynamically update pixels, aka SKMutableTexture. I'm not sure how slow it will be.

Which is the fastest way to add a rectangle on the front window

We can draw rectangle on the UIImage. And we can also add a sub-view with a backgroundcolor or border. I guess there is other methods to make it, too.
Did someone try to analyze them?
Which is the fastest way?
Thanks!
I would say, drawing rectangles using Quartz engine and UIImage is more CPU intensive that using UIView. If your scene is heavy and dynamic, Quartz is the best way of doing drawings because you can update your drawings.
Using UIView is not CPU intensive, but it'll have a heavy memory foot print if you want to draw a lot of rectangles.
So, if you want to draw just one or two rectangle for GUI design, I'd say go for using UIViews. But If you are trying to do some complex drawings involving more shapes go for Quartz.

Resources