SpriteKit 键盘观察器

SpriteKit Keyboard Observer

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

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

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

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

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

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

当你post通知时,任何观察者都会调用与观察者关联的方法。您可以从 post 编辑通知时附加的 userInfo 词典中获取密钥代码。在这种情况下,将调用具有此签名的方法:

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

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

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