1

我有两个 UIViewControllers。用户从UIViewController开始。然后用户点击一个按钮来玩游戏。因此应用程序继续切换到另一个视图控制器PlayViewController ,它显示了使用SKView进行的游戏。而ActionScene是负责游戏玩法的SKScene子类。当用户失败时,应用程序会显示一个标签(SKLabelNode)并询问他或她是否想退出游戏。如果用户点击这个标签,玩家将通过 PlayViewController 回到主视图控制器(UIViewController)。所以我认为 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
}

所以当用户点击 done 标签时,closeScene 被设计为启动。但是这个委托方法永远不会被调用。在过去的 9 个月里,我没有开发过 iOS 应用程序。但我认为我的想法是正确的。我究竟做错了什么?到目前为止,我已经阅读了这个主题这个主题和其他主题。

感谢您的帮助。

// 补充说明 //

  1. 在用户点击 doneLabel 之前,所有操作都会被删除。
  2. 游戏应用程序将进入 touchBegan。然而,它会跳过 [spriteView presentScene:scene] 行。
4

2 回答 2

0

我实现了你的代码,一切都像一个魅力。在一行上设置断点:

[self.delegate closeScene];

看看它是否被调用。

于 2014-02-26T14:53:17.340 回答
0

参考这篇文章,我的绝望措施已经奏效。对 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];
}

现在,我可以毫无顾虑地全速进行游戏开发。

于 2014-02-27T00:02:23.883 回答