作ろうと思った動機
上記エントリで CHIP-8 のエミュレータを作ろうと思っていて、ディスプレイを擬似的に用意しようと思ったときに「GUI でドットを表現する」ということを基礎として学びたかったというのが1つ。
また、Go のチュートリアルは一通りやってみましたが、やはり何か「やってる感」があるプログラムを採用したかったためです。
SDL2 自体も色々とできて、なかなか面白そうだったので、グラフィック周りのハンドリングも学べるということで、一石二鳥ということでやってみました。
たぶん普通は CUI プログラムを書いて、画面を逐一クリアしてターミナルに逐一表示するほうが簡単だと思いますが、そこはロマンということで ...
作ったもののデモ
こちらは初期位置をランダムに配置したバージョンです。マスをクリックすることで、強制的にマスを「生きている状態」にすることができます。
また配置をソースコードで記述してあげることで、こういった規則的なアニメーションができます。プログラムでこういったアニメーションが描画ができるなんて、かっこいいです( *ˊᵕˋ ) ⁾⁾
ソースコード
作り切るまでの過程
せっかく作ったので、足跡を残すために「どのように順を追って勉強をしたか」という点を残しておこうと思います。
1. Go について学ぶ
こちらは、有名すぎる「A Tour of Go」を一通りなぞりました。
2. Go の開発環境について学ぶ
私が Go を始めたころは Go Modules というものがなかった頃の話なので、アップデートがてら、Go Modules を使った開発環境を調べました。下記サイトでは goenv を利用していますが、私は brew で Go 1.12.5 を導入しました。
3. グラフィックライブラリの選定
ここは散々迷いました。もともとグラフィックライブラリには精通していないので、「OpenGL というものがあったり、Windows では DirectX ってのがあるな ...」程度にしか理解していません。
なので、記事先頭で引用した記事内で SDL2 を利用しているということなので、SDL2 を使うことにしました。GLUT や GLFW などもありますが、Go の binding では pixel というものもあるようです。
なかなか奥が深いです。ライブラリの棲み分けのブロック図とかないのかな、これ。
というわけで SDL2 を採用することを決めたので、Go の SDL2 binding である下記のveandco/go-sdl2 というライブラリを利用することにしました。
4. SDL2 の使い方を学ぶ
SDL2 を使うことにしたので、早速「ウインドウの表示」と「ピクセル単位での描画」を学んでいきます。
ここでは、「SDL には Window, Renderer, Texture」というものがあるんだな、というざっくりとした理解をして、「Texture に特定のデータの配列を渡して、Texture のデータを Renderer にコピーすればそれっぽいものを描画するんだな」ということを理解しておきます。
上記のソースでは sdl2canvas という自分が定義したパッケージに pixels
という配列を持たせて、そこに R8G8B8A8 形式でデータを持たせて、それを Texture に渡すことでピクセル単位の描画を行っています。
5. ライフゲームのルールを把握して実装する
SDL2 とはまったく関係なく、ライフゲームのルールを作り込んでいきます。
ライフゲームでは、フィールドがあり、ステップを進めるたびに特定のルールで次々とフィールド上で生死を繰り返していきます。
ここでは、「現在のフィールド(Current)」と「現在のフィールドを元に生死判定を行ったあとのフィールド(Next)」の2つのフィールドを持っておきます。生死判定が終わったあとに「現在のフィールド」にコピーします。
ちなみに生死判定はいろいろなルールがあるそうですね。
ちなみに正式名称は「Conway's Game of Life」と言うそうで、ボードゲームと名前がかぶるから「Conway's」という名前が先頭についているようです。
6. ライフゲームのフィールドを SDL2 で作ったウインドウに反映する
私が書いたコードの該当箇所はこちら
ライフゲームが持っている配列から、SDL2 Texture に反映する pixels という配列に反映します。
ここでは、ウインドウの横幅 -> 縦幅の順で for 文を回し、特定の範囲ごとに色を塗り分けています。
これで完成です⸜( ´ ꒳ ` )⸝
まとめ
SDL2 を使ってウィンドウを表示して、ドット絵っぽいような画面を描画して、そこにライフゲームのロジックを組み込むということができました。
これで、何らかのエミュレータを描くこともできるようになったかなと思います。
CHIP-8 エミュレータ書くぞー
ライフゲームに関する蛇足
ライフゲーム自体も奥が深く、専用の wiki があり、パターンファイルというものまで決まっているそうです。
RTE というファイルフォーマットがあり、このファイルにはルールやドットパターンなどが記述されています。このファイルを読み込んで、描画することで特定のアニメーションを再生できる、という仕組みですね。
ここまで対応できると、すでに先人が見つけたパターンを試すことができるので、これはこれでまた1つ面白いトピックだと思います。(今回は RTE ファイルの読み込みまではやっていません)