Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 1 year has passed since last update.

コナミコマンド

Last updated at Posted at 2022-02-23

押されたキーと順番を監視する

サンプル.js
// コナミコマンド
let order = 0;
const command = ['ArrowUp', 'ArrowDown', 'ArrowUp', 'ArrowDown'
, 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
document.onkeydown = e => {
  if (order == 0) {
    // 初回キー押下から3秒間, 入力を受け付ける
    setTimeout(() => order = 0, 3000);
  }
  order = e.key == command[order]
    ? (order + 1) | 0
    : 0;
  // 成功時
  if (order == command.length) {
    console.log('おけ');
  order = 0;
  }
};

解説

押されたキーを取得

押されたキーを取得.js
document.onkeydown = e => {}

MDN解説
e.keyで、押されたキーの名前が取れます。
aとかbとか、矢印ならArrowUpとかになります。
全量はMDNで調べるか、実際にやってみてください。

これをdevtoolのconsoleとかに入れて調べる.js
document.onkeydown = e => console.log(e.key)

順番を見る

コナミコマンドは、「↑↓↑↓←→←→BA」の順に押すこと。なので順番が大事。

0番目に↑を押されて
1番目に↓を押されたら成功だが

0番目に↑を押されて
1番目にBを押されたら失敗とみなすので、以降何を押されても無視する。

onkeydownイベント自体はどのキーを押されても発動しちゃうので
今何番目かと、今何を押されるべきかを縛ってあげよう

順番を見る.js
let order = 0;
document.onkeydown = e => {
  if (order == 0) {
    if (e.key == 'ArrowUp') {
      // 0番目に↑を押された
      order = 1;
    }
  }
  if (order == 1) {
    if (e.key == 'ArrowDown') {
      // 1番目に↓を押された
      order = 2;
    }
  }
  ...
};

これを、「順番」は「配列のindex」として扱ってあげると、ソースがきれいになる。

サンプル.js
let order = 0;
const command = ['ArrowUp', 'ArrowDown', 'ArrowUp', 'ArrowDown'
, 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
document.onkeydown = e => {
  // 押されたキーが、順番に対応していればorderを1追加する
  if (e.key == command[order]) {
    order = order + 1;
  }
  // 成功時
  if (order == command.length) {
    console.log('おけ');
    order = 0;
  }
};

ロジック部分から固有値がきえた。外部化していろんなコマンドつくれるね!

入力受付時間を決めて失敗時対策, 成功時にorderをリセット

サンプル.js
let order = 0;
const command = ['ArrowUp', 'ArrowDown', 'ArrowUp', 'ArrowDown'
, 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
document.onkeydown = e => {
  if (order == 0) {
    // 初回キー押下から3秒間, 入力を受け付ける
    // なので3秒間以内の入力でないとだめにする
    setTimeout(() => order = 0, 3000);
  }
  if (e.key == command[order]) {
    order = order + 1;
  } else {
    // 失敗時はすぐリトライできるようにorderをリセット
    order = 0;
  }
  // 成功時
  if (order == command.length) {
    console.log('おけ');
  order = 0; 
    // ここで0にリセットしないと、コマンド完了したあと何かキー押したらここ通る
  }
};

コマンド配列と、入力受付時間を外部ファイルとかに出せば、同じロジックで複数コマンドできる。
でまぁif文のとこを三項演算子にしたらこう

.js
  order = e.key == command[order]
    ? (order + 1) | 0
    : 0;

ifのが処理はちょっと早いらしいが、個人的には三項演算子好き

余談 処理速度

数値を1追加するときの処理速度なんですけど
cnt++みたいな書き方より、
cnt = cnt + 1;
こっちのほうがよいそうです。(場合によるかも、専門サイトみてね)
で、型を認識させる裏技として

|0を後ろにつけると、数値型だよ!って意味らしい。ので

cnt = (cnt + 1) | 0;

とりあえず脳死でこれ書いとけばよさそう。精通してます感あってカッコイイ
(一瞬読みにくいけど。。)

0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?