Как сохранить высокий результат в Xcode SpriteKit, даже если я выйду из приложения и снова открою его?

У меня есть приложение для видеоигр, которое я создал в Xcode, SpriteKit с помощью приложения-шаблона "Игра". В моей игре есть метка очков, которая отслеживает счет и обновляется, когда игрок набирает очки. Ниже приведен код, который я создал для двух меток: текущая и высокая оценка. В моем приложении гораздо больше кода, но я просто хотел упростить его и показать только тот код, который имеет отношение к этой ситуации. Когда я закрываю приложение и снова открываю приложение, счет сбрасывается до нуля. Но что я хочу, чтобы сохранить номер рекорда, даже если вы закроете приложение? А также, если текущая оценка выше, чем высокая оценка, тогда я хочу, чтобы высокая оценка была обновлена ​​до новой оценки, если это имеет смысл.

Я открыт для предложений.

GameScene.h

#import <SpriteKit/SpriteKit.h>

@interface GameScene : SKScene <SKPhysicsContactDelegate>
{
    NSTimer *timerOne;
    NSTimer *timerTwo;
    NSInteger HighScore;
    NSInteger score;
}
@end

GameScene.m

-(void)didMoveToView:(SKView *)view {

   //SCORELABEL
    SKLabelNode *scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"ChalkboardSE-Bold"];
    scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), self.frame.size.height-50);
    scoreLabel.fontSize = 30;
    scoreLabel.text = @"0";
    scoreLabel.fontColor = [SKColor blueColor];
    scoreLabel.name = @"scoreLabel";
    [self addChild:scoreLabel];
}



-(void) didBeginContact:(SKPhysicsContact *)contact {

   //When redblock comes in contact with redball
   if (contact.bodyA.categoryBitMask == CollisionCategoryRedBlock &&
        contact.bodyB.categoryBitMask == CollisionCategoryRedBall) {

        //Update the score label and add 1 to the current score
        [self addPoint:1];
    }

   //if anything else happens it's gameover
   else {
       [self performGameOver];
   }

}

//Method to add a point to the scorelabel
-(void) addPoint:(NSInteger)points {


    score += points;

    SKLabelNode *scoreLabel = (SKLabelNode*)[self       childNodeWithName:@"scoreLabel"];

    scoreLabel.text =[NSString stringWithFormat:@"%ld", (long)score];

}

//Gameover method which will show the high score label
-(void) performGameOver {

    //HIGHSCORELABEL
    SKLabelNode *highScoreLabel = [SKLabelNode labelNodeWithFontNamed:@"ChalkboardSE-Bold"];
    highScoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), 100);
    highScoreLabel.fontSize = 20;
    highScoreLabel.text = [NSString stringWithFormat:@"High Score: %ld", (long)score];
    highScoreLabel.fontColor = [SKColor blueColor];
    [self addChild:highScoreLabel];
}

2 ответа

Предположим, у нас есть массив высоких результатов, то есть: несколько пользователей

Пользовательские ошибки, базовые данные и списки могут быть прочитаны / записаны, но если вы используете список, вам нужно обратить внимание на то, какой каталог вы добавили. Смотрите часть списка ниже.

NSUserDefaults:
Это своего рода глобальные переменные, которые вы можете сказать, которые не удаляют свое состояние, пока не будут уничтожены. но можно синхронизировать

Чтобы написать их пользователю по умолчанию:

NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
[[NSUserDefaults standardUserDefaults] setObject:stringsArray forKey:@"MyStrings"];
[[NSUserDefaults standardUserDefaults] synchronize]

Чтобы прочитать от пользователя по умолчанию:

NSArray *stringsArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyStrings"];

Плист:

Если ваши строки будут изменены, вам нужно будет написать и прочитать plist, но вы не можете писать в ресурсы своего приложения.

  1. Чтобы получить список для чтения / записи, сначала найдите каталог документов

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
    
  2. Создайте массив (я предполагаю, что строки - это string1, ...)

    NSArray *stringsArray = [[NSArray alloc] arrayWithObjects: string1, string2, string3, nil];
    
  3. запишите это в файл

    [stringsArray writeToFile:stringsPlistPath atomically:YES];
    

Чтобы прочитать список:

  1. найти каталог документов

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Strings.plist"];
    
  2. прочитайте это в:

    NSArray *stringsArray = [NSArray arrayWithContentsOfFile:stringsPlistPath];
    

Вы можете использовать NSUserDefaults или, если вы намереваетесь использовать синхронизацию устройства и хранить большее количество данных, NSCoding.

Самый простой и быстрый - NSUserDefaults. NSCoding немного сложнее, но есть некоторые ориентированные в сети. На данный момент NSUSer Defaults будет выглядеть так:

Создайте при реализации NSUserDefaults:

@implementation FKMyScene{
    NSUserDefaults *prefs;
    /* Any other you use below*/
  }

Затем, при запуске init это так:

prefs = [[NSUserDefaults alloc] init];
    if(!prefs)
        [prefs setInteger:0 forKey:@"YourAppHighScore"];

Теперь он должен работать и будет хранить значения для нужных ключей. (Мы устанавливаем InInteger в 0, поэтому начальное значение равно 0. Далее, если вы хотите сохранить лучшие результаты, вы будете использовать строку для присвоения имени значению (например, "YourAppHighScore") и вызывать Integer с этим именем.

/*This should fetch the value whenever you need*/    
[prefs integerForKey:@"YourAppHighScore"];

/*This should update the value whenever you need*/
/*Note that I use setInteger to insert the new value. This can be used anywhere.*/
if(currentScore > [prefs integerForKey:@"YourAppHighScore"])
        [prefs setInteger:currentScore forKey:@"YourAppHighScore"];

Если вы намереваетесь сохранить что-либо еще, вы можете сделать это тем же методом, но убедитесь, что вам нужен integerForKey, objectForKey и т. Д. И т. Д.

Другие вопросы по тегам