マップの新規作成
今回は新しいマップを作れるようにします。新しいマップを作るときはマップの名前、行数、列数、デフォルトマップチップを指定します。これらの情報を入力する必要がありますが、Pygameにはテキストボックスが用意されていません。自作する必要があります。RPG編のメッセージウィンドウの表示(2008/6/28)で作成したWindowクラスを拡張してキー入力を読み取れるInputWindowも合わせて作ります。
マップの新規作成はNキーです。マップ名、行数、列数、デフォルトマップチップを入力すると新しいマップが作られます。今まで作ってたマップは消えてしまうので注意してください。
テキストを入力する
キー入力を読み取るInputWindowを作成します。InputWindowは下のように使います。
name = input_wnd.ask(screen, "NAME?") row = int(input_wnd.ask(screen, "ROW?")) col = int(input_wnd.ask(screen, "COL?")) default = int(input_wnd.ask(screen, "DEFAULT?"))
InputWindowのask()を呼び出すと画面上にスクリーンショットのようなウィンドウが表示されます。このウィンドウでキーを入力するとテキストが表示されます。バックスペースキーでテキストを消すこともできます。入力できるのは大文字のアルファベットまたは数字だけです。日本語は入力できません。エンターキーを押すとウィンドウが消えて入力した内容はask()の戻り値になります。
InputWindowの詳細
InputWindowはRPG編のメッセージウィンドウの表示(2008/6/28)で作ったWindowクラスの拡張です。テキストはメッセージエンジン(2008/6/28)で作ったMessageEngineを使っています。
class InputWindow(Window): def __init__(self, rect, msg_engine): Window.__init__(self, rect) self.msg_engine = msg_engine def get_key(self): """キー入力を読み取る""" while True: event = pygame.event.poll() if event.type == KEYDOWN: return event.key else: pass def draw(self, screen, message): Window.draw(self, screen) if len(message) != 0: self.msg_engine.draw_string(screen, self.inner_rect.topleft, message) pygame.display.flip() def ask(self, screen, question): cur_str = [] self.show() self.draw(screen, question) while True: key = self.get_key() if key == K_BACKSPACE: cur_str = cur_str[0:-1] elif key == K_ESCAPE: return None elif key == K_RETURN: break elif K_0 <= key <= K_9 or K_a <= key <= K_z: cur_str.append(chr(key).upper()) self.draw(screen, question + u" " + "".join(cur_str)) return "".join(cur_str)
ask()でメッセージウィンドウを表示したらwhileループに入り、get_key()で入力したキーを取得してcur_strに追加しています。cur_strはdraw()で画面に描画されます。このコードは、InputBoxを参考に作成しました。残念ながらPygameでは日本語入力ができないようです。というかPygameの元になっているSDLでもできないようです。これだとMMORPGのチャットとかは作れないですね・・・何かいい方法があればいいんですが。
マップの新規作成
新規作成の処理はイベントハンドラに書いています。Nキーを押すとマップ名、行数、列数、デフォルトマップチップをたずねるInputWindowが表示されます。入力したデータで新しいMapオブジェクトを作り、mapに格納しています。
elif event.type == KEYDOWN and event.key == K_n: # 新規マップ try: name = input_wnd.ask(screen, "NAME?") row = int(input_wnd.ask(screen, "ROW?")) col = int(input_wnd.ask(screen, "COL?")) default = int(input_wnd.ask(screen, "DEFAULT?")) except ValueError: print "Cannot create map" continue map = Map(name, row, col, default, palette)
これで新しいマップを作れるようになったのですがまだ保存ができません。次回はマップを保存する機能を実装します。