選択中の駒を表示
Playerが駒を選択して、○手目をクリックした時の挙動を実装していきます。
選択した駒の表示をcomputed
で作ります。
Playerが選択した駒のラベルをplayerSelectingKomaLabel
、Comが選択した駒のラベルをcomSelectingKomaLabel
で定義します。
computed: {
...mapState(["komaList"]),
kyokumen() {
return this.phase === 1 ? "初手" : this.phase + "手目"
},
displayResult() {
return this.gameResult ? this.gameResult : this.phaseResult
},
playerSelectingKomaLabel () { // 以下追加
return this.playerSelectingKoma ? this.komaList[this.playerSelectingKoma].label : null
},
comSelectingKomaLabel () {
return this.comSelectingKoma ? this.komaList[this.comSelectingKoma].label : null
}
}
PlayerはplayerSelectingKoma
に値が入っていればその駒のラベルを表示、値がなければ何も表示しません。
Comも同様です。
これをテンプレートで使います。
<td class="com-select">
{{ comSelectingKomaLabel }}
</td>
...
<td class="player-select">
{{ playerSelectingKomaLabel }}
</td>
playerSelectingKoma
とcomSelectingKoma
はnullなのでまだ何も表示されません。
Playerの駒選択にemitを使う
Playerが駒を選択したらplayerSelectingKoma
に値が入る処理をemit
を使って実装します。
emit
は子コンポーネントから親コンポーネントのイベント(主にmethods)を呼び出す仕組みのことです。
親から子へ変数を渡すprops
とは逆のイメージです。
これから実現したいのは下記の要件です。
子コンポーネントのPlayerKoma.vue
で駒をクリックすると、親コンポーネントのShogiPoker.vue
のplayerSelectingKoma
に値が入る。
この要件を満たすために親コンポーネントであるShogiPoker.vue
でplayerSelectingKoma
に値を代入するmethodsを作ります。
Playerが駒を選択したということで関数名は単純にselect
とします。
その準備として...mapState
に今後使用するstateを追加します。
computed: {
...mapState([
"komaList",
"playerSelectable", // 以下追加
"comSelectable",
"playerPoint",
"comPoint"
]),
},
computed: {
// 省略
},
methods: { // 以下追加
// playerが駒を選択
select(komaIndex) {
if (this.playerSelectable.includes(komaIndex)) {
this.playerSelectingKoma = komaIndex
}
}
}
引数のkomaIndex
にはfuやkinなどが渡ってくる想定です。
ただ駒はなんでもいい訳では無く、選択可能な駒である必要があるのでplayerSelectable
に含まれるかを条件にしています。
このselect
を子コンポーネントであるPlayerKoma.vue
からemit
を使って呼び出せば良いことになります。
emit
の実行にはイベントが必要なので、select-koma
というイベントを用意します。
このselect-koma
が親と子を繋ぐものになります。
実装は@select-koma="select"
をコンポーネントを使う箇所で記載します。
<player-koma
v-for="(koma, index) in this.komaList"
:key="index"
:koma-index="index"
:koma="koma"
@select-koma="select"
/>
PlayerKoma.vue
でselect-koma
が呼ばれたら、ShogiPoker.vue
のselect
を実行するという意味です。
@
はv-on
の省略記法です。
あとはこのselect-koma
をPlayerKoma.vue
で駒がクリックされたときに呼び出せば実現できます。
PlayerKoma.vue
に駒がクリックされたら呼ばれるclickKoma
を作ります。
methods: {
getKomaClass() {
if (!this.playerSelectable.includes(this.komaIndex)) {
return "unselectable"
}
},
clickKoma() { // 以下追加
this.$emit("select-koma", this.komaIndex)
}
}
clickKoma
の中でemit
を使っています。
emit
は$emit(イベント名, 渡す値)
のように書きます。
駒がクリックされたらclickKoma
を実行したいので、td
に@click
で設定します。
@click
はv-on:click
の省略記法です。
ShogiPoker.vue
の@select-koma
はこちらで作ったイベント(カスタムイベント)で、@click
はVueに元々あるイベント(ネイティブイベント)です。
ここら辺はややこしいので混同しないようにしましょう。
<td @click="clickKoma()" :class="getKomaClass()">{{ koma.label }}</td>
これでクリックしたら駒が表示されるようになったと思います。
○手目クリック処理
次は○手目をクリックしたときの処理を作っていきます。
○手目をクリックしたら起きることは以下になります。
- Comの駒をランダムに選択
- どちらの勝ちかを計算して結果を表示
- phaseを+1する
- 選択できる駒から使用した駒を削除
- 獲得ポイントを加算
- 獲得した駒を駒台に追加
このうち下3つはVuexのステートで定義した変数を変える処理になります。
これはVuexのミューテーションで行います。
本章は上3つの処理を実装します。
Comの駒をランダムに決定
○手目をクリックしたらbet
が呼ばれてComの駒がランダムに決まるように処理を追加します。
methods: {
// playerが駒を選択
select(komaIndex) {
// 省略
},
// 以下追加
// ○手目をクリック
bet() {
// comの駒をランダムに決める
let size = this.comSelectable.length
this.comSelectingKoma = this.comSelectable[Math.floor(Math.random() * size)]
}
}
<td @click="bet()" class="phase">
これで○手目をクリックするとComの駒が選択されて表示されます。
ランダムに駒を選択するところは若干ややこしいですが、JSではシンプルに書けないのでこのようになります。
Math.random()
は0から1未満のランダムな値(0.7493709みたいな)で、それに配列の要素数を掛ければ0から配列の要素数未満のランダムな値になり、小数点以下を切り捨てれば配列のインデックスをランダムに決めることができます。
例えば、要素数が3の配列なら均等な確率で0, 1, 2のどれかになります。
ComとPlayerでバトル
お互いの駒が選択されたので、どちらの勝ちか計算して結果を表示します。
battle
という関数を作って、bet
の中から呼び出します。
// ○手目をクリック
bet() {
// comの駒をランダムに決める
let size = this.comSelectable.length
this.comSelectingKoma = this.comSelectable[Math.floor(Math.random() * size)]
this.battle() // 追加
},
// 以下追加
// 対決
battle() {
// PlayerとComの駒ポイントを比較
const playerKomaPoint = this.komaList[this.playerSelectingKoma].point
const comKomaPoint = this.komaList[this.comSelectingKoma].point
if (playerKomaPoint > comKomaPoint) {
this.phaseResult = "WIN"
} else if (playerKomaPoint < comKomaPoint) {
this.phaseResult = "LOSE"
} else {
this.phaseResult = "DRAW"
}
}
このように内部から別の関数を呼ぶこともできます。
駒を選択して○手目をクリックすると結果が表示されたと思います。
phaseを加算
battle
が終わったらphase
を+1する必要があるので追加します。
// ○手目をクリック
bet() {
// comの駒をランダムに決める
let size = this.comSelectable.length
this.comSelectingKoma = this.comSelectable[Math.floor(Math.random() * size)]
this.battle()
// 以下追加
if (this.phase < 7) {
this.phase++
}
},
これで初手の次は2手目、3手目と増えていき7手目以降は増えなくなります。
ある程度ゲームのロジックができてきました。
ここまでのコードはこちらにあります。
次章 はVuexのmutationsを扱います。