2020年9月2日
ゲーム作りで学ぶVue.js (3) dataとcomputed

ゲームロジックを作る

前章で見た目の部分はできたので、ゲームのロジックを作っていきます。

ロジックを作るにはこれらの要素が必要になります。
・変数を宣言
・変数を画面に表示
・変数を更新する関数を作成
・操作によって関数が実行される

Vueでは基本的に各コンポーネントにこれらの処理を書いていきます。

しかしコンポーネントは独立しているので、そこで定義した変数や関数は他のコンポーネントでは使えません。
それによって変数名や関数名の衝突を避けることができます。

ただ、どうしても色んなコンポーネントから同じ変数や関数を使いたい場面があります。

そのような時に一役買ってくれるのがVuexです。
https://vuex.vuejs.org/ja/

Vuexは次章で扱うので、本章ではコンポーネントで使う変数を定義して画面に表示します。

data

ShogiPoker.vueではこれらの変数を扱います。

  • 何手目か (phase)
    型:Number
    初期値:1
    1づつ増えていき7でゲームが終了
  • ゲーム結果 (gameResult)
    型:String
    初期値:null
    勝ち or 負け or 引き分け
    ゲームが終了したときに表示される
  • 1手ごとの結果 (phaseResult)
    型:String
    初期値:null
    WIN or LOSE or DRAW
    1手ごとに表示される
  • Playerが選択中の駒(playerSelectingKoma)
    型:String
    初期値:null
    fukinのように選択中の駒を英名で格納する
    駒をクリックしたら値が入る
  • Comが選択中の駒(comSelectingKoma)
    型:String
    初期値:null
    fukinのように選択中の駒を英名で格納する
    ○手目をクリックした後に自動で決定される
  • 対決可能かどうか (canBattle)
    型:Boolean
    初期値:false
    ○手目をクリックしたときに、PlayerとComが対決できるかどうかのフラグ
    Playerが駒を選択していない時やゲームが終了した時はfalseとなり、ゲーム中にPlayerが駒を選択したらtrueとなる

これらを定義するのにdata()を使います。
この辺りの書き方はVueの決まりなので、そのまま覚えてしまうのが良いと思います。

src/components/ShogiPoker.vue

<script>
...
export default {
  components: {
    GameRule,
    ComKomadai,
    PlayerKomadai,
    ResetBtn
  },
  data() {  // 以下追加
    return {
      phase: 1,
      gameResult: null,
      phaseResult: null,
      playerSelectingKoma: null,
      comSelectingKoma: null,
      canBattle: false
    }
  }
}
</script>

定義したものはテンプレートで使用できます。

phaseを○手目のセルに表示します。
テンプレートの中でマスタッシュ構文{{}}を使えば変数を使うことができます。

src/components/ShogiPoker.vue

<td class="phase">
  {{ phase }}
</td>

これで○手目に1が表示されます。

03-010phase-data

computed

○手目に1が表示できましたが、実際には数字の後に「手目」が必要です。
足すだけなら後に記載するだけです。

<td class="phase">
  {{ phase }}手目
</td>

しかし将棋では1手目とは言わず初手というので、ここはカスタマイズが必要です。
{{}}の中ではJavaScriptが使えるので、テンプレート内で書くとしたら三項演算子でこのように書けます。

<td class="phase">
  {{ phase === 1 ? "初手" : phase + "手目" }}
</td>

これでも問題はありませんが、あまりテンプレート内にロジックを書くのはあまり好まれません。
このような時はcomputedを使います。

computedは算出プロパティと呼ばれるもので、データを加工して表示する際によく使われます。

ここではkyokumen(局面)という算出プロパティを作ります。
data()の下に記載します。

src/components/ShogiPoker.vue

<script>
...
  data() {
    return {
      phase: 1,
      gameResult: null,
      phaseResult: null,
      playerSelectingKoma: null,
      comSelectingKoma: null,
      canBattle: false
    }
  },
  computed: {  // 以下追加
    kyokumen() {
      return this.phase === 1 ? "初手" : this.phase + "手目"
    }
  }
}
</script>

JSでdata()に定義した変数を使う時はthis.変数名となります。
data()に限らず、変数や関数をJSで使う時はthis.が必要になります。

computedで定義した値もdata()同じようにテンプレートで使えます。
テンプレートではthis.は不要です。

src/components/ShogiPoker.vue

<td class="phase">
  {{ kyokumen }}
</td>

これで初手と表示されます。

03-020syote

次に将棋盤の真ん中の結果表示もcomputedで作ります。

結果表示は最初は空で、ゲームを進めていくとこのように変わっていきます。

  • ○手目をクリックしたらphaseResultを表示
  • ゲーム終了時にはgameResultを表示

名前をdisplayResultとして定義します。

src/components/ShogiPoker.vue

<script>

...
  computed: {
    kyokumen() {
      return this.phase === 1 ? "初手" : this.phase + "手目"
    },
    displayResult() {  // 以下追加
      return this.gameResult ? this.gameResult : this.phaseResult
    }
  }
}
</script>

gameResultはゲームが終了した時のみ値が入るように後で制御します。

これをテンプレートに表示します。

src/components/ShogiPoker.vue

<td class="result">
  {{ displayResult }}
</td>

現状はphaseResultが表示されていますが、値がnullなので見た目は変わりません。

ここまでのコードはこちらにあります。

コンポーネントで変数を定義できたので、 次章 はVuexで変数を管理します。

連載記事