我是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
的界面和实现中还有一些方法/属性,但我没有把它们放在那里以保持问题的相关性。
接下来,我将开始使用键代码来检测正在按下哪些键,但keyUp
和keyDown
方法甚至不会被调用。我不确定为什么。
任何帮助?
更新
谢谢你的回答!我发现你必须直接在你的场景类中实现keyUp
和keyDown
,因为他们不会从AppDelegate调用。再次感谢您的帮助!
答案 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)
}
}
}
}
}