SpriteKit键盘观察器

时间:2015-07-15 15:20:41

标签: macos sprite-kit observer-pattern keyboard-events

我目前一直在使用委托和SKView自定义类来监控我的OS X SpriteKit游戏中的按键操作。我需要为我的键盘监控类使用多个委托,我知道这是不可能的,但是可以通过使用观察者来实现。如何实现这一目标?这是我使用委托模式的代码:

CustomSKView.h

#import <SpriteKit/SpriteKit.h>

@protocol KeyPressedDelegate;

@interface CustomSKView : SKView

@property (weak) id <KeyPressedDelegate> delegate;

@end

@protocol KeyPressedDelegate

- (void) upArrowPressed;
- (void) downArrowPressed;

@end

CustomSKView.m

#import "CustomSKView.h"

@implementation CustomSKView:SKView {
    // Add instance variables here

}

- (id) initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        // Allocate and initialize your instance variables here

    }
    return self;
}

- (void) keyDown:(NSEvent *)theEvent {
    // Add code to handle a key down event here
    if (self.delegate) {
        switch (theEvent.keyCode) {
            case 126: {
                NSLog(@"delegate = %@", [self delegate]);
                [self.delegate upArrowPressed];
                break;
            }
            case 125:
                [self.delegate downArrowPressed];
                break;
            default:
                break;
        }
    }
}

@end

GameScene.h

#import <SpriteKit/SpriteKit.h>
#import "CustomSKView.h"

@interface GameScene : SKScene <KeyPressedDelegate>

@end

GameScene.m

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    ((CustomSKView *)view).delegate = self;
}

- (void) upArrowPressed {
    NSLog(@"Up Arrow Pressed");
}
- (void) downArrowPressed {
    NSLog(@"Down Arrow Pressed");
}

@end

1 个答案:

答案 0 :(得分:2)

您正在寻找NSNotificationCenter。要将对象添加为观察者,请使用以下命令:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyPressed:)
                                             name:@"KeyPressedNotificationKey"
                                           object:nil];

这会导致该对象观察名称为@"KeyPressedNotificationKey"的通知。要发布具有该名称的通知并附加已按下的键的keyCode,请调用:

[[NSNotificationCenter defaultCenter] postNotificationName:@"KeyPressedNotificationKey"
                                                    object:nil
                                                  userInfo:@{@"keyCode" : @(event.keyCode)];

发布通知时,任何观察者都会调用与观察者关联的方法。您可以从发布通知时附加的userInfo字典中获取keyCode。在这种情况下,将使用具有此签名的方法调用:

- (void)keyPressed:(NSNotification *)notification
{
    NSNumber *keyCodeObject = notification.userInfo[@"keyCode"];
    NSInteger keyCode = keyCodeObject.integerValue;
    // Do your thing
}

这有一个问题。一旦完成观察,您需要以观察者的身份移除对象。如果在不删除观察者的情况下释放对象,然后发布通知,它仍然会尝试在不存在的对象上调用该方法并崩溃。使用以下代码以观察者的身份删除对象:

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:@"NotificationNameKey"
                                              object:nil];