2015-07-31 8 views
5

Od Xcode został zaktualizowany do wersji 6.0, domyślna metoda dla SpriteKit w „GameScene” (domyślny sceny tworzone) zmiany:Kiedy używać didMoveToView lub initWithSize z SpriteKit w Xcode 6.4

-(void) didMoveToView:(SKView *) view { 
/* Scene set up in here */ 
} 

w przeciwieństwie do starsza metoda:

-(id) initWithSize:(CGSize) size { 
    if (self = [super initWithSize:size]{ 
    /* Scene set up in here */ 
    } 
} 

rozumiem, że nowa metoda (zgodnie ze zmianami w sterowniku widzenia) jest używany do zarządzania import z pliku .sks który jest nowy w Xcode 6. Jednakże, byłem ciekawy, jeśli nie chcę używać nowego formatu "storyboard", który jest .sk s pliku, czy nadal powinienem używać nowej metody? Czy powinienem zmienić metodę z powrotem do metody initWithSize i po prostu usunąć plik .sks?

Odpowiedz

5

Metody inicjujące powinny być używane do inicjowania, ale należy pamiętać, że wewnątrz init widok zawsze jest nil. Więc każdy kod, który potrzebuje widoku, musi zostać przeniesiony do metody didMoveToView (jest wywoływany natychmiast po przedstawieniu sceny przez widok).

O initWithSize w Xcode 6 ... Domyślnie scena jest ładowana z pliku .sks. Z tego powodu initWithSize nigdy nie jest wywoływany. initWithCoder nazywa zamiast:

- (instancetype)initWithCoder:(NSCoder *)aDecoder 
{ 

    if (self = [super initWithCoder:aDecoder]) { 
     // do stuff 
    } 
    return self; 
} 

więc inicjowanie czegokolwiek wewnątrz initWithSize nie będzie miał żadnego wpływu. Jeśli zdecydujesz się usunąć .sks plik i utworzyć scenę w „starych” sposób można zrobić coś takiego w widoku kontrolera:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Configure the view. 
    SKView * skView = (SKView *)self.view; 
    skView.showsFPS = YES; 
    skView.showsNodeCount = YES; 
    /* Sprite Kit applies additional optimizations to improve rendering performance */ 
    skView.ignoresSiblingOrder = YES; 

    // Create and configure the scene. 
    GameScene *scene = [GameScene sceneWithSize:self.view.bounds.size]; 
    scene.scaleMode = SKSceneScaleModeAspectFill; 


    // Present the scene. 
    [skView presentScene:scene]; 
} 

Po tym, można użyć initWithSize dla inicjalizacji.

Należy zauważyć, że w viewDidLoad ostateczny rozmiar widoku może nie być jeszcze znany, a użycie viewWillLayoutSubviews może być dobrym wyborem. Czytaj więcej here.

i właściwe wdrożenie viewWillLayoutSubviews dla celów inicjalizacji scena będzie:

- (void)viewWillLayoutSubviews 
{ 
    [super viewWillLayoutSubviews]; 

    // Configure the view. 
    SKView * skView = (SKView *)self.view; 
    skView.showsFPS = YES; 
    skView.showsNodeCount = YES; 
    /* Sprite Kit applies additional optimizations to improve rendering performance */ 
    skView.ignoresSiblingOrder = YES; 

    //viewWillLayoutSubviews can be called multiple times (read about this in docs) so we have to check if the scene is already created 
    if(!skView.scene){ 
     // Create and configure the scene. 
     GameScene *scene = [GameScene sceneWithSize:self.view.bounds.size]; 
     scene.scaleMode = SKSceneScaleModeAspectFill; 

     // Present the scene. 
     [skView presentScene:scene]; 
    } 
} 

Kod Swift:

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene { 
     // Configure the view. 
     let skView = self.view as SKView 
     skView.showsFPS = true 
     skView.showsNodeCount = true 
     skView.showsPhysics = true 
     skView.showsDrawCount = true 

     /* Sprite Kit applies additional optimizations to improve rendering performance */ 
     skView.ignoresSiblingOrder = true 

     /* Set the scale mode to scale to fit the window */ 

     if(skView.scene == nil){ 

      scene.scaleMode = .AspectFill 
      scene.size = skView.bounds.size 
      skView.presentScene(scene) 
     } 


    } 
} 
0

Obie opcje są poprawne. Powiedział, że metoda init nie jest w rzeczywistości taka sama jak metoda didMoveToView:, ponieważ ta ostatnia zostanie wywołana, gdy SKScene zostanie zaprezentowany w postaci SKView.

2

Myślę, że nie ma dużej różnicy między tymi dwoma metodami, jeśli chodzi o faktyczne ustawienie sceny i jej używanie. (initWithSize jest wywoływane, gdy scena jest inicjowana, a didMoveToView jest zawsze wywoływana w prawo, gdy scena jest prezentowana w widoku). Domyślam się, że jeśli naprawdę wolisz widzieć inicjalizację, możesz po prostu użyć metody init bez żadnych problemów.

Odnośnie pliku .sks:

przyjrzeć się swoim widokiem pliku wdrażania kontrolera. Bezpośrednio nad metodami v.controller zobaczysz:

@implementation SKScene (Unarchive) 

+ (instancetype)unarchiveFromFile:(NSString *)file { 
    /* Retrieve scene file path from the application bundle */ 
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:fileofType:@"sks"]; 
    /* Unarchive the file to an SKScene object */ 
    NSData *data = [NSData dataWithContentsOfFile:nodePath 
             options:NSDataReadingMappedIfSafe 
             error:nil]; 
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
    [arch setClass:self forClassName:@"SKScene"]; 
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey]; 
    [arch finishDecoding]; 

return scene; 
} 
@end 

To jest część, która obsługuje sks. Korzystanie z pliku jest całkowicie opcjonalne, nie musisz tego robić i nie ma to żadnego wpływu na konfigurację sceny. Jeśli jednak chcesz z nim pracować, okaże się, że musisz pracować z tym fragmentem kodu.

Powiązane problemy