Когда использовать didMoveToView или initWithSize с помощью SpriteKit в xCode 6.4

Поскольку xCode был обновлен до версии 6.0, метод по умолчанию для SpriteKit в «GameScene» (созданный по умолчанию сценарий) изменяется на:

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

в отличие от более старого метода:

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

Я понимаю, что новый метод (как и с изменениями в контроллере представления) используется для управления импортом из файла .sks, который является новым в xCode 6. Однако мне было любопытно, не хочу ли я использовать новый Формат «раскадровки», который является файлом .sks, должен ли я использовать новый метод? Или мне следует изменить метод обратно на метод initWithSize и просто удалить файл .sks?

Для инициализации следует использовать методы Init, но имейте в виду, что внутри init, просмотр всегда равен nil . Таким образом, любой код, который нуждается в представлении, должен быть перемещен в метод didMoveToView (он вызывается сразу же после того, как сцена представлена ​​представлением).

О initWithSize в Xcode 6 … По умолчанию сцена загружается из файла .sks. Из-за этого initWithSize никогда не называется на самом деле. Вместо этого вызывается initWithCoder :

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

Поэтому инициализация чего-либо внутри initWithSize не будет иметь никакого эффекта. Если вы решили удалить файл .sks и создать сцену «старым» способом, вы можете сделать что-то вроде этого в контроллере вида:

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

После этого вы можете использовать initWithSize для инициализации.

Обратите внимание, что в viewDidLoad окончательный размер представления может быть неизвестен, и использование viewWillLayoutSubviews вместо этого может быть правильным выбором. Подробнее читайте здесь .

И правильная реализация viewWillLayoutSubviews для цели инициализации сцены будет:

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

Быстрый код:

 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) } } } 

Я думаю, что для всех целей и целей нет никакой разницы между этими двумя методами, когда дело доходит до фактической настройки вашей сцены и ее использования. ( initWithSize вызывается, когда сцена инициализируется, а didMoveToView всегда вызывается сразу, когда сцена представлена ​​представлением). Я думаю, если вы действительно хотите увидеть инициализацию, вы можете просто использовать метод init без каких-либо проблем.

Что касается файла .sks:

взгляните на файл реализации контроллера просмотра. Прямо над методами v.controller вы увидите:

 @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 

Это та часть, которая обрабатывает sks. Использование файла полностью необязательно, вы не вынуждены это делать, и это действительно не влияет на настройку вашей сцены. Однако, если вы хотите работать с ним, вы обнаружите, что вам нужно будет работать с этим фрагментом кода.

Оба варианта верны. Сказано, что метод init самом деле не didMoveToView: , как метод didMoveToView: поскольку этот последний будет вызываться, как только SKScene будет представлен в SKView .

Interesting Posts
Давайте будем гением компьютера.