如何在 Sprite Kit 中初始化所有场景?
Posted
技术标签:
【中文标题】如何在 Sprite Kit 中初始化所有场景?【英文标题】:How do I initialize all scenes at the start in Sprite Kit? 【发布时间】:2014-08-27 11:45:26 【问题描述】:每当我想转换到某个场景时,SKTransition
甚至需要几秒钟才能开始。是否可以在游戏开始前初始化所有场景?
NewScene *newScene = [NewScene sceneWithSize:self.size];
SKTransition *reveal = [SKTransition moveInWithDirection:SKTransitionDirectionUp duration:0.5];
reveal.pausesIncomingScene = NO;
[self.view presentScene:newScene transition:reveal];
我也用didMoveToView
试过这个:
@implementation NewScene
-(id)initWithSize:(CGSize)size
if(self = [super initWithSize:size])
// Load a bunch of stuff like this:
SKSpriteNode *menuButton = [SKSpriteNode spriteNodeWithImageNamed:@"mainMenu"];
menuButton.position = CGPointMake(self.frame.size.width/2,self.frame.size.height/4);
menuButton.name = @"menuButton";
[self addChild:menuButton];
[menuButton setScale:0.8];
如何确保我的 Sprite Kit 游戏顺利运行?
编辑: 事实证明,问题在于我一直让主线程进入睡眠状态以淡出音乐。我已经让我所有的音频方法在后台运行,现在可以正常工作了。
【问题讨论】:
你能展示一下你用“加载一堆东西”评论替换了什么吗?在需要时创建场景不应该有任何问题,如果是,则更有可能重新考虑处理数据/加载资产的方式。你可以从尽可能多的异步处理开始,preloading textures。 @0x7fffffff - 编辑了我的帖子。我尝试过预加载纹理(为此使用了 Stack Overflow 上的另一个答案),但结果没有改变。我可能在新场景中加载了错误的纹理。也许你可以告诉我如何在新场景中加载纹理? 【参考方案1】:一个好的方法是在SKScene
的初始化之前异步加载所有资源。 Apple 在Adventure game 中使用了这种方法:
NewScene.h:
typedef void (^AGAssetLoadCompletionHandler)(void);
@interface GameScene : SKScene<SKPhysicsContactDelegate, UIGestureRecognizerDelegate>
+ (void)loadSceneAssetsWithCompletionHandler:(AGAssetLoadCompletionHandler)handler;
@end
NewScene.m:
@implementation NewScene
-(id)initWithSize:(CGSize)size
if(self = [super initWithSize:size])
// Load a bunch of stuff like this:
SKSpriteNode *menuButton = [SKSpriteNode spriteNodeWithTexture:[self menuButtonTexture];
menuButton.position = CGPointMake(self.frame.size.width/2,self.frame.size.height/4);
menuButton.name = @"menuButton";
[self addChild:menuButton];
[menuButton setScale:0.8];
#pragma mark - Shared Assets
+ (void)loadSceneAssetsWithCompletionHandler:(AGAssetLoadCompletionHandler)handler
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^
// Load the shared assets in the background.
[self loadSceneAssets];
if (!handler)
return;
dispatch_async(dispatch_get_main_queue(), ^
// Call the completion handler back on the main queue.
handler();
);
);
+ (void)loadSceneAssets
sBackgroundTexture = [SKTexture textureWithImageNamed:@"background"];
sMenuButtonTexture = [SKTexture textureWithImageNamed:@"mainMenu"];
// etc.
static SKTexture *sBackgroundTexture = nil;
- (SKTexture *)backgroundTexture
return sBackgroundTexture;
static SKTexture *sMenuButtonTexture = nil;
- (SKTexture *)menuButtonTexture
return sMenuButtonTexture;
@end
然后只需从您的UIViewController
中呈现NewScene
:
if (!self.skView.scene)
CGSize viewSize = self.view.bounds.size;
// Here you can present some loading scene or splash screen
[NewScene loadSceneAssetsWithCompletionHandler:^
NewScene *scene = [[NewScene alloc] initWithSize:viewSize];
[self.skView presentScene:scene transition:[SKTransition crossFadeWithDuration:1.f]];
];
【讨论】:
以上是关于如何在 Sprite Kit 中初始化所有场景?的主要内容,如果未能解决你的问题,请参考以下文章