我试图在 SpriteKit 中的场景“SKScene”之间传递数据。例如,我想将分数从 A 级传递到 B 级。
也许解决方案是归档,但我想实现一些更简单的东西,比如我们使用视图控制器的方式。
非常感谢这方面的任何线索。
我试图在 SpriteKit 中的场景“SKScene”之间传递数据。例如,我想将分数从 A 级传递到 B 级。
也许解决方案是归档,但我想实现一些更简单的东西,比如我们使用视图控制器的方式。
非常感谢这方面的任何线索。
如果您要将乐谱传递到许多不同的场景,您可能希望将其存储在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
.
Kobold Kit实际上使这样的事情变得简单,没有自定义子类。该视图具有(并且任何节点都可以具有)一个KKModel
对象,该对象是整数类型(float、int 等KKMutableNumber
)和任意对象的键/值存储。
因此,您可以通过将其绑定到视图来从任何节点持久并访问您的 highscores 对象:
[self.kkView.model setObject:highscores forKey:@"highscores"];
kkView 属性是写作的简写(KKView*)self.view
。
对于生命周期与场景或视图相关的对象,绝对没有必要使用或受益。它们属于场景或视图,时期。
这种方法对我有用,我认为它是正确的。到目前为止,这是在我发现的场景之间传递数据的最简单和最快的方法。
一、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
你在哪里/如何在场景之间转换?如果你能只显示你创建新场景的代码,那会有所帮助。我可能错过了问题的重点,但是如果您有某种“场景管理器”/导航器来执行此操作,那么只需将分数暂时保存在本地变量中并将其传递到您的新场景中。
Apple 文档指出 userData 是在Sprite Kit 最佳实践中存储节点特定数据的方法
使用节点上的userData属性来存储特定于游戏的数据,尤其是在您没有实现自己的子类时。
因此,在本机使用 Sprite Kit 时,我会接受 @doctorBroctor 的答案作为正确答案。
但是,您应该记住在设置值之前为目标节点初始化 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
}