【问题标题】:Global key handler for SpriteKit GameSpriteKit 游戏的全局密钥处理程序
【发布时间】:2015-07-08 06:25:08
【问题描述】:

我目前在各种 SKScene 课程中都有我所有的按键代码。我只希望每次按下键时都会发生一些事情。需要重新触发该键才能再次执行该操作。我正在使用布尔数组来跟踪这一点。这可能不是最优的,但这是我当时的想法。我希望创建一个类来管理所有这些,但关键事件方法 keyUp 和 keyDown 是在 SKScene 类中创建的。是否有一种全局方式来处理按键操作,这样我就不必在游戏中的每个场景中重新创建此代码?

【问题讨论】:

  • 带有 NSNotifications 的单例。
  • 当一个键被按下时你想发生什么?您想在当前场景中调用一个方法(例如 GameScene)还是只想从每个场景中访问该布尔数组?
  • 目前这主要用于菜单项的选择。例如,当用户按下时,指示器应移至下一个菜单项。

标签: objective-c macos sprite-kit keyboard-events


【解决方案1】:

您可以继承SKView 并在一个集中位置执行所有按键处理。这种方法有几个好处:1. 由于所有按键逻辑都在一个类中,因此对逻辑的更改是针对该类而不是在所有场景中进行的;2) 它从多个场景中删除了特定于设备的输入逻辑。例如,如果您决定将应用移植到 iOS,您只需将界面从键盘/鼠标更改为单个文件中的触摸即可。

以下是SKView 的自定义子类中按​​键处理程序的实现。它使用协议/委托设计模式将按键消息发送到各种场景。委托是对象(在本例中为类)与其他类通信的一种便捷方式,协议定义了这种通信将如何进行。

  1. 创建 SKView 的子类

CustomSKView.h

@protocol KeyPressedDelegate;

@interface CustomSKView : SKView

@property (weak) id <KeyPressedDelegate> delegate;

@end

@protocol KeyPressedDelegate

- (void) upArrowPressed;
- (void) downArrowPressed;

@end

CustomSKView.m

所有按键处理逻辑都驻留在此处。如何处理按键的详细信息对按键操作的代码是隐藏的。

@implementation CustomSKView:SKView {
    // Add instance variables here
}

// This is called when the view is created.
- (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:
                [self.delegate upArrowPressed];
                break;
            case 125:
                [self.delegate downArrowPressed];
                break;
            default:
                break;
        }
    }
}

@end
  1. 采用协议

GameScene.h

#import "CustomSKView.h"

@interface GameScene : SKScene <KeyPressedDelegate>

@end
  1. 在所有需要按键信息的场景中实现委托方法

GameScene.m

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    ((CustomSKView *)view).delegate = self;
}

- (void) upArrowPressed {
    NSLog(@"Up Arrow Pressed");
}
- (void) downArrowPressed {
    NSLog(@"Down Arrow Pressed");
}

@end
  1. 在主 .xib 文件中,将 SKView 的类设置为自定义类:

【讨论】:

  • 我对协议/委托部分有点困惑。我用作子类的类是单例吗?
  • 是的,CustomSKView 类是单例。您可以在该类中添加所有按键处理逻辑,并根据按下的键调用适当的委托方法(请参阅我刚刚添加的 upArrowPresseddownArrowPressed 方法)。
  • 既然GameScene.m 无论如何都必须创建和实现这些方法,那么与我之前使用的keyUpkeyDown 方法有什么区别?就像我之前说的,我不太清楚代表/协议的全部意义,我想我错过了你所解释的大部分内容。
  • 我在回答中添加了对代表和协议的描述。
  • 谢谢,这很有帮助!我已经将它作为一个测试项目运行,现在我正在整合我实际项目所需的功能。对于您说“在此处添加实例变量”的部分,我从未见过像这样使用的类的 @implementation 部分。我通常在@interface 部分或.h 文件中声明它们。如何初始化它们?
【解决方案2】:

我建议使用单例模式来存储和获取您的密钥。因为您可以从您的 SKScene 访问,而不是随时创建或更新。

http://www.galloway.me.uk/tutorials/singleton-classes/ 这个单例介绍又快又短。

【讨论】:

  • 是的,无论如何我都会这样做。我现在有几个单例类,用于游戏数据等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多