SpriteKit: transferring data between scenes

I'm stuck trying to transfer data between SKScene scenes in SpriteKit. For example, I would like to transfer a grade from level A to level B.

Perhaps the solution archives, but I would like to implement something more simplified, like the way we use with view controllers.

Any clue in this regard would be greatly appreciated.

+7
ios iphone ios7 sprite-kit
source share
6 answers

If you intend to scroll to many different scenes, you might want to save it to NSUserDefaults or some available storage engine. However, if you want to transfer data between SpriteKit objects, each SKNode (including SKScene ) has a dictionary property called userData , which you can use for everything you want. Here is an example of how you can pass the score between scenes:

  - (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]; } 
+15
source share

Save the invoice in your view controller instance or SKView subclass and save it there. This will save any object during the lifetime of the view.

If you need points to keep between application reloads, use NSUserDefaults .

The Kobold Kit actually makes such things the same easily without any custom subclasses. The view has (and any node can have) a KKModel object, which is a repository of keys / values ​​for both integral types (float, int, etc. Through KKMutableNumber ) and arbitrary objects.

That way, you can save and access your highscore object from any node by binding it to a view:

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

The kkView property is short for writing (KKView*)self.view .

There is no need to use or use when using singletons for objects whose lifetime is tied to either the scene or the view. They relate either to the scene or to the species, the period.

+7
source share

This approach worked for me, and I think it is correct. So far this is the easiest and fastest way to transfer data between the scenes I found.

1. Basic information about userData:

1.1. Hold the apple "Command Key" and click the left mouse button (in Xcode) in the line "userData" (for example, "self". UserData strong>; "). You will receive the following information:

 // 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. Visit apple docs: userData

1.3 userData is an NSMutableDictionary, which is basically a special array. In addition to the value, it contains a key associated with the value. With this key you can find the values. It may also be useful: apple docs: NSMuttableDictionary

2. Solution:

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]; 

Here I refer to userData of secondScene, adding an object that is my account. For the purpose it is only 6. I will add my account instance variable. You can add whatever you want as it accepts objects of type "id". The key is important. You will use it in secondScene.m to access the value of the object from then on. Make sure you are not mistaken.

 [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 is my secondScene. I created it in Xcode with "File - New File ..." as: SKScene. It will contain userData shown below.

2.2. secondScene

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

The following lines of code verify that the value is added correctly:

 -(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"]); } 

Console output:

 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 

If I have something wrong, please correct me :). Specifications: iOS 7.0, version Xcode 5.1 (5B130a), OS X 10.9.2

+4
source share

Where / how do you jump between the scenes? If you could only show the code in which you create a new scene that will help. I may miss the question point, but if you have some kind of "scene manager" or some kind of navigator, just save the account in the local var temporarily and transfer it to your new scene.

0
source share

Apple's documentation states that userData is a way to store node-specific data here in the Best Sprite Kit Recommendations

Use the userData property on nodes to store game-related data, especially if you do not implement your own subclasses.

Therefore, I would accept @doctorBroctor's answer as correct for using the Sprite Kit natively.

However, you must remember the userData initialization for the target node before setting the value, since @ LearnCocos2d points to this answer. You can do this inside the initWithSize: method of the SKScene subclass that you are going to switch to.

0
source share
  // First Scene NSUserDefaults.standardUserDefaults().setInteger(12345, forKey:"SCORE") // Second Scene if let myScore: AnyObject = NSUserDefaults.standardUserDefaults().objectForKey("SCORE") { println(myScore) finalScore = myScore as IntegerLiteralType } 
0
source share

All Articles