2015-07-31 22 views
5

Dal xCode è stato aggiornato alla versione 6.0, il metodo predefinito per SpriteKit in "GameScene" (la scena predefinito creato) modifiche:Quando utilizzare didMoveToView o initWithSize con SpriteKit in Xcode 6.4

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

al contrario di il metodo più vecchio:

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

capisco che il nuovo metodo (come con i cambiamenti nel controller della vista) è usato per aiutare a gestire l'importazione dal file .sks che è nuovo in xcode 6. Tuttavia, ero curioso se non volessi usare il nuovo formato di "storyboard" che è il .sk s file, dovrei ancora usare il nuovo metodo? O devo cambiare il metodo di nuovo al metodo initWithSize e solo eliminare il file .sks?

risposta

5

I metodi di inizializzazione devono essere utilizzati per l'inizializzazione, ma tenere presente che all'interno di init, la vista è sempre nil. Quindi qualsiasi codice che richiede la vista deve essere spostato sul metodo didMoveToView (viene chiamato immediatamente dopo che una scena viene presentata da una vista).

Informazioni su initWithSize in Xcode 6 ... Per impostazione predefinita, la scena viene caricata dal file .sks. Per questo motivo, initWithSize non viene mai chiamato in realtà. initWithCoder si chiama invece:

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

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

Così inizializzare nulla all'interno initWithSize non avrà alcun effetto. Se si decide di eliminare .sks di file e creare una scena in modo "vecchio", si può fare qualcosa di simile in controller di vista:

- (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]; 
} 

Dopo di che, è possibile utilizzare initWithSize per l'inizializzazione.

Si noti che in viewDidLoad la dimensione finale di una vista potrebbe non essere ancora nota, e l'utilizzo di viewWillLayoutSubviews potrebbe invece essere una scelta giusta. Maggiori informazioni here.

e la corretta attuazione del viewWillLayoutSubviews fini scena l'inizializzazione sarebbe:

- (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]; 
    } 
} 

Swift code:

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

Entrambe le opzioni sono corrette. Detto questo, il metodo init non è in realtà lo stesso del metodo didMoveToView:, poiché quest'ultimo verrà chiamato quando lo SKScene viene presentato in un SKView.

2

Penso che, a tutti gli effetti, non ci sia molta differenza tra i due metodi quando si tratta di impostare effettivamente la scena e usarla. (initWithSize viene chiamato quando la scena viene inizializzata, mentre didMoveToView viene sempre chiamato a destra quando la scena viene presentata dalla vista). Suppongo che se preferisci davvero vedere l'inizializzazione, puoi semplicemente usare il metodo init senza alcun problema.

Per quanto riguarda il file .sks:

un'occhiata al file di implementazione controller della vista. Subito sopra i metodi di v.controller vedrai:

@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 

Questa è la parte che gestisce gli sk. L'utilizzo del file è totalmente opzionale, non sei obbligato a farlo e non ha alcun impatto sull'impostazione della scena. Tuttavia, se vuoi lavorarci, scoprirai che dovrai lavorare con questo snippet di codice.

Problemi correlati