ゲームで使うデータを整理しよう
忙しい方はここだけ見て
この章で見るのは、ゲームの「材料」です。
今回の人生ゲームは、主にこのデータでできています。
BoardTile 人生のマス
PlayerState プレイヤー情報
PropertyOwner 物件の所有者
GameLog ゲームの記録
GameResult 最終結果・順位
EventInfo ランダムイベント
コードでは、このあたりを見ます。
class BoardTile
class PlayerState
class PropertyOwner
class GameLog
class GameResult
class EventInfo
まずは、こう覚えればOKです。
ゲームは、データを用意して、そのデータを画面に表示している
この章でやること
この章では、人生ゲームで使うデータを整理します。
ゲームアプリは、見た目だけでできているわけではありません。
裏側には、次のような情報があります。
今、誰のターンか
プレイヤーがどこにいるか
所持金はいくらか
どんなマスがあるか
物件を誰が持っているか
イベントでお金が増えるか減るか
これらをコードの中で整理しているのが、データクラスです。
今日のゴール
この章のゴールは、次の3つです。
1. ゲームにはデータが必要だと分かる
2. BoardTileとPlayerStateの役割が分かる
3. classは情報をまとめる箱だと分かる
全部を暗記しなくて大丈夫です。
まずは、「どのclassが何を担当しているか」だけ分かればOKです。
Step 1:データとは何かを知ろう
ゲームでいうデータとは、ゲームを動かすための情報です。
例えば、プレイヤーには次の情報が必要です。
名前
色
現在地
所持金
持っている物件
ゴールしたかどうか
人生のマスにも情報が必要です。
何歳のマスか
マスの名前
説明文
給料マスなのか
物件マスなのか
イベントマスなのか
このような情報をまとめておくことで、ゲームを動かせます。
Step 2:classは情報をまとめる箱
Dartでは、情報をまとめるときに class を使います。
例えば、人生のマスは BoardTile というclassでまとめています。
class BoardTile {
const BoardTile({
required this.index,
required this.age,
required this.stage,
required this.label,
required this.description,
required this.type,
this.price = 0,
this.rent = 0,
});
final int index;
final int age;
final String stage;
final String label;
final String description;
final TileType type;
final int price;
final int rent;
}
最初は、こう考えればOKです。
BoardTile = 人生のマス情報を入れる箱
Step 3:BoardTileを理解しよう
BoardTile は、人生ゲームの1マス分の情報です。
例えば、コードにはこのようなマスがあります。
BoardTile(
index: 2,
age: 23,
stage: '社会人スタート期',
label: '小さなカフェ',
description: '小さなカフェに投資できます。',
type: TileType.property,
price: 300,
rent: 80,
),
これは、次の意味です。
| 項目 | 意味 |
|---|---|
index | 何番目のマスか |
age | 何歳のマスか |
stage | 人生の時期 |
label | マスの名前 |
description | 説明文 |
type | マスの種類 |
price | 物件価格 |
rent | 通行料 |
物件マスなので、price と rent があります。
Step 4:TileTypeを理解しよう
マスの種類は、TileType で決めています。
enum TileType {
start,
normal,
payday,
event,
property,
tax,
goal,
}
それぞれの意味はこちらです。
| 種類 | 意味 |
|---|---|
start | スタート |
normal | 通常マス |
payday | 給料マス |
event | イベントマス |
property | 物件マス |
tax | 税金マス |
goal | ゴール |
enum は、選択肢をまとめるためのものです。
この場合は、
マスの種類を決める選択肢
として使っています。
Step 5:PlayerStateを理解しよう
次に、プレイヤーの情報です。
class PlayerState {
const PlayerState({
required this.id,
required this.name,
required this.color,
required this.position,
required this.cash,
required this.properties,
required this.isFinished,
});
final int id;
final String name;
final Color color;
final int position;
final int cash;
final Set<int> properties;
final bool isFinished;
}
これは、プレイヤー1人分の情報をまとめています。
PlayerState = プレイヤー情報を入れる箱
Step 6:PlayerStateの中身を見る
プレイヤーには、次の情報があります。
| 項目 | 意味 |
|---|---|
id | プレイヤー番号 |
name | プレイヤー名 |
color | コマの色 |
position | 今いるマス |
cash | 所持金 |
properties | 持っている物件 |
isFinished | ゴールしたか |
例えば、最初のプレイヤーはこう作られています。
PlayerState(
id: 0,
name: 'Player 1',
color: AppColors.red,
position: 0,
cash: 1500,
properties: <int>{},
isFinished: false,
),
意味はこうです。
Player 1
赤いコマ
0番目のマスにいる
所持金は1500
物件はまだ持っていない
ゴールしていない
Step 7:copyWithを理解しよう
PlayerState の中には、copyWith という関数があります。
PlayerState copyWith({
int? position,
int? cash,
Set<int>? properties,
bool? isFinished,
}) {
return PlayerState(
id: id,
name: name,
color: color,
position: position ?? this.position,
cash: cash ?? this.cash,
properties: properties ?? this.properties,
isFinished: isFinished ?? this.isFinished,
);
}
これは、プレイヤー情報の一部だけを変えるための便利な関数です。
例えば、所持金だけ変えたいときに使います。
player.copyWith(cash: player.cash + 300)
これは、
今のプレイヤー情報をもとにして
所持金だけ300増やした新しいデータを作る
という意味です。
Step 8:PropertyOwnerを理解しよう
物件の所有者は、PropertyOwner で管理します。
class PropertyOwner {
const PropertyOwner({
required this.tileIndex,
required this.ownerPlayerId,
});
final int tileIndex;
final int ownerPlayerId;
}
これは、次の情報を持っています。
| 項目 | 意味 |
|---|---|
tileIndex | どのマスの物件か |
ownerPlayerId | 誰が所有しているか |
例えば、
2番目のマスを、Player 1が持っている
という情報を保存できます。
Step 9:GameLogを理解しよう
ゲーム中の記録は、GameLog で管理します。
class GameLog {
const GameLog(this.message);
final String message;
}
例えば、こういう記録です。
Player 1 が 3 を出しました。
Player 2 は小さなカフェを購入しました。
Player 1 は通行料 80 を支払いました。
ゲームログがあると、何が起きたか分かりやすくなります。
Step 10:GameResultを理解しよう
ゲーム終了後の順位は、GameResult で管理します。
class GameResult {
const GameResult({
required this.player,
required this.totalAssets,
});
final PlayerState player;
final int totalAssets;
}
これは、次の情報を持っています。
| 項目 | 意味 |
|---|---|
player | どのプレイヤーか |
totalAssets | 最終資産 |
最終資産は、この考え方で計算します。
最終資産 = 現金 + 持っている物件の価格
Step 11:EventInfoを理解しよう
ランダムイベントは、EventInfo で管理します。
class EventInfo {
const EventInfo({
required this.title,
required this.description,
required this.cashChange,
required this.category,
});
final String title;
final String description;
final int cashChange;
final EventCategory category;
}
例えば、こういうイベントです。
EventInfo(
title: '副業が大成功',
description: '週末に始めた小さな副業が話題になりました。',
cashChange: 300,
category: EventCategory.work,
),
意味はこうです。
イベント名:副業が大成功
説明文:週末の副業が話題になった
お金の変化:+300
カテゴリ:仕事
Step 12:EventCategoryを理解しよう
イベントの種類は、EventCategory で分けています。
enum EventCategory {
income,
expense,
work,
health,
family,
investment,
chance,
trouble,
}
意味はこちらです。
| 種類 | 意味 |
|---|---|
income | 収入 |
expense | 出費 |
work | 仕事 |
health | 健康 |
family | 家族 |
investment | 投資 |
chance | チャンス |
trouble | トラブル |
イベントをカテゴリ分けしておくと、色やアイコンを変えやすくなります。
Step 13:GamePhaseを理解しよう
ゲームの状態は、GamePhase で管理しています。
enum GamePhase {
waitingRoll,
rolling,
showingModal,
choosingProperty,
gameOver,
}
意味はこちらです。
| 状態 | 意味 |
|---|---|
waitingRoll | サイコロ待ち |
rolling | サイコロ中 |
showingModal | イベント画面表示中 |
choosingProperty | 物件購入を選択中 |
gameOver | ゲーム終了 |
これがあることで、
今はサイコロを押してよいか
購入ボタンを出すべきか
ゲーム終了画面を出すべきか
を判断できます。
Step 14:データの関係をざっくり見る
今回のゲームは、だいたいこのような関係です。
BoardTile
↓
人生のマス
PlayerState
↓
プレイヤーの状態
EventInfo
↓
ランダムイベント
PropertyOwner
↓
物件の所有者
GameResult
↓
最終結果
GameLog
↓
ゲームの記録
このデータを使って、画面を作ったり、ゲームを進めたりしています。
Step 15:どこを編集しやすい?
初心者が最初に編集しやすいのは、この3つです。
| 編集するもの | 場所 |
|---|---|
| マスの内容 | _createTiles() |
| プレイヤー名 | _createInitialPlayers() |
| イベント内容 | _createEventPool() |
例えば、プレイヤー名を変えるならここです。
name: 'Player 1',
これを変えます。
name: '太郎',
まずは文字を変えるところから始めると、壊れにくいです。
触ってみよう
今回は、プレイヤー名だけ変えてみましょう。
_createInitialPlayers() を探します。
変更前です。
name: 'Player 1',
変更後です。
name: '太郎',
もう1人も変えてみます。
name: '花子',
保存して、アプリを再読み込みします。
r
画面に「太郎」「花子」と表示されたら成功です。
よくあるエラーと直し方
1. カンマを消してしまった
Dartでは、項目の区切りにカンマが必要です。
悪い例です。
name: '太郎'
color: AppColors.red,
正しくはこちらです。
name: '太郎',
color: AppColors.red,
文字を変えるときは、カンマを消さないようにしましょう。
2. クォーテーションを消してしまった
文字は ' で囲みます。
悪い例です。
name: 太郎,
正しくはこちらです。
name: '太郎',
文字を変えるときは、前後の ' を残します。
3. 数字に文字を入れてしまった
cash は数字です。
悪い例です。
cash: '1500',
正しくはこちらです。
cash: 1500,
数字は ' で囲みません。
4. typeを適当に変えてしまった
type は、決まった選択肢から選びます。
正しい例です。
type: TileType.event,
悪い例です。
type: 'event',
TileType.event のように書きます。
この章で覚えること
この章で覚えることは、3つだけです。
1. classは情報をまとめる箱
2. enumは選択肢をまとめるもの
3. ゲームはデータを使って動いている
まずはこれだけで大丈夫です。
やる気を維持するコツ
ゲーム開発は、データが分かると一気に楽しくなります。
なぜなら、文字を変えるだけで別のゲームにできるからです。
人生ゲーム
↓
投資ゲーム
↓
キャリアゲーム
↓
学校生活ゲーム
↓
店舗経営ゲーム
最初は難しい処理を書かなくても大丈夫です。
まずは、マスの名前やイベント名を変えて、自分だけのゲームに近づけていきましょう。
チェックリスト
□ BoardTileが人生のマスだと分かった
□ PlayerStateがプレイヤー情報だと分かった
□ PropertyOwnerが物件所有者だと分かった
□ GameLogがゲーム記録だと分かった
□ GameResultが結果表示用だと分かった
□ EventInfoがイベント情報だと分かった
□ TileTypeがマスの種類だと分かった
□ GamePhaseがゲームの状態だと分かった
□ EventCategoryがイベントの分類だと分かった
□ プレイヤー名を変更してみた
まとめ
この章では、ゲームで使うデータを整理しました。
人生ゲームは、画面だけで動いているのではありません。
BoardTile、PlayerState、EventInfo などのデータを使って、マス、プレイヤー、イベントを管理しています。
class は情報をまとめる箱、enum は選択肢をまとめるものです。
次の章では、_createTiles() を見ながら、人生のマスを作っていきます。
