CCCMKホールディングス TECH LABの Tech Blog

TECH LABのエンジニアが技術情報を発信しています

ブログタイトル

Raspberry PiとMinecraftでハッピー、バースデー!

こんにちは、技術開発の三浦です。みなさんはMinecraftというゲームをご存知でしょうか。ブロックで作られた世界を冒険したり、ブロックを積み上げて自分だけの建物を作ったりできる、子供にも人気があるゲームです。今年小学生になった娘も気になるようで、時々インターネットで熱心に動画を見ています。

さて、そんな娘が先日7歳の誕生日を迎えました。最近興味を持っているMinecraftに絡めた何か面白いことを誕生日のサプライズで出来ないかなぁと色々と考えた結果、Raspberry PiにインストールされているMinecraft Pi: Editionというゲームをベースにし、ちょっとしたサプライズの仕組みを作ってみましたので、今回紹介させていただきます!

配置イメージ

f:id:miu4930:20210811171455j:plain

手元にあるもので作ったので、もう少しスリム化、最適化出来る余地はあるかと思いますが、使ったものは以下です。

  • Raspberry Pi 3 Model B+  
    Raspberry Pi OSおよびMinecraft Pi: Editionをセットアップ済みのもの。
  • LEDテープ(WS2812B)  
    上の写真のカラフルな箱の中に仕込んでいます。
  • ディスプレイ・キーボード・マウス
  • その他ジャンパケーブル・ダンボールなど

配置が済んだからラズパイではMinecraft Pi: Editionと、後述するPythonのプログラムを実行しておきます。

サプライズの流れ

まずはMinecraftの世界であらかじめ作っておいた探検ゲームをプレイしてもらいます。プレイしている気持ちになって、以下読み進んでいただけると幸いです。

ゲームスタート!近くに小屋があるぞ。入ってみよう。

f:id:miu4930:20210811171659j:plain

小屋の中にはさらに先に続く扉があります。

f:id:miu4930:20210811181324j:plain

次の扉はどこにあるのかな。

f:id:miu4930:20210811172105j:plain

次はどこだろう。

f:id:miu4930:20210811181344j:plain

こんなところに。

f:id:miu4930:20210811181400j:plain

洞窟を抜けて・・・。

f:id:miu4930:20210811181413j:plain

大きな建物が見えてきた!登ってみよう。

f:id:miu4930:20210811181454j:plain

(大きな建物は上から見ると誕生日ケーキになっています。)

f:id:miu4930:20210811181915j:plain

一番上まで登ったぞ。一つだけ色が違うロウソクがあるよ。

f:id:miu4930:20210811181928j:plain

色が違うローソクを剣で叩いてみよう!

f:id:miu4930:20210811181943j:plain

すると・・・

f:id:miu4930:20210811182001g:plain

Minecraftの世界の空に大きなハッピーバースデーのメッセージが!
それから目の前の不思議な箱がキラキラ光りだした!
7歳の誕生日、おめでとう!

裏側で動いている仕組み

色が違うロウソクを剣で叩くイベントの発生を監視したり、巨大なメッセージを表示したり、LEDテープを光らせたりする処理は、Minecraft Pi: Editionの裏で動かしているPythonのプログラムの中で実装しています。

Minecraft Pi: Editionは本家のMinecraftに比べると使えるブロックの種類や世界の広さなどに制限がある一方、Pythonのライブラリを通じてプログラミングをすることが出来る、面白い特徴を持っています。

ご興味ある方は、ぜひ一度Raspberry Pi公式のドキュメントをご覧になってみてください。

projects.raspberrypi.org

さて、今回Minecraft Pi: Editionの裏側で、具体的には以下のようなループ処理を動かし続けています。

while True:
    blockEvents = mc.events.pollBlockHits()

    //剣でブロックを叩くイベントの発生を検知した場合
    if blockEvents:
        event = blockEvents[0]

        //叩かれたブロックが色違いのロウソクだった場合
        if (event.pos.x, event.pos.y, event.pos.z) == trigger_pos:

            //メッセージ表示処理
            make_message_board()

            //LEDテープの点滅処理
            theaterChaseRainbow(strip)

            //5秒間点滅継続
            time.sleep(5)

            //LEDを消灯
            colorWipe(strip, Color(0, 0, 0), 10)

            //メッセージ片付け処理
            delete_message_board()

ループの度に直近のブロックを剣で叩いたイベントをpollBlockHits()で取得し、該当のブロック、つまり色が違うロウソクが叩かれるイベントが発生したらメッセージボードの表示やLEDテープの点灯処理を実行します。

PythonのMinecraftライブラリはこちらを使用しています。

github.com

今回使ったLEDテープ(WS2812B)を制御するPythonのライブラリがあり、こちらを参考にLEDテープの点灯処理を実装しました。

github.com

その他

LEDテープはこのような感じでダンボール製の箱に入れています。

f:id:miu4930:20210811185059j:plain

手頃な箱を近くのお店に探しに行ったのですが丁度いいものが見つからず、結局自作で対応しました。ダンボール、結構便利ですね。

感想とまとめ

いかがでしょうか。反省点はあるものの、面白い仕組みが出来たかな、と思います。実はこの仕組みを作るまでMinecraftをほとんど知らず、攻略本を買うところからスタートしました。読めば読むほど色々なことが出来るゲームであることを理解した反面、作りたい仕組みの方向性がブレにブレてしまい、この形にたどり着くまでだいぶ紆余曲折ありました。

最終的に、ラズパイやPythonなど自分の知っている分野になるべく近いところからスタートし、徐々に新しい、これまで知らなかった分野であるMinecraftの要素を取り入れていく方が良いということに気づきました。既知の世界と未知の世界、どちらにスタート地点を設定するのか。これはとても重要なことなのだと改めて気づかされました。

今回作った仕組みですが、応用すれば他にも楽しいことがたくさん出来そうです。少し大げさな表現ですが、バーチャルとリアルの融合です。みなさまの夏の自由研究の一助になれば幸いです。