如何在SpriteKit游戏中获得键盘输入?

时间:2014-04-13 23:38:15

标签: objective-c macos sprite-kit

我是SpriteKit编程的初学者,并且一直试图弄清楚如何处理来自键盘的输入。

到目前为止,我发现你应该继承NSResponder并实现它:

@interface AppDelegate : NSResponder <NSApplicationDelegate>
-(void)keyUp:(NSEvent *)theEvent;
-(void)keyDown:(NSEvent *)theEvent;
@end

@implementation AppDelegate
-(void)keyUp:(NSEvent *)theEvent
{
   NSLog(@"Key Released");
}
-(void)keyDown:(NSEvent *)theEvent
{
  NSLog(@"Key Pressed");
}
@end

显然,在AppDelegate的界面和实现中还有一些方法/属性,但我没有把它们放在那里以保持问题的相关性。

接下来,我将开始使用键代码来检测正在按下哪些键,但keyUpkeyDown方法甚至不会被调用。我不确定为什么。

任何帮助?

更新 谢谢你的回答!我发现你必须直接在你的场景类中实现keyUpkeyDown,因为他们不会从AppDelegate调用。再次感谢您的帮助!

4 个答案:

答案 0 :(得分:11)

我知道最简单的方法是在SKScene中实现keyDown方法(而不是直接在AppDelegate中)。您不必将任何子类化。

- (void)keyDown:(NSEvent *)event {
    [self handleKeyEvent:event keyDown:YES];
}

- (void)keyUp:(NSEvent *)event {
    [self handleKeyEvent:event keyDown:NO];
}

然后使用方法handleKeyEvent:(NSEvent *)event keyDown:(BOOL)downOrUp检查按下了哪个键:

- (void)handleKeyEvent:(NSEvent *)event keyDown:(BOOL)downOrUp {
    // First check the arrow keys since they are on the numeric keypad.
    if ([event modifierFlags] & NSNumericPadKeyMask) { // arrow keys have this mask
        NSString *theArrow = [event charactersIgnoringModifiers];
        unichar keyChar = 0;
        if ([theArrow length] == 1) {
            keyChar = [theArrow characterAtIndex:0];
            switch (keyChar) {
                case NSUpArrowFunctionKey:
                    self.defaultPlayer.moveForward = downOrUp;
                    break;
                case NSLeftArrowFunctionKey:
                    self.defaultPlayer.moveLeft = downOrUp;
                    break;
                case NSRightArrowFunctionKey:
                    self.defaultPlayer.moveRight = downOrUp;
                    break;
                case NSDownArrowFunctionKey:
                    self.defaultPlayer.moveBack = downOrUp;
                    break;
            }
        }
    }

    // Now check the rest of the keyboard
    NSString *characters = [event characters];
    for (int s = 0; s<[characters length]; s++) {
        unichar character = [characters characterAtIndex:s];
        switch (character) {
            case 'w':
                self.defaultPlayer.moveForward = downOrUp;
                break;
            case 'a':
                self.defaultPlayer.moveLeft = downOrUp;
                break;
            case 'd':
                self.defaultPlayer.moveRight = downOrUp;
                break;
            case 's':
                self.defaultPlayer.moveBack = downOrUp;
                break;
            case ' ':
                self.defaultPlayer.fireAction = downOrUp;
                break;
        }
    }
}

我从Apple SpriteKit Adventure游戏中获取此代码。我发现学习SpriteKit非常有用:)

答案 1 :(得分:5)

Swift(2.0)版本的HeyFara的答案。我刚刚突然出现了#34;休息&#34;在哪里你可以进行实际的函数调用。

    public override func keyDown(theEvent: NSEvent) {
    handleKeyEvent(theEvent, keyDown: true)
}

public override func keyUp(theEvent: NSEvent) {
    handleKeyEvent(theEvent, keyDown: false)
}

public func handleKeyEvent(event:NSEvent, keyDown:Bool){
    if event.modifierFlags.contains(NSEventModifierFlags.NumericPadKeyMask){
        if let theArrow = event.charactersIgnoringModifiers, keyChar = theArrow.unicodeScalars.first?.value{
            switch Int(keyChar){
            case NSUpArrowFunctionKey:
                break
            case NSDownArrowFunctionKey:
                break
            case NSRightArrowFunctionKey:
                break
            case NSLeftArrowFunctionKey:
                break
            default:
                break
            }
        }
    } else {
        if let characters = event.characters{
            for character in characters.characters{
                switch(character){
                case "w":
                    break
                default:
                    print(character)
                }
            }
        }
    }
}

答案 2 :(得分:0)

如果您想知道何时按下某个键,您应该订阅全局事件管理器。

[NSEvent addGlobalMonitorForEventsMatchingMask:(NSKeyDownMask) handler:^(NSEvent *event) {
[NSEvent removeMonitor:event];

这将在按下某个键时调用处理程序。

答案 3 :(得分:0)

这是HeyFara回答的rougeExciter版本,但在Swift 4.2中...以防万一有人在几分钟前找到这个旧帖子...):

public override func keyDown(with event: NSEvent) {
    handleKeyEvent(event, keyDown: true)
}

public override func keyUp(with event: NSEvent) {
    handleKeyEvent(event, keyDown: false)
}

public func handleKeyEvent(_ event: NSEvent, keyDown: Bool){
    if event.modifierFlags.contains(NSEvent.ModifierFlags.numericPad) {
        if let theArrow = event.charactersIgnoringModifiers, let keyChar = theArrow.unicodeScalars.first?.value{
            switch Int(keyChar){
            case NSUpArrowFunctionKey:
                break
            case NSDownArrowFunctionKey:
                break
            case NSRightArrowFunctionKey:
                break
            case NSLeftArrowFunctionKey:
                break
            default:
                break
            }
        }
    } else {
        if let characters = event.characters{
            for character in characters {
                switch(character){
                case "w":
                    break
                default:
                    print(character)
                }
            }
        }
    }
}