boardgame.ioというボードゲーム作成用フレームワークを使ったブラウザゲーム作成の手順です
一連の事
- Boardgame.ioでマルチプレイオンラインボードゲームを作る① boardgame.ioの立ち上げ、基本、マルチプレイサーバの作成
- Boardgame.ioでマルチプレイオンラインボードゲームを作る② ターン、フェーズ、ステージの制御
今回は、ターン、フェーズ、ステージといった段階制御を行っていきます。
ターン
ターンに関しては何もしていない状態では以下の動作となります。
- endTurnイベントでターンを終了
- Player0,1,2,...n → 0,1,2..n の順でターンを交代
ゲームによってはターンの順を制御したい場合もあると思いますが、boardgame.io上にこれを設定できる項目があります。
Gにturnを設定します。
import { TurnOrder } from 'boardgame.io/core';
export const TicTacToe = {
turn: {
order: TurnOrder.CUSTOM(['0', '2']),
},
上記で、Player0,2→0,2といった順番で遷移します。
またendTurn({ next: playerID });
といった形でentTurn時に動的に次プレイヤーを指定する方法もあります。
orderに設定できる値は色々ありますが、次のフェーズの制御に関わるものが多いのでフェーズの説明に移ります。
フェーズ
フェーズとはゲームの工程ごとの動作のイメージです。
ターンとの関係は以下のようなイメージです。
- フェーズ1 カードを引く
- ターン:Player1
- ターン:Player2
- ...
- フェーズ2 カードを見せる
- ターン:Player1
- ターン:Player2
- ...
基本編ではG
のmoves
を一つだけ定義しましたが、phases
を定義してその中にmoves
を定義しなおします。
phases: {
draw: {
start: true, //最初に始めるフェーズ
next: 'play', //次フェーズ(固定文字列ではなく関数で動的に返すことも可)
moves: { /* draw用のmoveを記載 */ },
},
play: {
moves: { /* play用のmoveを記載 */ },
},
},
この状態ですとdrawで定義したフェーズがずっと続くこととなるので、フェーズ終了条件を定義します。
フェーズ終了条件は以下のようにphaseの中に定義するか
phases: {
draw: {
start: true, //最初に始めるフェーズ
next: 'play', //次フェーズ(固定文字列ではなく関数で動的に返すことも可)
moves: { /* draw用のmoveを記載 */ },
+ endIf: ({ G }) => (G.deck <= 0), //Trueを返したとき次フェーズ
},
play: {
moves: { /* play用のmoveを記載 */ },
},
},
あるいは前項のturn
で以下のようにONCEなどを設定すると一度ターンを回すとフェーズが終了します。
turn: {
order: TurnOrder.ONCE,
},
turnの種類は以下に記載があります。
https://boardgame.io/documentation/#/turn-order?id=changing-the-turn-order
フェーズ突入/終了時に何らかの処理をしたい場合はonBegin/onEndを使用します
phases: {
phaseA: {
onBegin: ({ G, ctx }) => { ... },
onEnd: ({ G, ctx }) => { ... },
},
};
ステージ
フェーズ/ターンではプレイヤーずつ順番にmoveを行っていきましたが、各プレイヤーが順番ではなく同時にmoveするような場合もあると思います。
そのような場合はStage
を定義します。
turn: {
stages: {
stageAAA: {
moves: { /* 同時に行わせたいmoveを定義 */ },
},
},
}
任意のタイミングでsetActivePlayers
を実行します。eventsがとれるところならば、Client内でもGame内でも実行可能です。
(setActivePlayerをコールしたタイミングがプレイヤーのターン中の場合、そのターンが終了させられてからステージに移行するようです)
const goStage = (events)=>{
events.setActivePlayers({ all: 'stageAAA', minMoves: 1, maxMoves: 1 });
}
この状態だと全プレイヤーが操作可能になります。maxMovesを設定しているので1回のみ行動可能ですが、maxMovesを外せば何回でも行動できます。
また第一引数にallを設定しているので全員が行動可能になりますが、これをOtherなどにすればcurrentPlayer以外のみ行動可能となったりします。
endStage()
をコールすることでステージを抜けます。
上記のようにフェーズ/ターンは親子の関係ですが、ステージは一時的に別の状況に飛ばすようなイメージの動きとなっています。