ゲームオーバー画面を作成する

前回、敵の攻撃を実装しましたが、実はプレイヤーの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()のほうを修正しました。

このあたり、「とにかく動けばいいや」精神で継ぎ足し継ぎ足ししてきた弊害が出てきましたね…

ひとまず、これでゲームオーバー後に再チャレンジができるようになりました。

ソースコードのダウンロード