leeparob
leeparob

Reputation: 35

How would you get the update method to be called in a class other than MyScene in Objective-C's Sprite-Kit project?

So I'm in the process of making a Objective-C Sprite-Kit based game. I'm fairly new to Objective-C so I seem to be stuck on something involving the update method.

Traditionally in the default Sprite-Kit project it generates for you create a View which contains a scene which contains all the nodes that you want to manipulate. It also comes with a pre-generated, empty update method which since then I have replaced with my own (which works great). But I do not want my update method to based in the MyScene class and this is where my problem lies. If I leave the update method in the MyScene class I can see using NSLog that is in fact continuously being called like it should be, but if I move it say to the ViewControler class it won't be called at all.

My question is how would I go about getting it to call the update method in a class other than MyScene..? You may be asking why I would want to do this so I'll explain below but its not fully necessary to answer the question, however if you do have any tips on my program please let me know!

Traditional Sprite-Kit Project

ViewController --> Creates a MyScene (which is just inheriting from SKScene) MyScene --> Creates all the nodes, and has the update method to hand game logic/graphics.

My Ideal Structure for my Sprite Game

ViewController --> Creates a ForegroundScene and BackgroundScene(still inherits from SKScene) ForegroundScene --> creates all the nodes/characters for the game BackgroundScene --> Creates the Sky, clouds, general landscape stuff for the game. GameController --> contains the update method which calls displayView and updateGame.

Edit: To clear up any confusion, ForgegroundScene and BackgroundScene are essentialy the same thing as the MyScene class which was originally generated, but now there are two classes re-named, one containing stuff for the background, the other for the foreground.

Update Game is still located in the GameController class and it just does things like collision test, updates position of nodes, deletes characters that were killed.

DisplayView is located in the ViewController and its name is self-explanatory it displays the view of the game which is composed of nodes from the BackgroundScene and the ForegroundScene.

Anyway, this is my idea set up for a game, not sure how pratical it is. I'm very open to suggestions.

Here is my intended update method incase you are interested in seeing it but like I said I test it with NSLog and it ticks accordingly but in any other class its never called.

-(void)update:(CFTimeInterval)currentTime
{
    const int TICKS_PER_SECOND = 35;
    const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; //these ivars would be moved to top of intended class
    const int MAX_FRAMESKIP = 10;

    NSDate *referenceDate = [NSDate date];

    double timePassed_ms = [referenceDate timeIntervalSinceNow] * -1000.0;
    NSUInteger next_game_tick = timePassed_ms;
    int loops;

    bool game_is_running = true;
    while( game_is_running ) {

        loops = 0;
        while([referenceDate timeIntervalSinceNow] * -1000.0 > next_game_tick && loops < MAX_FRAMESKIP) {
            [self updateGame] //calls GameController to do logic updates/collision test, etc.
            NSLog(@"update game");

            next_game_tick += SKIP_TICKS;
            loops++;
        }
        [self displayGame]; //calls viewcontroler to display game
    }
}

Upvotes: 2

Views: 703

Answers (1)

Brian Tracy
Brian Tracy

Reputation: 6831

You could make the class that you want to notify every time you call -update: an instance variable of your scene, then just forward the message to that class. For example, create an instance variable in your scene of the class you want to notify.

@interface MyScene ()
@property (nonatomic) ClassToNotify *notify;
@end

Then in your -update: method, just notify the instance variable.

- (void)update:(CFTimeInterval)currentTime
{
    // pass the message on
    [self.notify notifyThatUpdateWasJustCalledWithTime:currentTime];
}

In this case, -notifyThatUpdateWasJustCalledWithTime: would be a method of your ClassToNotify class.

Upvotes: 3

Related Questions