マップのロード
今までマップはスクリプト内に書いて固定されていましたが、ファイルからさまざまなマップを読み込めるように変更してみます。
スクリプトを全文掲載すると長くなるので、ここからは主要部分のみ掲載することにします。スクリプトファイルはダウンロードしてください。
マップファイルの構造
15 20 11111111111111111111 10000000000000000001 10000000000000000001 10000000000000000001 10000000000000000001 10000000000000000001 10000000011000000001 10000000011000000001 10000000000000000001 10000000000000000001 10000000000000000001 10000000000000000001 10000000000000000001 10000000000000000001 11111111111111111111
上のようなマップファイル(test.map)を用意します。0は
で1は
です。今までのマップと違って真ん中に湖を作りました。今回からマップのサイズもいろいろ変えられるようにファイルで指定します。1行目がマップのサイズで行数と列数です。
マップファイルの読み込み
マップファイルを読み込んでいるのはMapクラスです。
class Map: images = [None] * 256 # マップチップ(番号->イメージ) def __init__(self, name): self.name = name self.row = -1 # 行数 self.col = -1 # 列数 self.map = [] # マップデータ(2次元リスト) self.load() def load(self): """ファイルからマップをロード""" file = os.path.join("data", self.name + ".map") # テキスト形式のマップを読み込む fp = open(file) lines = fp.readlines() # ファイル全体を行単位で読み込む row_str, col_str = lines[0].split() # 行数と列数 self.row, self.col = int(row_str), int(col_str) # int型に変換 for line in lines[1:]: # マップデータを読み込む line = line.rstrip() # 改行除去 self.map.append([int(x) for x in list(line)]) fp.close()
前回までとは違って、rowとcolとmapがインスタンス変数になったことに注意してください。またマップのコンストラクタでマップ名nameを引数として渡しています。マップのロードはload()関数で行い、row、col、mapにマップファイルから読み込んだデータをセットしています。マップファイルの名前はコンストラクタで渡したマップ名に拡張子(.map)を加えた
Pythonでファイルを読み込むのは非常に簡単です。open()でファイルを開いて、readlines()で行単位で読み込んでリスト linesに格納します。マップデータは1行ずつ読み込み、int型に変換したうえで、self.mapに追加しています。今までと同じように self.mapは二次元リストのマップデータが格納されます。Pythonでファイルを扱うのが初めての人は上のサンプルスクリプトの途中にprint 文を挿入して各変数に何が格納されるか調べてみると理解しやすいと思います。
マップを作るのはmain()関数です。
# マップの作成 map = Map("test")
上のように書くとtest.mapからデータを読み込んだMapオブジェクトが作られます。他のファイルから読み込みたければtestの部分を変えます。
これでファイルからマップを読み込めるようになりましたが、大きいマップになるとマップファイルを自分で書くのは非常に面倒です。あとでマップエディタを作ってマップファイルを簡単に作れるようにしてみます。