ios - 如何在 Sprite Kit 中初始化所有场景?

标签 ios objective-c xcode sprite-kit transition

每当我想要转换到某个场景时,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 游戏顺利运行?

编辑: 事实证明,问题是我一直让主线程进入休眠状态以淡出音乐。我已经让所有音频方法在后台运行,现在工作正常。

最佳答案

一个好的方法是在 SKScene 初始化之前异步加载所有资源。苹果在 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]];
    }];
}

关于ios - 如何在 Sprite Kit 中初始化所有场景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25526322/

相关文章:

ios - iOS 14重新排序UICollectionViewCell时崩溃

ios - 在 iOS 上将 Web 服务与离线存储同步的最佳实践

ios - 在 iOS 中渲染水彩画

c++ - 完全相同的 C++ 代码在 Visual Studio 中有效,但在 Xcode 中无效

html - IOS 在 HTML 中导致不需要的换行符

objective-c - iOS 以编程方式拍照

objective-c - iOS 9.3 UIGraphicsImageRenderer 没有显示任何其他选项吗?

ios - 在弧下的 iOS 5 中释放内存

xcode - 这些红色靶心图标在 Xcode 中是什么意思?

ios - self.tableView.indexPathForCell(cell) 返回错误的单元格?