streaming kitAVerMedia BU110

まずはここから「伊藤流」Unity初心者講座【2048】後編

この記事は後編となっています。前編はこちらになります。

 

まずはここから「伊藤流」Unity初心者講座【2048】前編


「とりあえず動けばいい 勉強は後でやろう」

前回とりあえず動かしました。次は勉強をしましょう。

 

プログラムを解説していきます。

 

今回使用したプログラムの処理を簡単に書くとこのようになります。

1.初期化

2.プレイヤーの操作に合わせて盤面を移動

3.スコアアップのアニメーションを再生

4.盤面上に数字をランダムに生成

5.画面を更新(手順2と4はプログラム上だけの更新で画面の反映はしていない)

6.数字の大きさを調整

7.ゲームオーバーをしていないか判定

この6手順をループしてします。


この6手順の動きは91行目にある「UpdateCorutine()」に記載してあります。

 

 

IEnumerator UpdateCorutine()

「IEnumerator」はコルーチンというもので定義した関数を非同期で処理をすることが出来ます。今回は操作が行われるまで処理を止めるために使用しています。

102行目のこのことです。

yield return new WaitUntil(() => isPlay); //isPlayフラグがTRUEになるまで処理を一時停止する キーボードを押すとTRUEになる

フラグ「isPlay」が「True」になるまで処理を中断します。


「isPlay」はどこで「True」になっているのでしょうか?

59行目を見てください。

 

 

一行で内容を表すと、方向キーを入力するとTrueになる構造です。

Input.GetKeyDown()

は()の中のキーが押されたか判定します。

if (Input.GetKeyDown(KeyCode.S)

だと「S」のキーが押されたか判定します。

さらに深く見ていきましょう。

isPlay = true;

キーを押したことをフラグに反映させています。

enum_NextMoveAngle = MoveAngle.Left;

入力されたキーをenum_NextMoveAngleに記録しています。

この書き方は(私の中で)初心者殺しと思っています。

プログラム初心者の中にはこれを見て何をしてるか「?」になっている方もいるのではないのでしょうか。

「Enum」というもので列挙型と呼ばれる変数の型です。いくつかの文字列をひとまとめにして扱うことができ、指定した文字列以外は絶対に入ってこないのでコードが綺麗に見えやすいです。

「Enum」の定義は464行目に書いてあります。

 

 

書き方は比較的特殊ですが使いこなすと綺麗なソースコードを書くための必須レベルの知識だと考えています。この機会に覚えておくことをオススメします。

ちなみにこの2048では「CorutineUpdate関数」でメインの処理を行っており「Update関数」でキーの入力を制御しています。


CorutineUpdate関数に話を戻しましょう。

後の関数の内訳はこのような感じです。

1.初期化→Initilize()

2.プレイヤーの操作に合わせて盤面を移動→MoveBoard()

3.スコアアップのアニメーションを再生→PlayScoreUpAnimation()

4.盤面上に数字をランダムに生成→GenerateNumber()

5.画面を更新(手順2と4はプログラム上だけの更新で画面の反映はしていない)→UpdateDisplay()

6.数字の大きさを調整→ChangeScaleText()

7.ゲームオーバーをしていないか判定→CheckGameOver()

 

if (isUpdate)// 盤面の数字が動いたら実行

これはキーを押した際に盤面が動いたら「True」になるようになっています。その判定は「MoveBoard()」内で行っています。

それでは使用している関数を一つずつ説明していきます。


1.初期化

2種類の初期化があります。

49行目

 

 

406行目

 

 

「Initilize関数」はループごとに実行。

「Reset関数」はリセットボタンを押す時と起動時に実行されます。

「Initilize関数」はフラグとスコアの初期化のみを行っています。

「Reset関数」は「Initilize」以外で初期化が必要な事柄を全て行っています。

「Reset」の中身を説明していきます。

if(gameOverText)// gameOverTextがアタッチされていてたら実行
      gameOverText.text = "";

「gameOverText」のテキスト文を空白にします。

if(gameOverText)はUnityだけの特殊な記述となっています。

意味は 「gameOverText」 がアタッチされていたら実行するといった内容です。

通常アタッチされていない状態で実行するとエラーで処理が止まってしまうのですが今回のif(gameOverText)(Nullチェックと言います)のように書くとエラーの場合は無視して次の処理を実行できます。

for (int x = 0; x <= 3; x++)
      for (int y = 0; y <= 3; y++)
         board[x, y] = 0;

盤面の数字を全て0に上書きします。

後はコードのコメント通りに初期化用関数を実行します。


2.プレイヤーの操作に合わせて盤面を移動

177行目

 

 

盤面を移動させ数値を更新してから再度盤面に移動の処理を行っています。

Move関数は任意の方向に移動。CalculationCheckAndUpdate関数は移動元と移動先の数字が一緒の場合、倍にして合体します。

for文を多重でループさせているため見ずらいコードになっており最適化できる部分がいくつかあります。

余力がある方は是非ここの部分の最適化を練習してみてください。


3.スコアアップのアニメーションを再生

 

 

「scoreUpAnim.Play」から「ScoreUp」のアニメーションファイルを再生します。


4.盤面上に数字をランダムに生成

119行目

 

 

空いているマスにランダムで新しい数字を生成します。

ランダムでマスを選び、空いているマスでなかったら左側へ総当たりで探索します。

「左側へ総当たり」を「調べていないマスをランダム」に変えるとより本物に近づきます。

余力がある方は是非挑戦してみてください。

また新規作成する数字が「2」のみですが本物は「2」と「4」を生成します。この処理も同じく挑戦してみてください。


5.画面を更新(手順2と4はプログラム上だけの更新で画面の反映はしていません)

160行目

 

 

手順1~4で行ったことを画面に反映させます。

foreach (var value in textList)

「foreach」は配列すべてを実行する構文です。forと似ていますがforより簡潔にコードを書けるため私は積極的に使うようにしています。


6.数字の大きさを調整

425行目

 

 

数字の桁数に応じて盤面の数字の大きさを変更します。

数字の桁数が増えると隣の数字と重なって見ずらくなってしまいます。これを防ぎます。


7.ゲームオーバーをしていないか判定

339行目

 

 

ゲームオーバーの状態か確認します。

// 0がマスにあったら終了
for (int x = 0; x <= 3; x++)
   for (int y = 0; y <= 3; y++)
      if (board[x, y] == 0)
          return;

盤面に「0」の数字があるか調べます。「0」があったらゲームオーバーではないと判定し処理を終了します。

// 前後左右に同じ数字のマスがないか探索 あったら終了
// 存在しないマスを読んだ場合はtry catchを利用して終了
for (int x = 0; x <= 3; x++)
   for (int y = 0; y <= 3; y++)
    {
      try
      {
         if (board[x, y] == board[x + 1, y])
           return;
      }
      catch { }
      try
      {
         if (board[x, y] == board[x - 1, y])
            return;
      }
      catch { }
      try
      {
         if (board[x, y] == board[x, y + 1])
            return;
      }
      catch { }
      try
      {
          if (board[x, y] == board[x, y - 1])
            return;
      }
      catch { }
   }

入力されたキーに応じて、その方向に数字を動かして動かせたらゲームオーバーではないと判定として処理を終了させます。

// ゲームオーバー処理へ移行
GameOver();

2つのゲームオーバーチェックを抜けた時のみ実行されます。


お疲れ様です。プログラムの説明が終わりました。

この記事で説明した事柄は最低減です。わからないことが出てくると思います。

その際は

Google検索【わからないこと Unity】

と打ち込んで探してみてください。


まとめ

2パートに分けて行った今回の講座。

記事通りに行うと

1.とりあえず動かしてみる

2.完成されたものを追加、修正する

3.わからないものを調べる

3ステップの学習法を体験できたはずです。

勉強のモチベーションを維持することは重要です。

答えを見ながら問題集を解くような学習法ですが、「モチベーションを維持する」ためには「わからない状態を極力減らす」ことが大切の考えからできています。

向き不向きはあると思いますがこの記事をもとにUnityエンジニアの道を歩めるようになればと考えています。

 

最後に…

 

今回の記事は1回のみの予定ですが反響があったら連載にさせてもらえるかもしれません。

今回の記事がイイネ!と感じたら「イイネ!」を残してもらえると有難いです。

 

それでは良きUnityライフを

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

ページ上部へ戻る
%d人のブロガーが「いいね」をつけました。