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

お金の増減処理を理解しよう

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

忙しい方はここだけ見て

この章で見る一番大事な場所は、ここです。

void _addCashToCurrentPlayer(int amount) {
  final PlayerState player = _currentPlayer;

  _players[_currentPlayerIndex] = player.copyWith(
    cash: player.cash + amount,
  );

  setState(() {});
}

お金を増やすときは、プラスの数字を渡します。

_addCashToCurrentPlayer(500);

お金を減らすときは、マイナスの数字を渡します。

_addCashToCurrentPlayer(-250);

考え方はこれだけです。

今の所持金 + amount = 新しい所持金

つまり、

amount がプラス → お金が増える
amount がマイナス → お金が減る

まずは、これだけ分かればOKです。


この章でやること

この章では、人生ゲームの中で「現金が増えたり減ったりする仕組み」を見ていきます。

ゲームでは、いろいろな場面でお金が変わります。

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

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

イベントマスに止まる
↓
イベント内容によって増えたり減ったりする

この処理を担当しているのが、主に _addCashToCurrentPlayer() です。


今日のゴール

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

1. cash が所持金だと分かる
2. _addCashToCurrentPlayer() で現金を増減していると分かる
3. プラスなら収入、マイナスなら出費になると分かる

難しい計算はありません。

基本は、足し算と引き算です。


Step 1:cashを確認しよう

プレイヤーの所持金は、cash で管理しています。

最初のプレイヤー設定を見ると、こうなっています。

PlayerState(
  id: 0,
  name: 'Player 1',
  color: AppColors.red,
  position: 0,
  cash: 1500,
  properties: <int>{},
  isFinished: false,
),

大事なのはここです。

cash: 1500,

これは、

このプレイヤーは、最初に1500のお金を持っている

という意味です。


Step 2:お金を増やす関数を見る

お金を増やしたり減らしたりしている関数は、こちらです。

void _addCashToCurrentPlayer(int amount) {
  final PlayerState player = _currentPlayer;

  _players[_currentPlayerIndex] = player.copyWith(
    cash: player.cash + amount,
  );

  setState(() {});
}

名前が少し長いですが、意味はシンプルです。

今のプレイヤーに
amount分のお金を足す

Step 3:amountとは?

amount は、増減する金額です。

void _addCashToCurrentPlayer(int amount)

例えば、こう呼び出すと、

_addCashToCurrentPlayer(500);

amount500 になります。

つまり、

今の所持金 + 500

です。

所持金が1500なら、

1500 + 500 = 2000

になります。


Step 4:マイナスならお金が減る

お金を減らしたい場合は、マイナスの数字を渡します。

_addCashToCurrentPlayer(-250);

この場合、amount-250 です。

つまり、

今の所持金 + (-250)

です。

所持金が1500なら、

1500 - 250 = 1250

になります。

プログラムでは、増やす処理も減らす処理も、同じ関数でできます。


Step 5:給料マスではお金が増える

給料マスでは、この処理が使われています。

_addCashToCurrentPlayer(500);

これは、

今のプレイヤーの現金を500増やす

という意味です。

画面に表示する金額も、同じように 500 になっています。

cashChange: 500,

この2つの金額は、そろえておくと分かりやすいです。


Step 6:税金マスではお金が減る

税金マスでは、この処理が使われています。

_addCashToCurrentPlayer(-250);

これは、

今のプレイヤーの現金を250減らす

という意味です。

画面に表示する金額も、マイナスです。

cashChange: -250,

出費や税金では、数字の前に - をつけます。


Step 7:イベントでもお金が変わる

イベントマスでは、イベントごとに金額が変わります。

例えば、イベントデータにはこのようなものがあります。

EventInfo(
  title: '副業が大成功',
  description: '週末に始めた小さな副業が話題になりました。思わぬ収入です。',
  cashChange: 300,
  category: EventCategory.work,
),

この場合は、

現金 +300

です。

出費イベントなら、こうです。

EventInfo(
  title: '急な出費',
  description: '家電が突然故障。生活には欠かせないので買い替えました。',
  cashChange: -200,
  category: EventCategory.expense,
),

この場合は、

現金 -200

です。


Step 8:イベントの金額を反映する場所

イベントのお金を反映しているのは、ここです。

void _applyEvent(EventInfo event) {
  _addCashToCurrentPlayer(event.cashChange);

  if (event.cashChange >= 0) {
    _addLog(
      '${_currentPlayer.name} は「${event.title}」で ${event.cashChange} を獲得しました。',
    );
  } else {
    _addLog(
      '${_currentPlayer.name} は「${event.title}」で ${event.cashChange.abs()} を支払いました。',
    );
  }
}

大事なのはこの1行です。

_addCashToCurrentPlayer(event.cashChange);

イベントに書かれている cashChange を、そのまま所持金に反映しています。


Step 9:event.cashChangeとは?

event.cashChange は、イベントごとのお金の変化です。

例えば、イベントがこれなら、

cashChange: 300,

event.cashChange300 です。

イベントがこれなら、

cashChange: -200,

event.cashChange-200 です。

つまり、イベントデータに書いた金額が、そのまま現金に反映されます。


Step 10:プラスかマイナスでログを変えている

イベント後のログは、金額がプラスかマイナスかで文章を変えています。

if (event.cashChange >= 0) {
  _addLog(
    '${_currentPlayer.name} は「${event.title}」で ${event.cashChange} を獲得しました。',
  );
} else {
  _addLog(
    '${_currentPlayer.name} は「${event.title}」で ${event.cashChange.abs()} を支払いました。',
  );
}

意味はこうです。

0以上なら「獲得しました」
0より小さければ「支払いました」

abs() は、マイナスを外して表示するために使っています。

例えば、

-200

を画面では、

200を支払いました

のように見せています。


Step 11:copyWithでcashだけ変えている

お金を変えるときは、copyWith() を使っています。

_players[_currentPlayerIndex] = player.copyWith(
  cash: player.cash + amount,
);

これは、

プレイヤーの名前や位置はそのまま
cashだけ新しい金額にする

という意味です。

プレイヤー情報には、名前・色・現在地などもあります。

でも、お金の増減で変えたいのは cash だけです。

だから、copyWith(cash: ...) を使っています。


Step 12:setStateで画面を更新する

お金を変えたあと、最後にこの処理があります。

setState(() {});

これは、

データが変わったので、画面を更新してください

という意味です。

cash が変わっても、画面が更新されなければ、見た目は変わりません。

そのため、setState() が必要です。

初心者のうちは、

値を変えたら setState()

と覚えておくと分かりやすいです。


Step 13:お金がマイナスになってもよい?

今のコードでは、所持金がマイナスになる可能性があります。

例えば、所持金が100のときに、税金で250を支払うと、

100 - 250 = -150

になります。

これは、借金のような状態です。

人生ゲームとしては、マイナスを許してもOKです。

ただし、マイナスにしたくない場合は、あとで調整できます。


Step 14:マイナスを防ぎたい場合

所持金を0未満にしたくない場合は、このようにできます。

変更前です。

cash: player.cash + amount,

変更後です。

cash: max(0, player.cash + amount),

ただし、このコードを使うには、すでに上でこれを読み込んでいる必要があります。

import 'dart:math';

今回のコードでは、すでに読み込まれています。

import 'dart:math';

max(0, ...) は、

0より小さくならないようにする

という意味です。

初心者のうちは、まず元のままでOKです。


Step 15:金額を変えるとゲームバランスが変わる

お金の増減額を変えると、ゲームの難しさが変わります。

例えば、給料を増やすと、物件を買いやすくなります。

_addCashToCurrentPlayer(800);

税金を増やすと、少し厳しいゲームになります。

_addCashToCurrentPlayer(-500);

イベントの収入を大きくすると、逆転しやすくなります。

cashChange: 1000,

ただし、最初は大きく変えすぎないのがおすすめです。


触ってみよう

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

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

cashChange: 500,
_addCashToCurrentPlayer(500);

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

cashChange: 700,
_addCashToCurrentPlayer(700);

保存して、給料マスに止まったときに現金が700増えれば成功です。


もう1つ触ってみよう

税金を少し軽くしてみます。

変更前です。

cashChange: -250,
_addCashToCurrentPlayer(-250);

変更後です。

cashChange: -150,
_addCashToCurrentPlayer(-150);

保存して、税金マスに止まったときに現金が150減れば成功です。


よくあるエラーと直し方

1. 表示金額と実際の金額が違う

悪い例です。

cashChange: 700,
_addCashToCurrentPlayer(500);

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

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

cashChange: 700,
_addCashToCurrentPlayer(700);

2. 出費なのにプラスにしてしまった

悪い例です。

_addCashToCurrentPlayer(250);

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

出費にしたい場合は、マイナスにします。

_addCashToCurrentPlayer(-250);

3. 数字を文字にしてしまった

悪い例です。

cashChange: '300',

正しくはこちらです。

cashChange: 300,

数字は ' で囲みません。


4. setStateを消してしまった

悪い例です。

void _addCashToCurrentPlayer(int amount) {
  final PlayerState player = _currentPlayer;

  _players[_currentPlayerIndex] = player.copyWith(
    cash: player.cash + amount,
  );
}

これだと、画面の更新がうまくいかないことがあります。

正しくはこちらです。

void _addCashToCurrentPlayer(int amount) {
  final PlayerState player = _currentPlayer;

  _players[_currentPlayerIndex] = player.copyWith(
    cash: player.cash + amount,
  );

  setState(() {});
}

5. maxを使ったらエラーが出た

もし、次のように書いてエラーが出た場合です。

cash: max(0, player.cash + amount),

main.dart の上に、これがあるか確認してください。

import 'dart:math';

今回のコードでは最初から入っています。


この章で覚えること

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

1. cash はプレイヤーの所持金
2. _addCashToCurrentPlayer() で現金を増減する
3. プラスなら増える、マイナスなら減る

まずはこれだけで大丈夫です。


やる気を維持するコツ

お金の増減が分かると、ゲームのバランスを自分で調整できるようになります。

給料を増やす
税金を減らす
イベントの報酬を増やす
出費イベントを多くする

これだけで、ゲームの難しさが変わります。

プログラミングは、いきなり全部作る必要はありません。

まずは数字を変える。

動きを見る。

「ゲームが変わった」と感じる。

この小さな成功体験が、とても大事です。


チェックリスト

□ cash が所持金だと分かった
□ _addCashToCurrentPlayer() を見つけた
□ amount が増減する金額だと分かった
□ プラスなら現金が増えると分かった
□ マイナスなら現金が減ると分かった
□ event.cashChange がイベントの金額だと分かった
□ copyWith(cash: ...) の意味が少し分かった
□ setState() が画面更新だと分かった
□ 給料の金額を変更した
□ 税金の金額を変更した
□ 保存して動作確認した

まとめ

この章では、お金の増減処理を確認しました。

プレイヤーの所持金は cash で管理しています。

現金を増やしたり減らしたりする中心は、_addCashToCurrentPlayer() です。

プラスの数字を渡すとお金が増え、マイナスの数字を渡すとお金が減ります。

次の章では、物件購入の仕組みを見ながら、購入・所有者登録・所持金の減少を理解していきます。

教材トップへ戻る