我在Objective C for Mac OS中使用SpriteKit。在使用NSNotification时,我是一个菜鸟,但我在另一个我正在研究的应用程序中使用了以下方法,但它现在无法正常工作。也许有更好的方法,但我希望能够根据应用程序的状态捕获按键。
州开始于GameBeginState
。按下空格键后,它将移至GamePlayState
。如果我按任何其他键,则表明它使用keyPressed:
中的GameBeginState
方法,而不是keyPressed
中的GamePlayState
方法。有什么想法吗?我无法想象我的生活。
我创建了一个名为CustomNotificationHandler
的自定义视图,并在项目中设置了我的主SKView
。
以下是CustomNotificationHandler
的代码:
#import "CustomNotificationHandler.h"
@implementation CustomNotificationHandler: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 {
[[NSNotificationCenter defaultCenter] postNotificationName:@"KeyPressedNotificationKey"
object:nil
userInfo:@{@"keyCode" : @(theEvent.keyCode)}];
}
@end
在我的主要课程GameScene
中,我设置了GKStateMachine
初始化3个州。各州的课程如下:
#import "GameReadyState.h"
#import "GamePlayState.h"
@interface GameReadyState()
@property (weak) GameScene *scene;
@end
@implementation GameReadyState
-(instancetype) initWithScene:(GameScene*)scene {
if (self = [super init]) {
self.scene = scene;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name:@"KeyPressedNotificationKey" object:nil];
}
return self;
}
-(void) didEnterWithPreviousState:(GKState *)previousState {
}
-(void) willExitWithNextState:(GKState *)nextState {
}
-(BOOL) isValidNextState:(Class)stateClass {
return stateClass == [GamePlayState class];
}
-(void)keyPressed:(NSNotification*)notification {
NSNumber *keyCodeObject = notification.userInfo[@"keyCode"];
NSInteger keyCode = keyCodeObject.integerValue;
NSLog(@"GAME READY key = %ld", (long)keyCode);
switch (keyCode) {
case 49:
[self.stateMachine enterState:[GamePlayState class]];
break;
default:
break;
}
}
@end
这是第二个状态......与第一个状态几乎相同:
#import "GamePlayState.h"
#import "GamePauseState.h"
@interface GamePlayState()
@property (weak) GameScene *scene;
@end
@implementation GamePlayState
-(instancetype) initWithScene:(GameScene*)scene {
if (self = [super init]) {
self.scene = scene;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyPressed:) name:@"KeyPressedNotificationKey" object:nil];
}
return self;
}
-(void) didEnterWithPreviousState:(GKState *)previousState {
[_scene setPaused:NO];
}
-(BOOL) isValidNextState:(Class)stateClass {
return stateClass == [GamePauseState class];
}
-(void) updateWithDeltaTime:(NSTimeInterval)seconds {
[_scene.sequence moveLeft];
}
-(void)keyPressed:(NSNotification*)notification {
NSNumber *keyCodeObject = notification.userInfo[@"keyCode"];
NSInteger keyCode = keyCodeObject.integerValue;
NSLog(@"GAME PLAY key = %ld", (long)keyCode);
switch (keyCode) {
case 53:
[self.stateMachine enterState:[GamePauseState class]];
[_scene setPaused:YES];
break;
default:
break;
}
}
@end