この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
「src/mymod/data/map.py」の説明です。マップのデータ用のモジュールです。
from random import seed, randrangefrom dataclasses import dataclass
SEED = None # ランダムのシード値(None or int)PLAIN = 0FOLEST = 1MOUNTAIN = 2WATER = 3TOWN = 4CASTLE = 5
COLS = [ # ミニ マップ用色配列 (152, 232, 0), # 平地 ( 56, 104, 0), # 森 (192, 112, 0), # 山 ( 80, 128, 255), # 水 (232, 208, 32), # 街 (144, 64, 240) # 魔王城]
@dataclassclass Map: w: int h: int map:list[int] towns: list[list[int]]
# 初期化 @classmethod def from_wh(cls, w: int, h: int) -> "Map": res = Map(w, h, [], []) res.map = [PLAIN] * h * w return res
# マップ生成 def gen(self, start_x: int, start_y: int): seed(SEED) w, h, m = self.w, self.h, self.map
# 水 for i in range(int(w * 1.5)): x = randrange(w) y = randrange(h) for j in range(3): r = (j % 2) + 1 x2 = x + randrange(-r, r, 1) y2 = y + randrange(-r, r, 1) x2 = (x2 + w) % w y2 = (y2 + h) % h m[x2 + y2 * w] = WATER
# 開始位置(周囲の水を消す) for i in range(9): x = start_x - 1 + i % 3 y = start_y - 1 + i // 3 m[x + y * w] = PLAIN
# 山と森 for i in range(w): x = randrange(w) y = randrange(h) for j in range(24): r = (j % 3) + 1 x2 = x + randrange(-r, r, 1) y2 = y + randrange(-r, r, 1) x2 = (x2 + w) % w y2 = (y2 + h) % h if j < 16: m[x2 + y2 * w] = FOLEST else: m[x2 + y2 * w] = MOUNTAIN
# 街と城 step = 5 area_w = w // (step * 3) area_h = h // (step * 3) for i in range(9): x = i % 3 y = i // 3 x2 = (x * step + 1) * area_w + randrange(area_w * 3) y2 = (y * step + 1) * area_h + randrange(area_h * 3) if i == 4: m[x2 + y2 * w] = CASTLE else: m[x2 + y2 * w] = TOWN self.towns.append([x2, y2])
インポート部分を示します。
from random import seed, randrangefrom dataclasses import dataclass
マップ生成にランダムを使うのでrandom
モジュールのseed
とrandrange
を読み込みます。また、dataclass
を使うので読み込みます。
冒頭では、ゲームで利用する定数を用意します。
SEED = None # ランダムのシード値(None or int)PLAIN = 0FOLEST = 1MOUNTAIN = 2WATER = 3TOWN = 4CASTLE = 5
SEED
の値を数値にすると、マップの配置を固定化できます。通常はNone
にして、毎回異なるマップにしています。
次は、ミニマップの色の配列です。ミニマップは、マップ画面の右上に表示する、小さなマップです。このミニマップの色を用意します。
COLS = [ # ミニ マップ用色配列 (152, 232, 0), # 平地 ( 56, 104, 0), # 森 (192, 112, 0), # 山 ( 80, 128, 255), # 水 (232, 208, 32), # 街 (144, 64, 240) # 魔王城]
マップを表すMap
クラスです。クラス メソッドfrom_wh()
を持ちます。このメソッドは、横幅と高さの引数から、自身のオブジェクトを作成します。
@dataclassclass Map: w: int h: int map:list[int] towns: list[list[int]]
# 初期化 @classmethod def from_wh(cls, w: int, h: int) -> "Map": res = Map(w, h, [], []) res.map = [PLAIN] * h * w return res
マップ生成のアルゴリズムです。random
のrandrange()
関数を利用して、一定の範囲に地形を散布していきます。
# マップ生成 def gen(self, start_x: int, start_y: int): seed(SEED) w, h, m = self.w, self.h, self.map
# 水 for i in range(int(w * 1.5)): x = randrange(w) y = randrange(h) for j in range(3): r = (j % 2) + 1 x2 = x + randrange(-r, r, 1) y2 = y + randrange(-r, r, 1) x2 = (x2 + w) % w y2 = (y2 + h) % h m[x2 + y2 * w] = WATER
# 開始位置(周囲の水を消す) for i in range(9): x = start_x - 1 + i % 3 y = start_y - 1 + i // 3 m[x + y * w] = PLAIN
# 山と森 for i in range(w): x = randrange(w) y = randrange(h) for j in range(24): r = (j % 3) + 1 x2 = x + randrange(-r, r, 1) y2 = y + randrange(-r, r, 1) x2 = (x2 + w) % w y2 = (y2 + h) % h if j < 16: m[x2 + y2 * w] = FOLEST else: m[x2 + y2 * w] = MOUNTAIN
# 街と城 step = 5 area_w = w // (step * 3) area_h = h // (step * 3) for i in range(9): x = i % 3 y = i // 3 x2 = (x * step + 1) * area_w + randrange(area_w * 3) y2 = (y * step + 1) * area_h + randrange(area_h * 3) if i == 4: m[x2 + y2 * w] = CASTLE else: m[x2 + y2 * w] = TOWN self.towns.append([x2, y2])
広大なマップを作ることを想定していないので、簡単なランダムで済ませています。ある程度以上大きなマップを作るなら、もっと構造化された作り方をした方がよいです。
また、きちんとマップを作るのなら、移動不能な場所を排除する必要があります。今回のゲームでは、そうしたマップが生成される可能性は低いので割愛しています。
random
モジュールのrandrange()
関数の説明を書きます。いくつかの引数を指定できます。
randrange()
関数 | 説明 |
---|---|
random.randrange(stop) |
0から始めて、1ずつ違う値を、stop 未満で作成する |
random.randrange(start, stop) |
start から始めて、1ずつ違う値を、stop 未満で作成する |
random.randrange(start, stop, step) |
start から始めて、step ずつ違う値を、stop 未満で作成する |
次の内容については省略します。こちらは同人誌をご覧ください。
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)