前回、敵の攻撃を実装しましたが、実はプレイヤーのHPがゼロになってもゲームを続けることが可能です。
プレイヤーのHPがゼロになった時の処理を実装していないからですね。
今回は、ちゃんとやられたらゲームオーバーになるようにしたいと思います。
ゲームオーバークラスの作成
まず、title.pyをファイル丸ごとコピーし、gameover.pyというファイル名で保存します。
Titleクラスを改造してGameoverクラスを作ります。
import pygame
from pygame.locals import *
import sys
import cursor
class Gameover():
def __init__(self):
self.select = 0
self.menu_font = pygame.font.Font("data/minamoji04.ttf", 32)
self.retry = self.menu_font.render(u"リトライ", True, (255, 255, 255))
self.exit = self.menu_font.render(u"やめる", True, (255, 255, 255))
self.cursor = cursor.Cursor(220, 230, (255, 255, 255))
def update(self):
if self.select == 0:
self.cursor.y = 230
elif self.select == 1:
self.cursor.y = 280
def draw(self, screen):
screen.fill((0, 0, 0))
screen.blit(self.retry, ((320 - (self.retry.get_width() / 2)), 225))
screen.blit(self.exit, ((320 - (self.exit.get_width() / 2)), 275))
self.cursor.draw(screen)
Titleクラスから必要ないものを削除していきます。
タイトルやクレジット表記は不要なので、関係する変数を削除します。
ゲームオーバーなので背景を赤にし、それに合わせて文字色を黒にしています。
これで、簡単ですがゲームオーバー画面ができました。
ゲームオーバーを実装する
それでは、作成したGameoverクラスを実際に使用していきましょう。
まずはsample.pyでgameover.pyファイルをインポートし、Gameoverクラスをインスタンス化します。
import gameover
class Main():
def __init__(self):
# ゲームオーバー画面を作成
self.gameover = gameover.Gameover()
さらに、update()関数とdraw()関数にゲームオーバー時の処理を追記します。
game_stateがGAMEOVERのときは、先ほど作成したself.gameoverを更新・描画する処理です。
def update(self):
elif game_state == GAMEOVER:
self.gameover.update()
def draw(self, screen):
elif game_state == GAMEOVER:
self.gameover.draw(screen)
さらに、key_handler()関数にも処理を追記していきます。
処理の内容についても、タイトル画面とほぼ同じです。
def key_handler(self):
elif game_state == GAMEOVER:
if event.type == KEYUP and event.key == K_SPACE:
if self.gameover.select == 0:
game_state = STAGE
elif self.title.select == 1:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN and event.key == K_UP:
if self.gameover.select > 0:
self.gameover.select -= 1
elif event.type == KEYDOWN and event.key == K_DOWN:
if self.gameover.select < 1:
self.gameover.select += 1
画面の切り替えを実装する
これで、ゲームオーバー状態時の処理は完了しました。
続いて、プレイ画面→ゲームオーバー画面への切り替えを実装します。
このゲームでは、プレイヤーのHPが要因は敵 or 敵の攻撃への接触のみなので、collision_detection()関数でゲーム状態を切り替えます。
def collision_detection(self):
# HPがセロになったらゲームオーバー
if self.hp.hp <= 0:
global game_state
game_state = GAMEOVER
これで、ゲームオーバーを実装することができました。
「リトライ」選択でリセットできるようにする
ゲームオーバーは実装できましたが、このままでは「リトライ」ができません。
key_handler()関数では「リトライ」を選択すると「game_stateがSTAGEに戻る」と書かれていますが、プレイヤーのHPの状態はそのままのため、「STAGEに戻る→プレイヤーのHPはゼロのまま→再びGAMEOVERに」となり、再チャレンジができません。
そこで、新たにゲーム状態をリセットする関数を作ります。
def reset(self):
#ゲーム状態をリセット
self.all.empty()
self.enemies.empty()
self.shots.empty()
self.items.empty()
self.missiles.empty()
self.load_enemy()
self.load_item()
self.player.rect.center = (288, 200)
self.all.add(self.player)
self.hp.hp = self.hp.max
スプライトグループのempty()関数は、すべてのスプライトを削除する関数です。
これでグループを一度空っぽにした後、再度アイテムや敵をロードしています。
アイテムや敵にはデフォルトコンテナが設定されているんで、作成後すぐに各グループに格納されますが、プレイヤーだけは手動で格納しています。
最後にHPをリセットして…と思ったところで、HPバーのself.hpと、create_enemys()でのself.hpの名前が被ってしまっていることに気づきました。
def create_enemys(self, data):
hp = int(data[5])
enemy.Enemy(self.time, self.image, self.pos, self.move_type, hp, self.name, self.prob_atk)
とりあえずcreate_enemys()のほうを修正しました。
このあたり、「とにかく動けばいいや」精神で継ぎ足し継ぎ足ししてきた弊害が出てきましたね…
ひとまず、これでゲームオーバー後に再チャレンジができるようになりました。