2
votes

In SpriteKit, is it possible to add elements programmatically to the scene, so when .sks is opened, they display? Currently I have my GameScene (which extends SKScene) class that opens up already added elements in the scene editor, from the .sks file, using the UnarchiveFromFile method pattern. This method looks like this:

    @implementation SKScene (Unarchive)

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                          options:NSDataReadingMappedIfSafe
                                            error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

@end

How can I do the opposite thing from the unarchiveFromFile, ie. to go from the code and add sprites to the .sks file. After that, the unarchiveFromFile would be triggered and the rest goes as it is right now. Any suggestions guys? Thanks.

2
it is unclear what yo are asking can you please provide more infoRon Myschuk
Ok, I will add more info in the question.Vladimir Despotovic

2 Answers

1
votes

You don't want update your .sks file in code, even if you managed to work out how to do it. I think what you want to do is to add elements to the scene in didMoveTo(view:)

https://developer.apple.com/documentation/spritekit/skscene/1519607-didmove

didMove(to:) Called immediately after a scene is presented by a view.

Discussion This method is intended to be overridden in a subclass. You can use this method to implement any custom behavior for your scene when it is about to be presented by a view. For example, you might use0 this method to create the scene’s contents.

Here's an example to add a border:

override func didMove(to view: SKView) {
/* Setup your scene here */

//        drawBorder()
let border = drawSKShapeNode([CGPoint.zero,
    CGPoint(x: 0, y: frame.height),
    CGPoint(x: frame.width, y: frame.height),
    CGPoint(x: frame.width, y: 0)],
                             withWidth: 10,
                             inColour: SKColor.yellow,
                             called: "border")
border.zPosition = 200
addChild(border)
}

// Helper function to draw an SkShapeNode

    func drawSKShapeNode(_ withPoints: [CGPoint], withWidth width: CGFloat, inColour colour: SKColor, called name: String) -> SKShapeNode {

        var points = withPoints
        let shape = SKShapeNode(points: &points, count: points.count)
        shape.lineWidth = width
        shape.strokeColor = colour
        shape.name = name

        return shape 
}
0
votes

I solved my actual problem! - by just putting in a graph on the scene and getting it in the code. It is a NavigationGraph, and works fine. The programatic adding however didn't work.