前の頁へ   次の頁へ

老い学の捧げ物 Part Ⅰ

8.文字情報の表示

先ずゲームをどのように改良するかを決めます。
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

前の頁へ   次の頁へ