LoginSignup
5
7

More than 5 years have passed since last update.

RxJSとkeypressを使いfpsフレーム内で1キーだけ受け付ける処理

Last updated at Posted at 2015-08-19

ゴール

Node.js で RxJSkeypress を使い、「fps の 1 フレーム内で先頭の 1 キー入力のみを受け付ける」という処理を作ること。

サンプルコード

var keypress = require('keypress');
var Rx = require('rx');

var FPS = 2;

keypress(process.stdin);
process.stdin.setRawMode(true);
process.stdin.resume();

var pauser = new Rx.Subject();

var timerSource = Rx.Observable
  .timer(0, 1000 / FPS)
  .timeInterval()
  .map(function(data) {
    pauser.onNext(true);
    return data;
  })
;

var wrappedHandler;
var keypressSource = Rx.Observable
  .fromEventPattern(
    function addHandler(handler) {
      wrappedHandler = function(chr, key) {
        handler(key);
      };
      process.stdin.addListener('keypress', wrappedHandler);
    },
    function removeHandelr(handler) {
      process.stdin.removeListener('keypress', wrappedHandler);
    }
  )
  .pausable(pauser)
  .filter(function() {
    var isStopped = pauser.isStopped;
    pauser.onNext(false);
    return !isStopped;
  })
;

timerSource.subscribe(
  function(data) {
    console.log('Frame count:', data.value);
  }
);

keypressSource.subscribe(
  function (key) {
    console.log('Input key:', key.name);
    if (key && key.ctrl && key.name === "c") {
      process.stdin.pause();
      process.exit(0);
    }
  }
);

node コマンドで実行して適当にキーを連打すると、以下の様な出力になると思います:

$node ./filename.js
Frame count: 0
Input key: j
Frame count: 1
Input key: j
Frame count: 2
Frame count: 3
Input key: n
Frame count: 4
Input key: n
Frame count: 5
Input key: k
Frame count: 6
Input key: k
Frame count: 7
Input key: k
Frame count: 8
Frame count: 9
Frame count: 10
Input key: c

同フレーム内で、2回以上のキー受付をしていないことがわかると思います。
なお、抜けるには Ctrl-C を押して下さい。

参考リンク

所感

  • 元々はゲーム的な入力受付を作りたいという趣旨でしたが、おそらく実際は、例えば格闘ゲームであれば先行入力などの仕様もあるため、こんなに単純ではないとは思います。
  • pausable によるフラグ管理ではなくて、それを一発で解決してくれる operator がありそうな予感もしたのですが、自分には見つけることができませんでした。
5
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7