Unityでライフゲームを作った時の実装思考
こんにちは!岩崎です。
最近絵が好きな人が落書きをするように、ゲームを作りまくってます。 今回はライフゲームを作りました。その時考えたことなど書いていきたいと思います。
ライフゲームについてあまり知らない人はこのサイトの動画を見るといいと思います。
さて、いきなりですが、実際にライフゲームをUnityで作る過程を動画にしました。ご覧あれ。
なんと20秒!
嘘です。実際はこのソースコードを書くのに2時間くらいかかりました。
ソースコードはコチラ github.com
みんながコピペだけでライフゲームを作れるように、ソースコードをオブジェクトに貼るだけでゲームができるような実装にしました。
なので、Unityにしては不自然なコードだと思うところもあると思います。そこはご了承ください。
それでは、僕が実装の時考えていたことです。
実装思考
ライフゲームの基本的な設計方針
です。
実際に見ていくと 最初の変数宣言で
// セルのデータを二次元配列で持つ。0...死、1...生 int [,] board; // 描画に関する配列 Renderer[,] _renderer;
としてます。
まずセルの情報をint型の二次元配列で持ちます。
int型で0,1で情報を持った方がアルゴリズムなどの実装がしやすいため、個人的にオススメです。
次に、ゲームが始まった時にセルを生成する
//ゲームが始まる時に1回呼ばれるメソッド void Start () { board = new int[N,N]; _renderer = new Renderer[N, N]; //初期化 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { // 最初はみんな死んだ状態 board [i, j] = 0; // セルを生成 GameObject obj = Instantiate (cell, new Vector3 (i, 0, j), Quaternion.identity) as GameObject; // 描画情報を取得 _renderer [i, j] = obj.gameObject.GetComponent<Renderer> (); } } // 省略 }
そして、Update()の中身で
①アルゴリズム実行
②描画
の順に呼びます。
void Update () { if (game) { timer += Time.deltaTime; //タイマーを動かす if (timer > interval) { Action (); // アルゴリズム実行 board[]の更新 timer = 0; //タイマーリセット } }else{ //省略 } Draw(); //board[]の内容を描画 }
Action() には、アルゴリズムの中身
Draw() には、board[,]の情報をセルの描画に反映させる命令を書きます。
重要なのは、 アルゴリズムと描画を分けて実装することだと思ってます。
アルゴリズムと描画の実装を混ぜて書くと、
アルゴリズムだけを変えたい時、または描画のところだけを変えたい時に大変になります。
また、今回は一つのスクリプトにまとめて書いてますが、
いつもはアルゴリズム用のスクリプトとセルの描画用のスクリプトに分けて書きます。
これも、変更点や拡張がしたい時に実装しやすくするためです。
このような実装の背景にはMVCモデルがあります。
Model View Controller - Wikipedia
ソフトウェアを実装する時の有力なモデルの一つです。
今回の実装がこのMVCモデルに完全に当てはまっているかというと、微妙ですが
アルゴリズムと描画の実装を分けようとしてるのは、これに少し則って実装しようとしてるからです。
Action(),Draw()の中身...省略します。自分で書いた方が楽しいよ。
おわりに
僕はアルゴリズムがからんだゲームを作るのが好きです。
今まで作ったゲームの例で言うと、
オセロ、将棋、マインスイーパー、2048などなど
全て、マス目の上にルール(アルゴリズム)があって、成立つゲームです。
このようなアルゴリズムが強いゲームを作る時は、ある程度実装を工夫しないと、
プログラムを変更しようと思ったときに大変です。
その工夫が今回でいうとMVCモデルでした。
参考になれば幸いです。