1

I have created an SKCameraNode which is is able to move around and look at a to-scale version of the solar system. I am having an issue when the camera zooms in and moves around as shown here:

https://gfycat.com/HighScarceHorsemouse

This is the code that moves the position of the camera:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches{

        let pointOfTouch = touch.location(in: self)
        let previousPointOfTouch = touch.previousLocation(in: self)


        let amountDraggedY = (pointOfTouch.y - previousPointOfTouch.y)
        let amountDraggedX = (pointOfTouch.x - previousPointOfTouch.x)

        hud.touchesMoved(x: amountDraggedX, y: amountDraggedY)

    }
}

hud.touchesMoved calls this:

func touchesMoved(x: CGFloat, y:CGFloat){

    print("Previous Position:" + cam.position.debugDescription)
    print("Position Change: (\(x), \(y))")
    cam.position.x = cam.position.x - x
    cam.position.y = cam.position.y - y
    print("New Position: " + cam.position.debugDescription)

}

The output of the print function gives me this when the camera is zoomed out:

Previous Position:(-2940752.25, 86727.8203125)
Position Change: (-2940752.25, -2940752.25)
New Position: (-2940752.25, 86727.8203125)

When the camera zooms in, and moves around I get these values

Previous Position:(-2940770.0, 86966.34375)
Position Change: (0.0, -0.0859375)
New Position: (-2940770.0, 86966.4296875)

For some reason when I am moving my finger across the screen, the touchesMoved function doesn't give a value for the change in position in the x-axis, and instead gives zero. Once I move my finger a certain amount left or right and it snaps to the next position.

I tried getting the location of the touch in the view (instead of the SKScene), and then multiplied it by the camera scale to get a more precise number to move the camera by. But for some reason the position of the camera refused to move until it was given a value big enough to snap left or right.

Also, the video only shows it jittering only along the x-axis. This is when the earth was almost directly left of the sun. When the earth completes 1/4th of its orbit and is above the sun, the jittering and movement issues will only happen along the y-axis. This also means that the jitteriness does not occur when the camera is near (0, 0).

I then tried scaling down the entire solar system because I thought the large numbers were causing the issue. But it still didn't fix it. Then I tried using an SKAction to move the camera but that did not work either.

Could this be an issue with using CGFloats. I thought maybe they are not giving precise enough value and instead rounding the position values of the camera.

Any clues or indications as to what this could be would be extremely helpful.

EDIT: So it looks like this a problem when setting a CGPoint equal to an SKNode's position

 func updatePos(delta:CGFloat, ct:CGFloat){

    let t = CGFloat(Int(ct*10000) % Int(T*10000))/10000
    let newPos = getPos(at: t)

    self.prevPos = self.position
    self.position = newPos
    self.vel = calcVel()

    if(self.name == "Earth"){
        print("P1: " + newPos.debugDescription)
        print("P2: " + self.position.debugDescription)
        //self.position.
    }

}

This prints:

P1: (-147027315091.13248, 4715744568.852638)
P2: (-147027312640.0, 4715744768.0)
P1: (-147027315075.2827, 4715745071.273114)
P2: (-147027312640.0, 4715745280.0)
P1: (-147027315059.33746, 4715745576.7201805)
P2: (-147027312640.0, 4715745792.0)
P1: (-147027315043.39218, 4715746082.167245)
P2: (-147027312640.0, 4715746304.0)
P1: (-147027315027.54242, 4715746584.587657)
P2: (-147027312640.0, 4715746816.0)
P1: (-147027315011.59717, 4715747090.034788)
P2: (-147027312640.0, 4715747328.0)
P1: (-147027314995.65192, 4715747595.481853)
P2: (-147027312640.0, 4715747840.0)

My calcPos() function will calculate a very accurate position, however when I set it equal to the the node's position it all of a sudden gets rounded. This definitely is the cause of the issue. Is there a way to fix or get around this?

samster
  • 142
  • 1
  • 2
  • 9
  • 1
    the cause of your issue is you are not using an SKAction. SKAction will allow a smoother movement because your sprite movement is slightly delayed which allows the camera to move in a fluid line and not jumping back and forth. Floats are always going to round in Spritekit, because this is the way floats work in general. a value like 0.1 cannot be represented in binary format. – Knight0fDragon Nov 02 '18 at 13:44
  • newPos and self.position are both CGPoints, which are structs that contain two CGFloats. If newPos is able to hold two decimal values in the form of CGFloats, shouldn't self.position be able to as well? – samster Nov 02 '18 at 16:12
  • Even though you think it is 2 decimal values, it really isn’t. There are checks in place to display a different value then what it really is, but behind the scenes, it is always rounding. On top of that, precision changes from 32bit to 64bit in a few places, causing even more rounding errors. – Knight0fDragon Nov 02 '18 at 16:18
  • would you know of any other way to get around this? I tried SKActions, but it did not stop the jitteriness. – samster Nov 02 '18 at 16:31
  • are you using it properly? You can't just keep slapping actions on, you need to remove the previous one – Knight0fDragon Nov 02 '18 at 18:02

0 Answers0