Reputation: 1792
I have currently been using delegation and an SKView custom class to monitor key presses in my OS X SpriteKit game. I need to employ multiple delegates for my keyboard monitoring class, which I know is not possible, but it is possible through using observers. How can this be accomplished? 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
Upvotes: 3
Views: 302
Reputation: 10060
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 that object to observe notifications with the name @"KeyPressedNotificationKey"
. To post a notification with that name and attach the keyCode for the key that was pressed, call this:
[[NSNotificationCenter defaultCenter] postNotificationName:@"KeyPressedNotificationKey"
object:nil
userInfo:@{@"keyCode" : @(event.keyCode)];
When you post the notification, any observers will call the method associated with the observer. You can get the keyCode from the userInfo
dictionary you attached when you posted 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 to this. You need to remove the object as an observer as soon as it is done observing. If you deallocate an object without removing the observer, then post the notification, it'll still try to call the method on your non-existent object and crash. Use the following code to remove the object as an observer:
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"NotificationNameKey"
object:nil];
Upvotes: 3