読者です 読者をやめる 読者になる 読者になる

つらねの日記

プログラムの進捗やゲームをプレイした感想などを書き連ねる日記。

KeyClass

前書き

Processingでキーボードを用いて操作するゲームを開発していると、キーが押された瞬間や押されている時間、離された瞬間などが取得したくなる。しかもデフォルトのkeyCodeを使っていると一つしかキーが取れず、不便だ。したがってそうした問題を解決するためにクラスを作ったのを発見し、それを改良した。

KeyClass

Key.pde
public static class Key {
  private static int pressTime[] = null;

  public static void setApplet(PApplet applet) {
    pressTime = new int[Character.MAX_VALUE];

    applet.addKeyListener(new java.awt.event.KeyAdapter() {

      @Override
        public void keyPressed(java.awt.event.KeyEvent e) {
        if (pressTime[e.getKeyCode()] <= 0)
          pressTime[e.getKeyCode()] = 1;
      }

      @Override
        public void keyReleased(java.awt.event.KeyEvent e) {
        pressTime[e.getKeyCode()] = -1;
      }
    }
    );

  }

  public static int get(int code) {
    return pressTime[code];
  }
  public static boolean pressed(int code) {
    return get(code)==1;
  }
  public static boolean released(int code) {
    return get(code)==-1;
  }
  public static boolean pushed(int code, int n, int m) {
    return get(code)>=n&&get(code)%m==0;
  }

  public static void update() {
    for (int i=0; i<pressTime.length; i++)
      pressTime[i]+=pressTime[i]!=0?1:0;
  }
}

新しい変数を定義することを避けたかったため、staticに扱えるものを作成した。
setAppletはこのclassを使うための準備にあたるもので、KeyListenerの追加を行っている。これがいわゆる、他のものでいうところのgetInstanceやコンストラクタにあたるだろう。この処理を呼ばないとNullPointerExceptionが出る。
getはキーが押されているフレーム数を返し、pressedは押された瞬間、releasedは離された瞬間返り値がtrueになる関数である。pushedは多少特殊で一定時間以上たった後で一定時間ごとにtrueになる関数である。
updateがその名の通りキーの押されたフレームを更新するための関数で、pressed以外を正常に使用するためにはメインプログラムの方のdraw内部のどこかで呼ぶ必要がある。

使い方

使い方の簡単な例を下に示そう。
Zが押されているフレーム数を描画し、Xが押された瞬間のフレーム数を出力し、SHIFTが押された時には右下を黒く塗りつぶし、C押されて一定時間ごとに背景をあおく染めるサンプルである。

HowToUse.pde
void setup() {
  Key.setApplet(this);
}

void draw() {
  background(255);
  fill(0);
  if (Key.pushed('C', 50, 20))
    background(#aaaaff);
  if (Key.get(SHIFT)>0)
    rect(width/2, height/2, width/2, height/2);

  if (Key.pressed('X'))
    println("X:"+frameCount);
  text(Key.get('Z'), width/2, height/2);

  Key.update();
}