Сложность с SKScene. Передача игры в UIViewController.
У меня есть два UIViewControllers. Пользователь начинает с UIViewController. Затем пользователь нажимает кнопку, чтобы начать игру. Таким образом, приложение переключается на другой viewcontroller, PlayViewController, который показывает игру с SKView. А ActionScene - это подкласс SKScene, который отвечает за игровой процесс. Когда пользователь терпит неудачу, приложение отображает метку (SKLabelNode) и спрашивает, хочет ли он или она выйти из игры. Если пользователь коснется этой метки, игрок будет возвращен к контроллеру основного вида (UIViewController) через PlayViewController. Поэтому я считаю, что ActionScene должна делегировать эту задачу PlayViewController. Следующее происходит от ActionScene.
// ActionScene.h
#import <SpriteKit/SpriteKit.h>
@protocol actionDelegate;
@interface ActionScene : SKScene
@property (weak) id <actionDelegate> delegate;
@end
@protocol actionDelegate <NSObject>
@required
// Delegate
- (void)closeScene;
@end
// ActionScene.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
SKNode *n = [self nodeAtPoint:[touch locationInNode:self]];
if (n != self && [n.name isEqual: @"doneLabel"]) { // It was else if before. I've made a change.
[[self childNodeWithName:@"doneLabel"] removeFromParent]; // The user chooses to end the game by tapping doneLabel (SKLabelNode)
[self.delegate closeScene];
}
}
}
Что касается PlayViewController, он отвечает за представление ActionScene в SKView, а также за отправку пользователя обратно в UIViewController следующим образом.
// PlayViewController.h
#import "ActionScene.h"
@interface PlayViewController : UIViewController <actionDelegate>
@property (strong,nonatomic) ActionScene *actionScene;
@end
// PlayViewController.m
- (void)viewWillLayoutSubviews {
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[ActionScene alloc] initWithSize:spriteView.frame.size];
[self.actionScene setDelegate:self]; // Letting ActionScene delegate a task to itself
[spriteView presentScene:scene];
}
- (void)closeScene {
// It doesn't get a call from ActionScene
}
Поэтому, когда пользователь нажимает на ярлык "Готово", closeScene предназначен для включения. Но этот метод делегата никогда не получает вызов. Я не разрабатывал iOS-приложение последние 9 месяцев. Но я думаю, что у меня есть правильная идея. Что я делаю неправильно? Пока я читал эту тему, эту тему и другие.
Спасибо за помощь.
// Дополнительные пояснения //
- Все действия удаляются до того, как пользователь нажмет на DoneLabel.
- В игровое приложение войдет touchBegan. Тем не менее, он пропустит строку [spriteView presentScene:scene].
2 ответа
Со ссылкой на этот пост моя отчаянная мера сработала. Следующее изменение внесено в PlayViewController.m, чтобы вернуть пользователя в UIViewController.
- (void)viewWillLayoutSubviews {
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
SKScene *scene = [[ActionScene alloc] initWithSize:spriteView.frame.size];
[self.actionScene setDelegate:self]; // Letting ActionScene delegate a task to itself
[spriteView presentScene:scene];
}
в
- (void)viewWillLayoutSubviews {
SKView *spriteView = [[SKView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:spriteView];
ActionScene *scene = [ActionScene sceneWithSize:spriteView.bounds.size];
[scene setDelegate:self];
[spriteView presentScene:scene];
}
Теперь я могу продолжать разработку игр без особого беспокойства.
Я реализовал ваш код, и все работает как шарм. Установите точку останова на линии:
[self.delegate closeScene];
чтобы увидеть, если это будет вызвано.