PythonとPygameで作る レトロ風RPG 全コード

同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)


6-2 保存するデータ1 ゲーム

公開:2024-03-18

説明と全体コード

 「src/mymod/data/game.py」の説明です。保存するデータのルートにあたります。

from dataclasses import dataclass, field
from . import growth, item, map, map_event
@dataclass
class Game:
# 主人公
x: int = 10 # X位置
y: int = 10 # Y位置
next_x: int = 10 # 次のX位置
next_y: int = 10 # 次のY位置
move_rate: float = 0.0 # 移動比率
exp: int = 0 # 経験値
level: int = 0 # レベル
hp: int = 0 # HP
mp: int = 0 # MP
hp_max: int = 0 # 最大HP
mp_max: int = 0 # 最大MP
at: int = 0 # 攻撃力
df: int = 0 # 防御力
items: item.Items = field(
default_factory = lambda: item.Items.from_blank()) # アイテム
img_nums: list[int] = field(default_factory = lambda: [0, 1]) # 画像参照
# マップ
map_w: int = 60
map_h: int = 40
data_map: map.Map = field(default_factory = lambda: map.Map.from_wh(0, 0))
map_events: list[map_event.Event] = field(default_factory = list)
# 空引数から生成
@classmethod
def from_blank(cls) -> "Game":
d = Game()
growth.add_exp(d, 0) # 経験値追加(レベル1の値を計算)
d.data_map = map.Map.from_wh(d.map_w, d.map_h)
d.data_map.gen(d.x, d.y) # マップ生成
d.map_events = map_event.gen_event_from_map(d) # イベント
return d
data: Game # インスタンス格納用

インポート部分

 まずはインポート部分を示します。

from dataclasses import dataclass, field
from . import growth, item, map, map_event

 1行目では、組み込みのdataclassesから、dataclassfieldをインポートします。

 dataclassは、作成するクラスをデータ クラスにするためのものです。保存するオブジェクトのクラスは、全てデータ クラスとして作ります。

 fieldは、データ クラス内で、インスタンス変数の初期値のオブジェクトを作成するために利用します。

 2行目では、同じパッケージ内のgrowth item map map_eventモジュールを読み込みます。

Gameクラス1

 Gameクラスを分解して説明していきます。まずはクラスの作成部分と、2つのインスタンス変数です。

@dataclass
class Game:
# 主人公
x: int = 10 # X位置
y: int = 10 # Y位置

 データ クラスとしてGameクラスを作成します。属性をx yのように設定して初期値を書いていきます。

 データ クラスなので、各属性に型ヒントを書きます。データ クラスのインスタンス変数は、型ヒントを書いておく必要があります。

Gameクラス2

 インスタンス変数の定義は続きます。

next_x: int = 10 # 次のX位置
next_y: int = 10 # 次のY位置
move_rate: float = 0.0 # 移動比率
exp: int = 0 # 経験値
level: int = 0 # レベル
hp: int = 0 # HP
mp: int = 0 # MP
hp_max: int = 0 # 最大HP
mp_max: int = 0 # 最大MP
at: int = 0 # 攻撃力
df: int = 0 # 防御力

 HPなどが0になっていますが、これらの値は、他の場所で初期化します。

Gameクラス3 初期値がオブジェクトの属性

 インスタンス変数の定義は続いています。

items: item.Items = field(
default_factory = lambda: item.Items.from_blank()) # アイテム
img_nums: list[int] = field(default_factory = lambda: [0, 1]) # 画像参照

 次は、初期値がオブジェクトのインスタンス変数を作ります。

 値がオブジェクトのインスタンス変数は、fielddefault_factoryを使って初期値を設定します。そうしなければ、全てのインスタンス オブジェクトで、同じオブジェクトを利用してしまいます。

 default_factoryに登録した関数(ここではラムダ関数)は、オブジェクトが作成されるときに実行されます。この関数の戻り値が、インスタンス変数の値になります。

 なぜこうしたことが必要なのか、より詳しく知りたい方は、「浅い複製」「深い複製」のキーワードで、ネットを調べてみてください(この本では割愛します)。

 次は、マップについての変数を書きます。

# マップ
map_w: int = 60
map_h: int = 40
data_map: map.Map = field(default_factory = lambda: map.Map.from_wh(0, 0))
map_events: list[map_event.Event] = field(default_factory = list)

 マップdata_mapや、マップ イベントmap_eventsについても、同じように値とオブジェクトの生成関数を登録します。

 map_eventsのようにリストを生成するときは、default_factory = listと書くだけでよいです。

Gameクラス4 空引数からインスタンスを生成

 次は、クラス メソッドfrom_blank()です。

# 空引数から生成
@classmethod
def from_blank(cls) -> "Game":
d = Game()
growth.add_exp(d, 0) # 経験値追加(レベル1の値を計算)
d.data_map = map.Map.from_wh(d.map_w, d.map_h)
d.data_map.gen(d.x, d.y) # マップ生成
d.map_events = map_event.gen_event_from_map(d) # イベント
return d

 データ クラスでは、自動でコンストラクターが作られます。しかし、初期化段階で値を設定したり、計算をおこなったりしたい場合もあります。そうしたときは、コンストラクターとは別に、オブジェクトを作成する関数を用意しておくとよいです。

 先ほどHPなどの値を他の場所で初期化しますと書きました。このfrom_blank()関数で初期化をおこないます。

 ここでは、レベルと能力値を計算するgrowth.add_exp()関数や、マップを生成するd.data_map.gen()関数、マップ イベントを生成するmap_event.gen_event_from_map()関数を書いています。これらの関数で値を生成します。

インスタンス保持用の変数

 最後は、Gameクラスのインスタンス オブジェクトを保持するdata変数です。

data: Game # インスタンス格納用

 モジュールの外から利用することを想定しています。data.game.dataのように使います。

 この変数にゲームで保存するデータが全てぶら下がるようにします。そうすることで、手軽に保存や復帰ができるようになります。


 次の内容については省略します。こちらは同人誌をご覧ください。


同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)

 技術系同人誌など まとめページ


トップページに戻る
Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2024 Cronus Crown (c)1997-2024 Masakazu Yanai
ご意見・お問い合わせはサイト情報 弊社への連絡までお願いします
個人情報の取り扱い、利用者情報の外部送信について