あざらし備忘録。

音ゲー好きなウェッブエンジニアがいろいろ思った事やった事を書いていくブログです

ターミナルで遊べる音ゲー作ってみた

この記事はVOYAGE GROUP エンジニアブログ Advent Calendar 2014の12日目の記事です!

こんにちは!@gomachan46です。

VOYAGE GROUPの新卒エンジニアとして日々楽しみながらお仕事しております。

社内にて密かに活動を続けている音ゲー部の部長をやっております!

少し前にVOYAGE GROUP エンジニアブログ : あなたにおすすめするたった一つの最高のキーボードとかいうエントリを上げたところ、社外の方からも「音ゲーの人だよね?」とわかってもらえるようになりました。

さて、今回はちょっとした休憩中でもさっとお仕事をしていると見せかけて「ターミナルでプレイできる音ゲー」を作ってみようと思います!

もちろんこの間紹介したキーボードでもプレイ可能です:)

音ゲーとは

簡単にいうとリズムに合せて作成された譜面の通りにボタンを押して遊ぶゲームです。

f:id:shiro_goma:20141212053111p:plain

作ってみる

今回作るのに使ったものはざっと以下の通りです。

  • Burn
  • afplay
  • Karabiner

Burnとは

remore/burn · GitHub

8bit風なゲームをRubyで簡単に作ることができるようになるフレームワークです!

Rubyist Magazine - 8-bit風ゲームをつくるフレームワークburnの紹介 こちらを読んでいただけるとどんなものかわかるかと思います。

このBurnは以下の2種類の方式で8bitゲームを作成することができます。

  • :rom mode ROMを作成してブラウザにてゲームを楽しめるようになります。
  • :telnet mode telnetによってターミナルにてゲームを楽しめるようになります。

今回は何が何でも「ターミナルで音ゲーがしたい!」ので、後者の:telnet modeで実装をしました。

afplayとは

Mac OSにデフォルトで入っている音楽再生コマンドです。

Burnの:telnet modeだとどうにも上手く音声が再生されなさそうなので、今回はこちらのafplayコマンドを併用して音ゲーを作ってみました。

demo

こんな感じです!(音楽は諸々を考えて無しにしました)

ターミナルでプレイできる音ゲー作ってみた - YouTube

これはターミナルですよ〜telnetですよ〜←

プレイに当たって困ったこと

telnetなのでEnterを押さないとユーザのキーボード入力が送信されない

ユーザのキーボード入力を有効にしなければ音ゲーができないので、有効にするのですが、telnetなので情報を送信するためには「送信したいキー+Enter」を押さないと送信したいキーの情報が送信できません。

これでは4分のリズムでも8分で叩かなきゃいけないという鬼畜な感じになってしまいます。

そこで、Karabinerを用いて特定のキーのみ「押された直後にEnterを押す」設定を施しました。

Karabinerでは独自のキー設定に際してはprivate.xmlというファイルを編集する必要があるのですが、以下のようにしました。

<?xml version="1.0"?>
<root>
  <item>
    <name>otoge_burn</name>
    <identifier>private.otoge_burn</identifier>
    <block>
      <autogen>
        __KeyToKey__
        KeyCode::Q,
        KeyCode::Q,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::D,
        KeyCode::D,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::R,
        KeyCode::R,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::F,
        KeyCode::F,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::U,
        KeyCode::U,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::J,
        KeyCode::J,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::I,
        KeyCode::I,KeyCode::RETURN
      </autogen>
      <autogen>
        __KeyToKey__
        KeyCode::K,
        KeyCode::K,KeyCode::RETURN
      </autogen>
    </block>
  </item>
</root>

これでキーを押すだけで送信できるという状態を擬似的に作ることができ、快適なプレイになりました!

音ズレ

やはり最後まで悩まされたのが処理落ちによる音ズレで、機構としてひたすらBurnを用いた音ゲー関連の処理を1フレーム毎処理を行いつつ、別プロセスでただafplayを実行しているだけなので、Burn側が少しでも重くなるとだんだんとずれていきます。つらいw

まとめ

ソースは闇を抱えていますがこちら

ターミナルでやろうとすると恐ろしく制約が入りますが、やっぱり夢があって楽しい!✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌

とりあえずターミナルの割にヌルヌル動いてくれたので大満足です。

この調子で色々夢のあることをやれたらいいなぁと思っています!

明日は新卒研修時にもお世話になった@TachibanaKaoruです!楽しみですね!