SpriteKit:在场景之间传递数据

我试图在SpriteKit中的场景“SKScene”之间传递数据。 比如我想把A级的分数传给B级

也许解决scheme是归档,但我想实现一些更简单的事情,就像我们使用视图控制器的方式。

在这方面的任何线索将非常感激。

如果你打算把分数传递给很多不同的场景,你可能想把它存储在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]; } 

将分数存储在您的视图控制器实例中,或将SKView子类化并存储在那里。 这将在视图的整个生命周期中保留任何对象。

如果您需要在应用程序重新启动之间保持分数,请使用NSUserDefaults

狗头人实际上使这样的东西很容易,没有自定义的子类。 该视图(和任何节点可以)有一个KKModel对象,这是一个键/值存储为整数types(浮动,int等通过KKMutableNumber )和任意对象。

所以你可以坚持和访问你的highscores对象从任何节点捆绑到视图:

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

kkView属性是写作(KKView*)self.view简写。

对于生命周期与场景或视图相关的对象, 绝对没有必要使用或使用单例 。 它们属于现场或景观,时期。

这种方法对我有用,我认为这是正确的。 到目前为止,这是在我发现的场景之间传递数据的最简单和最快的方式。

1.有关userData的基本信息:

1.1。 按住“Command”键,并在“userData”string(例如“self.userData”)上按下鼠标左键(在Xcode中)。 您将获得以下信息:

 // 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。 访问苹果文档:userData

1.3 userData是一个NSMutableDictionary,它基本上是一个特殊的数组。 除了值之外,它还包含一个绑定到值的键。 用这个键你可以find值。 这也许是有帮助的: apple docs:NSMuttableDictionary

2.解决scheme:

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

在这里,我通过添加一个对象来引用secondScene的userData,这是我的分数。 为了testing目的,它只是6.我将添加我的分数实例variables。 你可以添加你想要的东西,因为它接受“ID”types的对象。 关键是重要的。 您将在secondScene.m中使用它来访问对象值。 检查你是否input错误。

 [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是我secondScene。 我使用“File – New File …”在Xcode中创build了它: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

你在哪里/如何在场景之间转换? 如果你可以只显示你创build新场景的代码,这将有所帮助。 我可能会错过这个问题的重点,但是如果你有一个“场景pipe理器”/导航器来完成这个任务,那么只需简单地将分数保存在本地variables中,并将其传递到你的新场景中。

Apple文档指出,userData是在Sprite Kit Best Practices中存储节点特定数据的方法

使用节点上的userData属性来存储特定于游戏的数据,特别是如果您没有实现自己的子类。

因此,我会接受@ doctorBroctor的答案作为本地使用Sprite Kit时的正确答案。

但是,在设置一个值之前,您应该记得初始化目标节点的userData,因为@ LearnCocos2d指出了这个答案。 你可以在你将要转换的SKScene子类的initWithSize:方法内部执行此操作。

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