Arduboyで麻雀ゲーム作る話(1)

Arduinoに小さいディスプレイと十字+ABボタンつけた製品?があります。 その名もArduboy

どっかで会うてなかったかワレ?
名刺より小さいですね!
UE/Unity用モデル制作や各種プログラム制作など雑多にやってる弊社もよろしくお願いします
昔、キックスターターで購入して、ちょっと遊んで打ち捨ててあったのですが、これが持ち歩くのにちょうど良くて、仕事部屋でもダイニングでも出張先でもArduinoプログラムができてしまう優れものだと気が付きました。
どこでも開発できちゃうぜ!ヒャッハー

んじゃ、なんか作るか (←いつもどおり手段と目的を履き違えている)
それにしても小さいディスプレイ(1.3インチOLED 128x64)やの、ワレ
せや!この狭いとこに小さい牌を並べたら絶対ワシらの老眼では見えへんやろ!
ジジィ発見器に使えるし、麻雀作ったろ!

という軽いノリから作ることにして、ちょっとどこまで作りきれるかわかりませんが、できるところまでやってみようかと思っています。

イメージの準備

麻雀といえば和了に14枚の牌が必要1なので、横128ドットの液晶に並べるとすると最大幅で横9ドットになります。 牌と牌の間には仕切り線が欲しいので、中身は横8ドットで描くことになります。 高さはちょっと余裕があるので11ドットで描きます。
ドット絵作成は便利なサイトがあったので、こちらを使いました。
ミニドット絵メーカー3

またイメージはプログラム中に持つことになるので、Cの配列形式になっていると都合が良いです。 これまたArduboyに特化した便利なページがあったので、使わせてもらいました。
Image Converter

通常、ゲームに必要な麻雀牌は

  • 萬子1~9
  • 筒子1~9
  • 索子1~9
  • 風牌(東南西北)
  • 三元牌(白發中)

の34種類2。 それに

  • 牌の外枠(10x15dot)

を作成しました。 githubにgifファイルと.hファイルをまとめた.zipを放り込んでおきました。

プログラム

せっかくデータを作ったので、早速表示してみます。
Arduboyの開発には専用のライブラリが必要なのでインストールします。
このあたりが詳しいです↓
Arduboy

とりあえず表示できれば良いので、setupにいろいろ書きます。

void setup() {
  // initiate arduboy instance
  arduboy.begin();

  // here we set the framerate to 10, we do not need to run at
  // default 60 and it saves us battery life
  arduboy.setFrameRate(10);

  //   arduboy.clear();
  arduboy.fillRect(0, 0, 128, 64);
  for (int i = 0; i < 9; i++) {
    arduboy.drawBitmap(i * 9, 0, img_back, 10, 15, BLACK);
    arduboy.drawBitmap(i * 9 + 1, 2, &img_manzi[i * 16], 8, 11, BLACK);
  }
  for (int i = 0; i < 9; i++) {
    arduboy.drawBitmap(i * 9, 14, img_back, 10, 15, BLACK);
    arduboy.drawBitmap(i * 9 + 1, 16, &img_manzi[(i+9) * 16], 8, 11, BLACK);
  }
  for (int i = 0; i < 9; i++) {
    arduboy.drawBitmap(i * 9, 28, img_back, 10, 15, BLACK);
    arduboy.drawBitmap(i * 9 + 1, 30, &img_manzi[(i+18) * 16], 8, 11, BLACK);
  }

  for (int i = 0; i < 4; i++) {
    arduboy.drawBitmap(128 - 36 + i * 9, 0, img_back, 10, 15, BLACK);
    arduboy.drawBitmap(128 - 35 + i * 9, 2, &img_manzi[(i+27) * 16], 8, 11, BLACK);
  }
  for (int i = 0; i < 3; i++) {
    arduboy.drawBitmap(128 - 36 + i * 9, 14, img_back, 10, 15, BLACK);
    arduboy.drawBitmap(128 - 35 + i * 9, 16, &img_manzi[(i+31) * 16], 8, 11, BLACK);
  }
  arduboy.display();
}

なお、

  • img_backが牌の外形のイメージ
  • img_manziが牌の中身イメージの配列(manziといいながら筒子から索子から何から全部突っ込んであります)

になります。
ちなみに8×11のイメージで16バイト使っているようです。11バイトでいいように思うんですが、なぜでしょう?
とりあえず動けば良いので、あんまり突っ込んで調べていません^^;(←キモい顔文字)

出力イメージはこちら↓

なお、Arduboyは本来白黒反転液晶なので、何もしないと黒バックに白文字になります。 個人的に見づらくてかなわんので、わざと白黒を逆転させています。

俺は黒白が好きだぜ!という人はソースコード

arduboy.fillRect(0, 0, 128, 64);

arduboy.clear();
に(いまコメントアウトされてますね)、
また
arduboy.drawBitmap(ほにゃらら, BLACK);
となっているところを
arduboy.drawBitmap(ほにゃらら);
にしてあげてください(,BLACKを削除する)。

次回、テンパイかどうかの判定ロジック(の前段階)を組みます。 というか、ここまではもう組んでいるのでアップするだけです!
その後はまだこれからなので、ぼちぼちやろうと思っています。
※解説なんかいらねーぜ!いま見せろって方は、上の表示部分含めてgithubにmajan.inoがあります。


  1. とりあえず槓子は後で考えます!

  2. 赤5・花牌は考えません!