Question

I'm working on a game and it has 50 levels. I want to unlock each level after completing the level that comes before it. Right now I set up 50 SKSpriteNodeslabeled 1 to 50 so they are numbered levels. I want the NSUserDefaults to tell the level-selection screen that the user has unlocked a new level when the level is complete. (i.e. if user completes level 2, unlock level 3). I was trying to follow the solution on this question How to save NSMutablearray in NSUserDefaults but it wasn't working for me because I wasn't sure how to have an NSMutableArray that would be in both the level selection menu and the current level itself.

This is the bit of code I had tried:

[[NSUserDefaults standardUserDefaults] setObject:levelAchieved forKey:@"level2"];
[[NSUserDefaults standardUserDefaults] synchronize];

I used this when the user finished level 1

Then I tried calling this:

NSMutableArray *levelAchieved = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"level2"] mutableCopy];

To tell the level-selection scene that the user had achieved a new level and to unlock it on that scene.

But this didn't work because I wasn't able to have the array in both the scenes, even when I made sure I imported the header file that had the NSMutableArray *levelAchieved in.

How can I properly add to the array, but furthermore --> Is this the right way to be approaching this type of thing? Is there a different way to unlock a series of levels between 2 scenes?

Was it helpful?

Solution

NSUserDefaults is a valid way of both persisting information and accessing it across multiple classes, so there is nothing wrong with your technique from that point of view.

What I would look at is the need to store 50 different values. If levels can only be unlocked sequentially - i.e. You must complete all the levels 1-39 before you can attempt level 40, then all you need to do is store a single NSInteger that represents the highest completed level.

e.g. When you complete level 38, you would do something like

NSInteger highLevel=38;
[[NSUserDefaults standardUserDefaults] setInteger:highLevel forKey:@"highLevel"];

The first time your app runs you would need to set the NSUserDefault value to 0.

Without seeing your code, I can't give you the next bit exactly, but it would be something like:

NSInteger highLevel=[[NSUserDefaults standardUserDefaults] integerForKey:@"highLevel"];

for (int i=0;i<NUMBEROFLEVELS;i++)
{
    if (i<=highLevel) {
        // TODO Display unlocked level button
    }
    else {
        // TODO Display locked level button
    }
}

Note that setting highLevel to 0 actually unlocks level 1 because the first element of your array will actually be 0. When highLevel is 1 then element 0 and 1 (levels 1 and 2) are unlocked and so on...

OTHER TIPS

Would it be possible to just store the NSString of the highest level completed in the NSUserDefaults and not the full NSMutableArray (or the NSInteger for the index value). Since you are only unlocking the levels in a sequential pattern. if the user completes all levels up to level 7, then you just store level7 (or the value for objectAtIndex which would be 6). Then in your code display all objects in your array up to the highest level completed + 1, meaning display levels 1 through 8 (aka indexes 0 through 7).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top