Flutterアプリケーション開発概論

マスごとのイベント分岐を理解しよう

12人生ゲームを作る。サイコロ処理・イベント分岐・プレイヤー管理・データ設計・アニメーション
FlutteriOSAndroidMacOSWindows基礎から学ぶ開発アプリ開発

忙しい方はここだけ見て

この章で見る場所は、ここです。

Future<void> _handleTileEffect(BoardTile tile) async {
  switch (tile.type) {
    case TileType.start:
      // スタートマス

    case TileType.normal:
      // 通常マス

    case TileType.payday:
      // 給料マス

    case TileType.event:
      // イベントマス

    case TileType.tax:
      // 税金マス

    case TileType.property:
      // 物件マス

    case TileType.goal:
      // ゴールマス
  }
}

止まったマスで何が起きるかは、tile.type で決まります。

TileType.payday なら、お金が増える
TileType.tax なら、お金が減る
TileType.event なら、ランダムイベントが起きる
TileType.property なら、物件購入に進む
TileType.goal なら、ゴール処理に進む

まずは、こう覚えればOKです。

マスの種類を見る
↓
種類に合わせて処理を分ける

この分岐をしているのが、switch です。


この章でやること

この章では、プレイヤーが止まったマスで、どのようにイベントが分かれるのかを見ていきます。

人生ゲームでは、止まったマスによって起きることが違います。

給料マスに止まる
↓
お金が増える

税金マスに止まる
↓
お金が減る

イベントマスに止まる
↓
ランダムイベントが起きる

このような分岐を、コードでは _handleTileEffect() で行っています。


今日のゴール

この章のゴールは、次の3つです。

1. _handleTileEffect() がマスの効果を決める場所だと分かる
2. switchでマスの種類ごとに処理を分けていると分かる
3. 給料・税金・イベント・物件・ゴールの流れが分かる

全部のコードを覚えなくて大丈夫です。

まずは、止まったマスの種類で処理が変わることを理解しましょう。


Step 1:_handleTileEffect()を探す

lib/main.dart を開きます。

検索で、次の文字を探してください。

_handleTileEffect

このような関数があります。

Future<void> _handleTileEffect(BoardTile tile) async {
  switch (tile.type) {
    case TileType.start:
      // スタートマスの処理

    case TileType.normal:
      // 通常マスの処理

    case TileType.payday:
      // 給料マスの処理

    case TileType.event:
      // イベントマスの処理

    case TileType.tax:
      // 税金マスの処理

    case TileType.property:
      // 物件マスの処理

    case TileType.goal:
      // ゴールマスの処理
  }

  _checkGameOver();
}

ここが、止まったマスのイベント分岐を担当しています。


Step 2:tileとは?

tile は、プレイヤーが止まったマスです。

前の章で、次のように止まったマスを取り出しました。

final BoardTile landedTile = _tiles[nextPosition];

そして、そのマスを _handleTileEffect() に渡しています。

await _handleTileEffect(landedTile);

つまり、

landedTile = 止まったマス
tile = 受け取ったマス

と考えればOKです。


Step 3:tile.typeを見る

マスには、type があります。

例えば、給料マスならこうです。

BoardTile(
  index: 4,
  age: 25,
  stage: '初任給・収入期',
  label: '初任給',
  description: '仕事の成果として給料を受け取ります。',
  type: TileType.payday,
),

大事なのはここです。

type: TileType.payday,

この type を見て、どの処理をするか決めています。


Step 4:switchとは?

switch は、条件によって処理を分けるための書き方です。

今回のコードでは、このように使っています。

switch (tile.type) {
  case TileType.payday:
    // 給料マスの処理
  case TileType.tax:
    // 税金マスの処理
  case TileType.event:
    // イベントマスの処理
}

意味はこうです。

tile.type が payday なら給料処理
tile.type が tax なら税金処理
tile.type が event ならイベント処理

つまり、switch は分岐の交差点のようなものです。


Step 5:スタートマスの処理

スタートマスは、TileType.start です。

case TileType.start:
  await _showLifeEventModal(
    title: 'START',
    categoryLabel: 'LIFE START',
    subtitle: '${_currentPlayer.name} は人生のスタート地点にいます。',
    description: tile.description,
    icon: Icons.flag,
    accentColor: AppColors.green,
  );
  _addCashToCurrentPlayer(300);
  _addLog('${_currentPlayer.name} はスタートボーナス 300 を受け取りました。');
  _moveToNextPlayer();

流れはこうです。

スタート画面を表示
↓
現金を300増やす
↓
ログを追加
↓
次のプレイヤーへ

スタート地点でも、ボーナスを受け取るようになっています。


Step 6:通常マスの処理

通常マスは、TileType.normal です。

case TileType.normal:
  await _showLifeEventModal(
    title: tile.label,
    categoryLabel: 'NORMAL',
    subtitle: '${tile.age}歳|${tile.stage}',
    description: _normalMessage(),
    icon: Icons.circle_outlined,
    accentColor: AppColors.heading,
  );
  _addLog('通常マスです。大きな収支はありません。');
  _moveToNextPlayer();

流れはこうです。

通常マスの画面を表示
↓
お金の増減なし
↓
ログを追加
↓
次のプレイヤーへ

通常マスは、大きなイベントが起きない休憩マスです。

ゲームには、こういう何も起きないマスも大事です。


Step 7:給料マスの処理

給料マスは、TileType.payday です。

case TileType.payday:
  await _showLifeEventModal(
    title: tile.label,
    categoryLabel: 'PAYDAY',
    subtitle: '${tile.age}歳|${tile.stage}',
    description: tile.description,
    icon: Icons.payments,
    accentColor: AppColors.green,
    cashChange: 500,
  );
  _addCashToCurrentPlayer(500);
  _addLog('${_currentPlayer.name} は ${tile.label} で 500 を受け取りました。');
  _moveToNextPlayer();

流れはこうです。

給料画面を表示
↓
現金を500増やす
↓
ログを追加
↓
次のプレイヤーへ

実際にお金を増やしているのは、この部分です。

_addCashToCurrentPlayer(500);

金額を変えたい場合は、この 500 を変更します。


Step 8:イベントマスの処理

イベントマスは、TileType.event です。

case TileType.event:
  final EventInfo event = _eventPool[_random.nextInt(_eventPool.length)];
  final Color eventColor = _eventColor(event.category, event.cashChange);

  await _showLifeEventModal(
    title: event.title,
    categoryLabel: _eventCategoryLabel(event.category),
    subtitle: '${tile.age}歳|${tile.stage}',
    description: event.description,
    icon: _eventCategoryIcon(event.category),
    accentColor: eventColor,
    cashChange: event.cashChange,
  );

  _applyEvent(event);
  _moveToNextPlayer();

流れはこうです。

イベント一覧からランダムに1つ選ぶ
↓
イベント画面を表示
↓
現金を増減する
↓
次のプレイヤーへ

ランダムイベントを選んでいるのは、この部分です。

final EventInfo event = _eventPool[_random.nextInt(_eventPool.length)];

イベントの中身は、前の章で見た _createEventPool() にあります。


Step 9:税金マスの処理

税金マスは、TileType.tax です。

case TileType.tax:
  await _showLifeEventModal(
    title: tile.label,
    categoryLabel: 'TAX',
    subtitle: '${tile.age}歳|${tile.stage}',
    description: tile.description,
    icon: Icons.receipt_long,
    accentColor: AppColors.red,
    cashChange: -250,
  );
  _addCashToCurrentPlayer(-250);
  _addLog('${_currentPlayer.name} は ${tile.label} で 250 を支払いました。');
  _moveToNextPlayer();

流れはこうです。

税金画面を表示
↓
現金を250減らす
↓
ログを追加
↓
次のプレイヤーへ

お金を減らしているのは、この部分です。

_addCashToCurrentPlayer(-250);

マイナスなので、現金が減ります。


Step 10:物件マスの処理

物件マスは、TileType.property です。

case TileType.property:
  await _handlePropertyTile(tile);

物件マスだけは、処理が少し長くなるので、別の関数に分けています。

物件マスに止まる
↓
未購入なら、購入するか選ぶ
↓
自分の物件なら、何も払わない
↓
他人の物件なら、通行料を払う

この詳しい処理は、次の章以降で見ていきます。

この章では、

物件マスは _handlePropertyTile() に任せている

と分かればOKです。


Step 11:ゴールマスの処理

ゴールマスは、TileType.goal です。

case TileType.goal:
  await _showLifeEventModal(
    title: tile.label,
    categoryLabel: 'GOAL',
    subtitle: '${tile.age}歳|${tile.stage}',
    description: tile.description,
    icon: Icons.emoji_events,
    accentColor: AppColors.red,
  );
  _finishCurrentPlayer();

流れはこうです。

ゴール画面を表示
↓
現在のプレイヤーをゴール済みにする
↓
次のプレイヤーへ

ゴール処理をしているのは、この部分です。

_finishCurrentPlayer();

全員がゴールすると、ゲーム終了になります。


Step 12:最後にゲーム終了チェックをする

switch の最後に、この処理があります。

_checkGameOver();

これは、

全員がゴールしたか確認する

ための処理です。

全員がゴールしていれば、ゲーム終了状態になります。

全員ゴール
↓
GamePhase.gameOver
↓
最終順位を表示

ゲームの最後を確認する大事な処理です。


Step 13:全体の流れを見てみよう

マスごとの分岐の全体像はこうです。

止まったマスを受け取る
↓
tile.type を見る
↓
start ならスタート処理
normal なら通常処理
payday なら給料処理
event ならランダムイベント処理
tax なら税金処理
property なら物件処理
goal ならゴール処理
↓
ゲーム終了か確認

これが、イベント分岐の中心です。


Step 14:金額を変えてみよう

まずは簡単に、給料の金額を変えてみます。

変更前です。

_addCashToCurrentPlayer(500);

変更後です。

_addCashToCurrentPlayer(800);

ただし、モーダルに表示している金額も合わせて変えます。

変更前です。

cashChange: 500,

変更後です。

cashChange: 800,

この2か所を合わせると、表示と実際の金額がズレません。


Step 15:税金の金額を変えてみよう

税金も変えられます。

変更前です。

cashChange: -250,
_addCashToCurrentPlayer(-250);

変更後です。

cashChange: -400,
_addCashToCurrentPlayer(-400);

マイナスの数字なので、現金が減ります。

表示用の cashChange と、実際の処理 _addCashToCurrentPlayer() の金額を合わせましょう。


触ってみよう

今回は、給料マスの金額を 500 から 700 に変えてみましょう。

変更する場所は2つです。

cashChange: 500,
_addCashToCurrentPlayer(500);

これを、両方 700 にします。

cashChange: 700,
_addCashToCurrentPlayer(700);

保存して、給料マスに止まったときに +700 になれば成功です。


よくあるエラーと直し方

1. 表示金額だけ変えてしまった

悪い例です。

cashChange: 700,
_addCashToCurrentPlayer(500);

この場合、画面では +700 と出るのに、実際は 500 しか増えません。

正しくは、両方そろえます。

cashChange: 700,
_addCashToCurrentPlayer(700);

2. 税金なのにプラスにしてしまった

悪い例です。

_addCashToCurrentPlayer(250);

これだと、税金マスでお金が増えてしまいます。

税金で減らしたい場合は、マイナスにします。

_addCashToCurrentPlayer(-250);

3. caseの中身を消してしまった

case TileType.payday: などの中身を消すと、そのマスで何も起きなくなります。

初心者のうちは、全体を消さずに金額だけ変えるのがおすすめです。


4. TileTypeの名前を間違えた

悪い例です。

case TileType.payDay:

正しくはこちらです。

case TileType.payday:

大文字・小文字が違うだけでもエラーになります。


5. _moveToNextPlayer() を消してしまった

多くのマスの最後には、これがあります。

_moveToNextPlayer();

これを消すと、次のプレイヤーに交代しなくなります。

初心者のうちは、消さないようにしましょう。


この章で覚えること

この章で覚えることは、3つだけです。

1. _handleTileEffect() がマスごとの処理を決める
2. switch(tile.type) でマスの種類ごとに分岐する
3. 金額を変えるときは、表示用と実際の処理をそろえる

これだけで大丈夫です。


やる気を維持するコツ

イベント分岐が分かると、ゲームを自由に調整できるようになります。

例えば、

給料を増やす
税金を重くする
イベントを増やす
物件を高くする
ゴール報酬を追加する

こうした変更で、ゲームの難しさや雰囲気が変わります。

プログラミングは、最初から新しいものを全部作る必要はありません。

まずは、今ある処理の数字や文章を変えるだけでも立派なカスタマイズです。


チェックリスト

□ _handleTileEffect() を見つけた
□ tile が止まったマスだと分かった
□ tile.type でマスの種類を見ていると分かった
□ switch が分岐に使われていると分かった
□ payday が給料マスだと分かった
□ tax が税金マスだと分かった
□ event がランダムイベントマスだと分かった
□ property は _handlePropertyTile() に進むと分かった
□ goal は _finishCurrentPlayer() に進むと分かった
□ 給料の金額を変えてみた

まとめ

この章では、マスごとのイベント分岐を確認しました。

止まったマスの種類は、tile.type で判断しています。

switch (tile.type) を使って、スタート、通常、給料、イベント、税金、物件、ゴールの処理に分けています。

金額を変更するときは、画面表示用の cashChange と、実際にお金を増減する _addCashToCurrentPlayer() の数字をそろえることが大切です。

次の章では、お金の増減処理を見ながら、現金が増えたり減ったりする仕組みを理解していきます。

教材トップへ戻る