SpriteKit Keyboard Observer

I am currently using delegation and a custom SKView class to control keystrokes in my OS X SpriteKit game. I need to use multiple delegates for my keyboard control class, which I know is not possible, but it is possible with observers. How can I do that? Here's my code using the delegation pattern:

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

      

+3


source to share


1 answer


You are looking for NSNotificationCenter

. To add an object as an observer, use the following:

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

      

This causes the object to watch for named notifications @"KeyPressedNotificationKey"

. To send a notification with this name and attach the keyCode to the key pressed, call this:

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

      



When you post a notification, any observers will call the method associated with the observer. You can get the keyCode from the dictionary userInfo

you attached when you sent the notification. In this case, the method with this signature will be called:

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

      

There is one catch. You need to remove the object as an observer as soon as it happens by observing. If you delete the object without removing the observer, then post a notification, it will still try to call a method on a non-existent object and fail. Use the following code to remove an object as an observer:

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

      

+2


source







All Articles