8

我试图在 SpriteKit 中的场景“SKScene”之间传递数据。例如,我想将分数从 A 级传递到 B 级。

也许解决方案是归档,但我想实现一些更简单的东西,比如我们使用视图控制器的方式。

非常感谢这方面的任何线索。

4

6 回答 6

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

 }
于 2013-09-20T19:28:06.520 回答
6

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

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

Kobold Kit实际上使这样的事情变得简单,没有自定义子类。该视图具有(并且任何节点都可以具有)一个KKModel对象,该对象是整数类型(float、int 等KKMutableNumber)和任意对象的键/值存储。

因此,您可以通过将其绑定到视图来从任何节点持久并访问您的 highscores 对象:

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

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

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

于 2013-09-20T08:37:18.817 回答
4

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

一、userData基本信息:

1.1。按住苹果的“Command key”并在“userData”字符串(例如“ 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,它基本上是一个特殊的数组。除了值之外,它还包含一个绑定到该值的键。使用此键,您可以找到值。这也可能有帮助:apple docs:NSMuttableDictionary

2.解决方法:

2.1。第一场景

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

在这里,我通过添加我的 score 对象来引用 secondScene 的 userData 。出于测试目的,它只有 6 个。我将添加我的 score 实例变量。您可以添加任何您想要的内容,因为它接受“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.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

于 2014-03-12T15:23:37.423 回答
0

你在哪里/如何在场景之间转换?如果你能只显示你创建新场景的代码,那会有所帮助。我可能错过了问题的重点,但是如果您有某种“场景管理器”/导航器来执行此操作,那么只需将分数暂时保存在本地变量中并将其传递到您的新场景中。

于 2013-09-26T11:49:34.570 回答
0

Apple 文档指出 userData 是在Sprite Kit 最佳实践中存储节点特定数据的方法

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

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

但是,您应该记住在设置值之前为目标节点初始化 userData,正如@LearnCocos2d 在此答案中指出的那样。您可以在您即将过渡到的 SKScene 子类的 initWithSize: 方法中执行此操作。

于 2013-11-13T08:47:41.833 回答
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
    }
于 2015-03-10T20:41:28.690 回答