2013-09-19 7 views
7

Я застреваю, пытаясь передать данные между сценами «SKScene» в SpriteKit. Например, я хотел бы передать оценку от уровня А до уровня B.SpriteKit: Передача данных между сценами

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

Любая подсказка в этом отношении будет очень оценена.

+2

Я хотел бы использовать синглтон для этого – DogCoffee

ответ

15

Если вы собираетесь прокрутить счет до множества разных сцен, вы можете захотеть сохранить его в NSUserDefaults или в каком-то доступном механизме хранения. Однако, если вы хотите передавать данные между объектами SpriteKit, каждый SKNode (включая SKScene) имеет свойство словаря userData, которое вы можете использовать для всего, чего вы так хотите. Вот пример того, как вы могли бы пройти счет между сценами:

- (void)changeScene 
{ 
     SKView *spriteView = (SKView *) self.view; 
     SKScene *currentScene = [spriteView scene]; 
     SKScene *newScene = [MySceneClass scene]; 
     [newScene.userData setObject:[currentScene.userData objectForKey:@"score"] forKey:@"score"]; 
     [spriteView presentScene:newScene]; 

} 
7

Храните оценку в своем экземпляре контроллера вашего вида или подклассе SKView и храните его там. Это сохранит любой объект за время жизни представления.

Если вам нужны баллы, которые необходимо сохранить между перезагрузками приложений, используйте NSUserDefaults.

Kobold Kit на самом деле делает такие вещи легкими без каких-либо пользовательских подклассов. У представления есть (и любой узел может иметь) объект KKModel, который является хранилищем ключей/значений для обоих интегральных типов (float, int и т. Д. Через KKMutableNumber) и произвольных объектов.

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

[self.kkView.model setObject:highscores forKey:@"highscores"]; 

Свойство kkView является сокращением для написания (KKView*)self.view.

Абсолютно нет необходимости использовать или использовать в использовании одноточие для объектов, срок службы которых привязан либо к сцене, либо к виду. Они относятся либо к сцене, либо к виду, периоду.

+1

+1 для объяснения, почему одиночек не правильный путь - [на самом деле, они, как правило, не] (http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons) – Till

+0

Согласовано о ненужном синглетоне. –

0

Где/как вы переход между сценами? Если бы вы могли показать только код, в котором вы создадите новую сцену, которая поможет. Возможно, мне не хватает точки в вопросе, но если у вас есть какой-то «менеджер сцен»/навигатор, просто сохраните счет в локальном var временно и передайте это в свою новую сцену.

0

компании Apple документация говорится, что USERDATA это путь для хранения узлов конкретных данных здесь в Sprite Kit Best Practices

Используя userData свойства на узлы для хранения игровых конкретных данных, особенно, если вы не выполняете свои собственные подклассы ,

Поэтому я принимаю ответ @ doctorBroctor как правильный, если использовать Sprite Kit изначально.

Однако вы должны запомнить инициализацию userData для целевого узла, прежде чем устанавливать значение как @ LearnCocos2d, указывая в ответе this. Вы можете сделать это внутри метода initWithSize: подкласса SKScene, к которому вы собираетесь перейти.

4

Этот подход работал для меня, и я думаю, что это правильно. Пока это самый простой и быстрый способ передачи данных между найденными мной сценами.

1. Основные сведения о USERDATA:

1,1. Удерживайте яблочный «Командный ключ» и нажмите левую кнопку мыши (в Xcode) в строке «userData» (например, «self». userData; »). Вы получите следующую информацию:

// An optional dictionary that can be used to hold user data pretaining to the node. Defaults to nil. 
@property (SK_NONATOMIC_IOSONLY, retain) NSMutableDictionary *userData; 

1.2. Посетите apple docs:userData

1.3 userData - это NSMutableDictionary, который в основном представляет собой специальный массив. Помимо значения, он содержит ключ, привязанный к значению. С помощью этого ключа вы можете найти значения. Это может быть полезно, как хорошо: apple docs:NSMuttableDictionary

2. Решение:

2,1. firstScene

//somewhere in firstScene.m 
//how the tranisiton from firstScene to secondScene is going to look and how long it is goint to take 
SKTransition *reveal = [SKTransition moveInWithDirection:SKTransitionDirectionDown duration:0.5]; 
SKView * skView = (SKView *)self.view; 
SKScene *secondScene = [WBMGameEndsScene sceneWithSize:skView.bounds.size]; 
//You need to initialize the NSMD since it is by default nil. 
secondScene.userData = [NSMutableDictionary dictionary]; 

Здесь я ссылаюсь на USERDATA в secondScene путем добавления объекта, который мой счет. Для цели это всего лишь 6. Я добавлю свою переменную экземпляра счета. Вы можете добавить все, что захотите, поскольку оно принимает объекты типа «id». Ключ важен. Вы будете использовать его в secondScene.m для доступа к значению объекта с тех пор. Убедитесь, что вы не ошибаетесь.

[secondScene .userData setObject:@"6" forKey:@"score"]; 
//Testing 
NSLog(@"Is it finally working -- %@",[secondScene .userData objectForKey:@"score"]); 
//The secondScene will scale to fit the whole SKView 
secondScene.scaleMode = SKSceneScaleModeAspectFill; 
//present the secondScene 
[self.scene.view presentScene: secondScene transition:reveal]; 

* WBMGameEndsScene - это моя вторая сцена. Я создал его в Xcode с «File - New File ...» как: SKScene. Он будет содержать userData, показанный ниже.

2.2. secondScene

//secondScene.m (ex. in my :"@implementation WBMGameEndsScene") 

Эти следующие строки проверки кода, если значение было добавлено:

-(void)didMoveToView:(SKView *)view 
{ 
    NSLog(@"-- -(void)willMoveFromView:(SKView *)view --"); 
    NSLog(@"Working score is : %@",[self.userData valueForKey:@"score"]); 
    NSLog(@"Working score is : %@",[self.userData objectForKey:@"score"]); 
} 

выход консоли:

2014-03-12 15:29:06.804 AppTest[4841:60b] -(id)initWithSize:(CGSize)size 
2014-03-12 15:29:06.806 AppTest[4841:60b] scoreLabel 
2014-03-12 15:29:06.812 AppTest[4841:60b] successMessage 
2014-03-12 15:29:06.815 AppTest[4841:60b] Is it finally working -- 6 
2014-03-12 15:29:06.815 AppTest[4841:60b] -- -(void)willMoveFromView:(SKView *)view -- 
2014-03-12 15:29:06.816 AppTest[4841:60b] Working score is : 6 
2014-03-12 15:29:06.816 AppTest[4841:60b] Working score is : 6 

Если я что-то неправильно, пожалуйста, поправьте меня :) , характеристики: IOS 7.0, Xcode версии 5.1 (5B130a), OS X 10.9.2

0
// First Scene 
    NSUserDefaults.standardUserDefaults().setInteger(12345, forKey:"SCORE") 

    // Second Scene 
    if let myScore: AnyObject = NSUserDefaults.standardUserDefaults().objectForKey("SCORE") { 
     println(myScore) 
     finalScore = myScore as IntegerLiteralType 
    } 
Смежные вопросы