先ずゲームをどのように改良するかを決めます。
1.選択した面の番号を表示する。
2.同じ面を最初からやり直すリセット機能を追加する。
3.クリアしたらその旨を表示する。
4.プレー途中で諦めたら選択画面に戻れるようにする。
5.現在の歩数を表示する。
リセットするには「R」キーを押し、選択画面に戻るには「space」キーを押すことにし、その情報も画面に表示した方が親切ですね。これらの表示は、「sysfont = pygame.font.SysFont(None, 30)」とフォントを使うことを宣言し、souko.pyのメインループに以下のコードを追加するだけです。しかし文字が面画像にまではみ出たので、オフセットの「200」を変更しましょう。ところが選択画面で98面を選ぶと、面がはみ出てしまいました。つまりSCR_RECTの数値を面データの大きさに合わせて変更しなければなりません。今回は、最大値が98面ですからSCR_RECT = Rect(0, 0, 1200, 480)に変更し、OFFSET = 300に変更します。
# 文字表示 now = sysfont.render('Stage : '+ str(map.index), True, (255,255,255)) # stage No 表示 select = sysfont.render('Select : space key', True, (255,255,255)) # space Key 表示 count = sysfont.render('Counter : '+ str(player.counter), True, (255,255,255)) # Counter No 表示 back = sysfont.render('Back : "Back space" key', True, (255,255,255)) # back key 表示 reset = sysfont.render('Reset : "R" key', True, (255,255,255)) # reset key 表示 screen.blit(now, (0, 10)) screen.blit(select, (0, 40)) screen.blit(count, (0, 70)) screen.blit(back, (0, 100)) screen.blit(reset, (0, 130))
ところがここで不具合が明らかになりました。表示された文字がチカチカするのです。そこでSoukoクラスのdrawChar()メソッドからpygame.display.update()を削除し、それをPlayerクラスに移しました。これでチカチカが治りました。面番号と歩数はもう表示されています。back spaceキーも正しく機能しています。
次は「space」キーを押した時の処理です。「space」キーには、面選択画面に戻る機能を付けましょう。クリアできずに諦めた時と、クリアした時に「space」キーが押されます。souko.pyのmain()メソッドに変数clearFlagを定義し、キーイベントに以下を追加します。またキーイベントの外側にクリア時のコードを追加し、クリアした時にclearFlag = 1とします。このフラグは後で使います。
if event.type == KEYDOWN and event.key == K_SPACE: map.stage.clear() # stage[]クリア self.main() # main()メソッドを実行 if map.bags == map.stored: # 収納完了時 clearFlag = 1 end = sysfont1.render('Stage : '+ str(map.index) + ' Cleared!!', True, (0,255,255)) screen.blit(end, (0, 400))
次はリセット時に「R」キーを押した時の処理です。PlayerクラスにresetStage()メソッドを作ります。3-4行では荷物の履歴配列の1番目の要素を現在の配列にコピーし、最初の座標に戻しています。5-6行ではプレーヤーの座標を最初に戻しています。7-9行では、履歴配列の最初の要素を残して全部消去しています。つまりこのメソッドは、履歴配列をリセットするものです。
001: def resetStage(self, map): 002: self.counter = 0 003: map.bags = copy.deepcopy(map.bagsHis[0]) 004: map.stored = copy.deepcopy(map.storedHis[0]) 005: self.dir = map.playerHis[0][0] # playerは 006: (self.x, self.y) = map.playerHis[0][1] # 初期位置に戻す 007: del map.bagsHis[1:] # index1 を残して全部削除 008: del map.storedHis[1:] # index1 を残して全部削除 009: del map.playerHis[1:] # index1 を残して全部削除
あとはsouko.pyのキーイベントに以下を追加するだけですね。しかしテストしていたら突然画面を閉じられなくなったため、MapクラスのgetStage()メソッドにもキーイベントの終了処理を追加しました。
if event.type == KEYDOWN and event.key == K_r: # reset player.resetStage(map)
これで完璧と信じてさらにテストしていたら、players.pyの19行目で「'NoneType' object is not subscriptable」と怒られたので、players.pyのコンストラクタの前に「pos = []」を追加し、コンストラクタに「self.pos = pos」を追加しました。今のところエラーは出ていませんので、さらに改良を続けます。
現時点におけるsoukoフォルダ内の各ファイルを掲載しておきます。
button.py
mapStage.py
players.py
souko.py