駒台の表示ロジック
本章からゲームロジックで必要になる関数を作っていきます。
駒台に獲得した駒を表示する関数を作ります。
ComKomadai.vue
に駒ラベルを表示するかを決めるshowKomaLabel
という関数を作ります。
関数はmethods
で定義します。
<script>
import { mapState } from "vuex"
export default {
computed: {
...mapState(["komaList", "comKomadai", "comPoint"])
},
methods: { // 以下追加
showKomaLabel(komaIndex) {
if (this.comKomadai.includes(komaIndex)) {
return this.komaList[komaIndex].label
} else {
return null
}
}
}
}
</script>
引数のkomaIndex
はfuやkinなどの値が渡ってくる想定です。
this.comKomadai
はstore.js
のstate
で定義したcomKomadai
です。
まだ作成していませんが、Comが駒を獲得したらcomKomadai
にfuやkinなどが追加されます。
例えばcomKomadai
が["fu", "kin"]
だとしたら、showKomaLabel("fu")
の戻り値は歩で、showKomaLabel("kaku")
の戻り値はnullとなります。
これをテンプレートで所定の駒の位置で引数を渡せば表示ロジックが出来上がります。
<tbody>
<tr>
<td>{{ showKomaLabel("kaku") }}</td>
<td>{{ showKomaLabel("kin") }}</td>
<td>{{ showKomaLabel("gin") }}</td>
</tr>
<tr>
<td>{{ showKomaLabel("keima") }}</td>
<td>{{ showKomaLabel("kyosha") }}</td>
<td>{{ showKomaLabel("fu") }}</td>
</tr>
</tbody>
comKomadai
はまだ空の配列なので駒台には何も表示されません。
試しにstore.js
のcomKomadai
を["fu"]
にすると、歩が表示されるのが確認できます。
PlayerKomadai.vue
にもshowKomaLabel
を作ります。
<script>
import { mapState } from "vuex"
export default {
computed: {
...mapState(["komaList", "playerKomadai", "playerPoint"])
},
methods: { // 以下追加
showKomaLabel(komaIndex) {
if (this.playerKomadai.includes(komaIndex)) {
return this.komaList[komaIndex].label
}
}
}
}
</script>
Comとの違いはincludes
の対象になる配列がplayerKomadai
になっただけです。
ComKomadai.vue
と同じshowKomaLabel
という関数名でも別のコンポーネントなので問題ありません。
Comと同じようにテンプレートで使用します。
<tbody>
<tr>
<td>{{ showKomaLabel("fu") }}</td>
<td>{{ showKomaLabel("kyosha") }}</td>
<td>{{ showKomaLabel("keima") }}</td>
</tr>
<tr>
<td>{{ showKomaLabel("gin") }}</td>
<td>{{ showKomaLabel("kin") }}</td>
<td>{{ showKomaLabel("kaku") }}</td>
</tr>
</tbody>
駒をコンポーネント化
次は選択する駒の表示部分を改良します。
ゲームが進んでいくと一度使ったコマは使えませんので、薄く表示しています。
これを実装していきたいのですが、その前に駒をコンポーネントにします。
ShogiPoker.vue
が肥大化しそうなので適度にコンポーネントを作ると都合が良いです。
ComKoma.vue
を作成します。
<template>
<td :class="getKomaClass()">{{ koma.label }}</td>
</template>
<script>
import { mapState } from "vuex"
export default {
props: {
komaIndex: {
type: String,
required: true
},
koma: {
type: Object,
required: true
}
},
computed: {
...mapState(["comSelectable"])
},
methods: {
getKomaClass() {
if (!this.comSelectable.includes(this.komaIndex)) {
return "unselectable"
}
}
}
}
</script>
<style scoped>
td {
transform: rotate(0.5turn);
-webkit-transform: rotate(0.5turn);
}
.unselectable {
opacity: 0.4;
}
</style>
getKomaClass
というメソッドでcomSelectableに含まれていなければ、unselectableをクラスにつけています。
unselectableにopacity: 0.4;
を付ければ選択できない駒を薄く表示することができます。
tdにtransform
で逆さに表示するスタイルもここで当てています。
props
は親コンポーネントから渡ってくるプロパティです。
https://jp.vuejs.org/v2/guide/components-props.html
ComKoma.vue
をShogiPoker.vue
で読み込みます。
<script>
import { mapState } from "vuex"
import GameRule from "./GameRule"
import ComKomadai from "./ComKomadai"
import PlayerKomadai from "./PlayerKomadai"
import ResetBtn from "./ResetBtn"
import ComKoma from "./ComKoma" // 追加
export default {
components: {
GameRule,
ComKomadai,
PlayerKomadai,
ResetBtn,
ComKoma // 追加
},
...
</script>
Comの駒表示する部分をコンポーネントを使って書き換えます。
<div class="shogi-ban">
<table>
<tbody>
<tr class="com-row">
<com-koma
v-for="(koma, index) in this.komaList"
:key="index"
:koma-index="index"
:koma="koma"
/>
</tr>
コンポーネントに対してもv-for
は使えます。
追加されたkoma-index
とkoma
がComKoma.vue
にあるprops
に渡されます。
渡す側はkoma-index
のようにケバブケースで、受け取る側はkomaIndex
のようにキャメルケースで書くことが推奨されています。
props: {
komaIndex: {
type: String,
required: true
},
koma: {
type: Object,
required: true
}
},
props
には型をtype
で指定したり、required
で必須かどうかを定めることができます。
続いてPlayerの駒もコンポーネントにしていきます。
<template>
<td :class="getKomaClass()">{{ koma.label }}</td>
</template>
<script>
import { mapState } from "vuex"
export default {
props: {
komaIndex: {
type: String,
required: true
},
koma: {
type: Object,
required: true
}
},
computed: {
...mapState(["playerSelectable"])
},
methods: {
getKomaClass() {
if (!this.playerSelectable.includes(this.komaIndex)) {
return "unselectable"
}
}
}
}
</script>
<style scoped>
td:not(.unselectable) {
cursor: pointer;
}
td:hover,
.unselectable {
opacity: 0.4;
}
</style>
ほぼCom側と同じです。
Playerは駒を実際に選択できるので、ホバーした時にスタイルを当てています。
ShogiPoker.vue
でPlayerKoma
を使います。
<script>
import { mapState } from "vuex"
import GameRule from "./GameRule"
import ComKomadai from "./ComKomadai"
import PlayerKomadai from "./PlayerKomadai"
import ResetBtn from "./ResetBtn"
import ComKoma from "./ComKoma"
import PlayerKoma from "./PlayerKoma" // 追加
export default {
components: {
GameRule,
ComKomadai,
PlayerKomadai,
ResetBtn,
ComKoma,
PlayerKoma // 追加
},
...
</script>
<tr class="player-row">
<player-koma
v-for="(koma, index) in this.komaList"
:key="index"
:koma-index="index"
:koma="koma"
/>
</tr>
</tbody>
</table>
</div>
ここまでのコードはこちらにあります。
次章 はemitを使って駒選択の処理を作成します。