SpriteKit: how to animate SKCameraNode smoothly when tracking a node, but only after the node moves Y pixels?

This question and others discuss how to track a node in SpriteKit using SKCameraNode.

However, our needs are changing.

Other solutions, such as updating the camera position in update(_ currentTime: CFTimeInterval)SKScene, do not work, because we only want to adjust the camera position after the node has moved Y pixels down.

In other words, if the node moves 10 pixels up, the camera should remain stationary. If the node button moves left or right, the camera should remain stationary.

We tried animating the camera’s position over time, rather than instantly, but running SKAction against the camera inside update(_ currentTime: CFTimeInterval)can do nothing.

+2
source share
2 answers

I just did it quickly. I believe this is what you are looking for? (the actual animation is smooth, I just had to compress the GIF)

enter image description here

This is the update code:

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */

    SKShapeNode *ball = (SKShapeNode*)[self childNodeWithName:@"ball"];
    if (ball.position.y>100) camera.position = ball.position;

    if (fabs(ball.position.x-newLoc.x)>10) {
        // move x
        ball.position = CGPointMake(ball.position.x+stepX, ball.position.y);
    }

    if (fabs(ball.position.y-newLoc.y)>10) {
        // move y
        ball.position = CGPointMake(ball.position.x, ball.position.y+stepY);
    }
}
+3
source

I would not put this in the update code, try to keep the clutter in the update section, remember that you only have 16 ms to work.

Instead, subclass your node symbol and override the position property. Basically, we say that if your camera is 10 pixels away from your character, move towards your character. We use the key in our action, so that we do not perform multiple actions and synchronization mode, so that the camera moves smoothly to your point, and not instantly.

class MyCharacter : SKSpriteNode
{
    override var position : CGPoint
    {
        didSet
        {

            if let scene = self.scene, let camera = scene.camera,(abs(position.y - camera.position.y) > 10)
            {
                let move = SKAction.move(to: position, duration:0.1)
                move.timingMode = .easeInEaseOut
                camera.run(move,withKey:"moving")
            }
        }
    }
}

Edit: @Epsilon , SKActions SKPhysics , , . didFinishUpdate:

override func didFinishUpdate()
{
    //character should be a known property to the class,  calling find everytime is too slow
    if let character = self.character, let camera = self.camera,(abs(character.position.y - camera.position.y) > 10)
    {
        let move = SKAction.move(to: character.position, duration:0.1)
        move.timingMode = .easeInEaseOut
        camera.run(move,withKey:"moving")
    }
}
+2

All Articles