Search code examples
xcodesprite-kitroundingskscene

Issue with non-integer node positions after loading scene from a file in Xcode


I have had a strange issue which I thought I would share. Although work-arounds are fairly simple, they are a bit tedious, and I was wondering whether there was a better way.

I designed a SpriteKit scene using the scene editor, loaded the scene and performed some custom logic in custom class initialisers. This involved creating some new nodes and comparing node positions and adding some integer offsets to the node positions.

Strangely, I found that although the node positions were specified throughout as integers in the scene editor, they came out as non-integer (as shown in the debugger).

Specifically, I had a node with the x value:

96.000122

This appears to be some binary fraction, so obviously a low bit is set somewhere. I say again, in the scene editor it appears as "96".

The trouble with this as I see it is two fold:

  1. Comparisons can fail.
  2. It is possible SpriteKit has to do unnecessary anti-aliasing of the image (if it is already pixel aligned).

Are there elegant solutions to round all the positions off in the scene file, or is it something that has to be done manually?


Solution

  • In the end, as suggested, I wrote an extension to round all of the positions:

    extension SKNode {
        func fixUp() {
            for child in children {
                child.position = CGPoint(
                                     x: round(child.position.x * 4) / 4,
                                     y: round(child.position.y * 4) / 4)
                child.fixUp()
            }
        }
    }
    

    In this example, I round to quarter points, but this is arbitrary; it could be smaller as only very tiny displacements fail to show up in the scene editor.

    I call this in the init function.