SpriteKit - Return to a persistent scene in the same state it was left in.

我的梦境 提交于 2019-12-08 06:31:45

问题


The concept of being able to return to a previous scene from where you left off is briefly mentioned here: https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/DesigningGameswithSpriteKit/DesigningGameswithSpriteKit.html

Other than that I can't find any more documentation on the subject. I know in other frameworks like Cocos2D you can pop scenes on a stack, and even have multiple scenes running at the same time.

How do I get this to work in SpriteKit.

I have a game with a swiping menu for character selection. Upon selecting a character the scene changes to another menu. I want users to be able to hit a back button and be presented with the previous scene, where the character they selected is in full view.

At the moment I have it presenting the previous scene as a new one. Which of cause creates it in a fresh state, with the first character in plain view, and not the character they selected.

This should be really simple, but for all my googling, I do not have a clue on how to implement this.


回答1:


I don't know if anyone is still checking this, but I believe that I have another way to solve the problem.

I made a custom "PauseScene" and the user can set a return scene, meaning that when you are ready to go back, the PauseScene's view presents the return scene. Here's the code:

PauseScene.h

#import "MAScene.h"

@interface PauseScene : MAScene
@property (weak, nonatomic, readonly) SKScene * returnScene;

-(void)setReturnScene:(SKScene *)otherScene;


@end

PauseScene.m

#import "PauseScene.h"
#import "MASpriteButton.h"


@interface PauseScene ()
@property (strong, nonatomic) MASpriteButton * resumeButton;
@end


@implementation PauseScene


-(void)setReturnScene:(SKScene *)otherScene
{
    _returnScene = otherScene;
}


-(void)didMoveToView:(SKView *)view
{
    [self createContent];
}

-(void)createContent
{

    __weak typeof(self) weakMe = self;

    MASpriteButton * resume = [[MASpriteButton alloc] initWithBackgroundImageNamed:@"cardback.png" andSelectedImageNamed:@"cardback.png" andCallbackBlock:^{

        NSLog(@"removing...");
        [weakMe.view presentScene:self.returnScene];
    }];

    resume.size = CGSizeMake(self.widthToHeightRatio * 20, self.heightToWidthRatio * 20);
    resume.position = CGPointMake(self.size.width/2, self.size.height/2);


    self.resumeButton = resume;
    [self addChild:self.resumeButton];
    [self setBackgroundColor:[UIColor blueColor]];
}


@end

The way I used it was that when the user hits a pause button in the gameplay scene, I call these lines:

self.paused = YES;
PauseScene * pScene = [[PauseScene alloc] initWithSize:self.size];
[pScene setReturnScene:self];
[self.view presentScene:pScene];

Note that self in this little block is the gameplay scene.

By having the pause scene keep a weak pointer to the gameplay scene, it can keep a pointer to the return scene without dealloc-ing it when the pause scene is dealloc-ed.

PS The MAScene class is just a little extension of the SKScene class, I just added a couple things to it. If anyone wants that too just let me know.




回答2:


Assuming the menu scene is also implemented in Sprite Kit, you could create a modal view controller, present it, and put the Sprit Kit scene over that modal view.

So, specifically, create a new UIViewController inheriting class MenuViewController, and a new SKScene inheriting class, MenuScene. The class 'MenuScene' MenuScene should be the Scene you're looking to present. Hook up MenuScene and MenuViewController like you would normally hook up an SKScene and its view controller. Make sure you have the original scene's view controller as a property of the original SKScene.

Wherever you want to present this menu, you can call from the original SKScene:

MenuViewController *modalViewController = [[MenuViewController alloc] init]; [self.viewController presentModalViewController:modalViewController];

There are simpler ways to just transition b/w SKScene instances, but if you want to keep the intial SKScene running in the background, this is what you would have to do, I believe.




回答3:


You just should keep strong pointer to the leaving scene before you call new

Here is example of realisation via singleton (actually usual singleton with scene pointer, no magic)

@interface Global : NSObject

+ (Global*)sharedInstance;

@property (strong, nonatomic) SKScene *mainScene;
@end

And .m file

@implementation Global

+ (instancetype) sharedInstance{
    static Global *_sharedInstance = nil;

    static dispatch_once_t oncePredicate;

    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[Global alloc] init];
    });
    return _sharedInstance;
}

@end


来源:https://stackoverflow.com/questions/20507790/spritekit-return-to-a-persistent-scene-in-the-same-state-it-was-left-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!