ハンドヘルドデバイスでもゲームを動かそう

最近は、Arduino 1 を代表とするワンボードマイコンをコアとし、それにディスプレイやボタンを追加したハンドヘルドゲーム機を DIY で作るというトレンドがある。自分好みのゲーム機を自由に作れるのが利点である一方、様々なデバイスが乱立してしまい、多くの人が持っている共通のデバイスというものはあまり無い。

これらのデバイスで動作するためのゲームは、C 言語で書かれることが多い。そのため、付随するライブラリも C 言語で実装する必要がある。

今回、私はブラウザ向けに JavaScript (TypeScript)で実装した自作ライブラリを C 言語に移植した。名前を crisp-game-lib-portable 2 という。

PyBadge crisp-game-lib-portable screenshot

crisp-game-lib-portable で作ったゲームは、M5StickC PLUS 3 や Adafruit PyBadge 4 などで動く。また、Emscripten 5 を活用することで、ブラウザ上でも遊べるようになった。

また、ライブラリ本体 6 とゲームのコード 7 はブラウザを含むすべてのデバイス向けで共通、デバイス向けには最小限の個別コードを書けば対応できる、というのを目指している。

デバイス個別コードで書く必要がある処理は、

  • デバイスの初期化処理(Arduino ならsetup())とそこからのinitGame()の呼び出し。
  • フレームの更新処理(Arduino ならloop())とそこからのsetButtonState()呼び出しによるボタン状態の通知とupdateFrame()の呼び出し。
  • machineDependent.h 8 で定義された描画や音周りの処理。

だけである。そのため、一般的なデバイスで固有に必要な実装は 250 行程度だ。

音回りの実装はmd_playTone(float freq, float duration, float when)で特定の周波数を、特定の期間、特定の開始時間で鳴らすことを要求している。デバイスごとにこれに対応することが、多少面倒かもしれない。PyBadge のようなブザー音量がanalogWrite()で設定できる機能しか無いデバイスだと、音のタイミング管理をしつつ、矩形波を自力で生成しないといけない。

md_drawCharacter(unsigned char grid[CHARACTER_HEIGHT][CHARACTER_WIDTH][3], float x, float y, int hash)でドット絵を表示する機能も、少し手間がかかる。最後にハッシュ値が付いているのは、毎回ドット絵のパターン定義をパース・描画するのではなくて、ハッシュ値でキャッシュしておいてそれを使う実装を想定している。LovyanGFX ライブラリ 9 を使って描画しているならば、LGFX_Spriteとハッシュ値をペアで保存しておいて、それを取り出してpushSprite()すれば良い。

こういった移植性を考えながらコードを書くことは、色々なデバイスを相手にしたライブラリでないとできないことなので、なかなか楽しい経験ではある。あまたあるマイコンボードに対して、Arduino IDE などの共通な開発環境、Adafruit Arcada 10 や LovyanGFX などの多デバイス対応ライブラリを駆使しつつ独自のゲームライブラリを作るのは、PC やスマホをターゲットとしたゲームライブラリとはまた違った面白さがある。興味があれば試していただきたい。


1. Arduino
2. crisp-game-lib-portable
3. M5StickC PLUS
4. Adafruit PyBadge
5. Emscripten
6. crisp-game-lib-portable src/lib
7. crisp-game-lib-portable src/games
8. machineDependent.h
9. LovyanGFX
10. Adafruit Arcada

results matching ""

    No results matching ""