ながみえ

一つ前のチャプターではゲームにゲームオーバーを設定しました。

今回は プレイ時間の表示方法 について見ていきましょう。

Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
 ・Chapter5-1:画面にゾンビを出現させよう
 ・Chapter5-2:ゲームオーバーを設定しよう
 ・Chapter5-3:プレイ時間を表示しよう ◁今回はここ
 ・Chapter5-4:スコアを表示しよう
Chapter6:pygameのお役立ち情報

ゾンビシューティングゲームが少しずつ形になってきましたね。

前回はプレイヤーがゾンビにぶつかったときにゲームオーバーになる機能を追加しましたが、今回はゲームに「プレイ時間の表示」機能を追加していきます。

プレイ時間が画面に表示されると、プレイヤーは自分がどれだけ長く生き延びているのかを意識しながらプレイすることができ、ゲームの緊張感がグッと高まります。

本記事ではゲーム開始からの経過時間をカウントし、それを画面上に表示する方法を、順を追って丁寧に解説していきます。

注意点

チャプター5を通してシューティングゲームを制作するにあたり、ベースとなるコードや使用する画像をまとめた「Chapter5_set.zip」を無料配布しています。

まだ入手していない人は、まずは pygameのトップページ に移動し、チャプター5の章から ダウンロード してください。

本記事は会員向けの有料記事ですが、現在は期間限定で無料公開中です。

<<前のページ

pygameの記事一覧

Pythonのゲームライブラリ pygame を使ってゲームアプリを制作するページのアイキャッチ画像

次のページ>>

プレイ時間とは何か?

今回追加する「プレイ時間」とは、ゲームが始まってから現在までに経過した時間のことを指します。

今回は「秒数」で表します」。たとえばゲームを始めてから30秒経過していれば「TIME : 30 s」となります。

ゲームにおけるプレイ時間の表示には、以下のような意味やメリットがあります。

  • プレイヤーの努力の可視化:どれだけ長くプレイできたかを確認できる
  • 達成感の向上:長く生き延びたことが数字として残り、達成感を得られる

また、このゲームではプレイ時間に応じてスコアも加算される(Chapter5-4で追加)ため、プレイ時間は単なる装飾ではなく、ゲームの根幹に関わる重要な仕組みとなります。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

プレイ時間を測定するには?

プレイ時間を測るには、ゲームが開始された時刻を記録し、その後の経過時間を計算する必要があります。

pygameではこのような処理を簡単に行うための便利な関数が用意されています。

pygame.time.get_ticks()

この関数は、pygameが初期化されてからの経過時間をミリ秒(1秒=1000ミリ秒)で返してくれる関数です。たとえば、ゲームが始まってから3秒経ったタイミングでこの関数を呼び出すと、3000という値が返ってきます。

この関数を使ってプレイ時間を測定するには、次のような流れで処理を行います。

  1. ゲーム開始時に start_time という変数に現在時刻を記録する。
  2. 毎フレームごとに 現在の時刻 - start_time を計算する。
  3. 得られた値を1000で割り、秒単位に変換する。

この方法で、ゲーム中にリアルタイムで正確な経過時間を取得することができます。

時間の表示に必要な変数の追加

プレイ時間を画面に表示するためには、ゲーム開始時刻を記録する変数や、時間の進行を制御するための変数を用意する必要があります。

zombie_shooting.pyにはすでに以下の3つの変数が書き込まれているはずです。

start_time = pygame.time.get_ticks()  # ゲーム開始時刻(ミリ秒)
end_time = 0                           # 終了時刻(ゲームクリアやオーバー時)
freeze_time = False                   # 時間の更新を止めるためのフラグ
  • start_time
    ゲームが開始された瞬間の時刻。これを基準として以降の経過時間を計算する。
  • end_time
    ゲームクリアやゲームオーバーになった瞬間の経過時間を一度だけ記録。
  • freeze_time
    end_time を繰り返し更新しないためのフラグ。ゲーム終了時に一度だけ時間を保存し、画面が更新されるたびに再計算されてしまうのを防ぐ。

これらの変数は、スクリプトの冒頭部分(グローバル領域)に定義しておくことで、すべての関数からアクセス可能になります。

【Python】勉強猫がノートパソコンを見ながら考え込む様子。記事内の休憩用イラスト

タイム表示用の関数を作成しよう

プレイ時間を画面に表示するには、時間を計算して文字として描画する専用の関数を作成するのが一般的です。

今回は show_time() という関数を使ってこれを実現しています。

コードを書いてみよう

「## ゲームステージ関数」の下に以下のコードを書き足してください。

## タイム表示関数
def show_time():
    global end_time, freeze_time
    font = pygame.font.Font(None, 50)  # フォントサイズを50に設定
    if page == 1:  # もしゲームプレイ中なら
        seconds = (pygame.time.get_ticks() - start_time) // 1000
        freeze_time = False
    else:  # もしゲームオーバーやクリア後なら
        if not freeze_time:
            end_time = (pygame.time.get_ticks() - start_time) // 1000
            freeze_time = True
        seconds = end_time

    text = font.render(f"TIME : {seconds} s", True, pygame.Color("YELLOWGREEN"))
    screen.blit(text, (20, 20))  # 画面の左上に表示
  • pygame.font.Font(None, 50)
    数字を描画するためのフォントサイズを設定。
  • (pygame.time.get_ticks() – start_time) // 1000
    ゲーム開始からの経過時間(秒)を計算。
  • pageの値によって処理を分岐
    page == 1 のときはゲーム中なので、リアルタイムで秒数を更新。
    それ以外(ゲームオーバーやゲームクリア)のときは、一度だけ end_time に時間を保存し、それを固定表示。
  • freeze_timeフラグの活用
    freeze_time によってゲーム終了後に時間が更新され続けないように制御。

このようにして、ゲーム中も終了後も、正しく時間が表示される仕組みになっています。

タイム表示関数の呼び出し

show_time() 関数を、実際にゲーム中の画面に時間を表示する処理として組み込むには、必要な個所で呼び出す必要があります。

コードを書いてみよう

「## ゲームステージ関数」の中に以下のコードを書き足しましょう。

    # タイムとスコアの処理
    show_time()  # タイム表示関数の呼び出し

また、「## ゲームオーバー関数」の中にも、以下のコードを書き足しましょう。

ジャンプ関数の上の行がおすすめです。

show_time()      # タイム表示関数の呼び出し

このように、show_time() をゲームオーバー時にも呼び出すことで、画面が切り替わってもプレイ時間が保持されたまま表示されるようになります。

ここで活躍するのが前章で解説した freeze_time 変数です。

この変数によって、「何度も end_time を更新してしまう問題」を防ぎ、ゲームオーバーになった瞬間の時間を固定表示することができます。

【Python】勉強猫がコーヒーを片手にリラックスしている様子。記事内の休憩用イラスト

リセット時に時間も初期化しよう

プレイヤーがゲームオーバーになったあとに「もう一度プレイしたい」と思ったとき、Enterキーを押すことでゲームが最初から再スタートできるようになっています。

この処理は reset() 関数で行われています。

ここで大切なのが、プレイ時間のリセットです。前回のプレイで計測された時間が次のプレイに持ち越されないように、ゲーム再開時には時間関連の変数も初期化する必要があります。

コードを書いてみよう

「## リセット関数」の中に以下のコードを書き足しましょう。

    start_time = pygame.time.get_ticks()
    freeze_time = False

リセット時にも時間の管理をきちんと行うことで、ゲームが何度でも正しく繰り返しプレイできるようになります。

まとめ

今回はゾンビを倒すシューティングゲームに「プレイ時間の表示機能」を追加しました。

ゲームをプレイしている間に時間がリアルタイムで表示されることで、プレイヤーの集中力や達成感を高めることができました。

また、ゲームが終了した後にもそのプレイ時間が画面に残るように工夫を加えることで、結果を見返す楽しさも生まれました。

こういった小さな機能の積み重ねが、ゲームの完成度やプレイヤー体験をぐっと向上させてくれます。

次回のChapter5-4では、この時間と連動する「スコアの表示機能」を追加していきます。

スコアが表示されるようになるとゲームのやり込み要素がグッと増し、さらに楽しい作品に仕上がっていきます。

あなたには着実にゲーム開発の力が身に付いています。引き続き、楽しみながら一歩一歩進んでいきましょう!

Q
Chapter5-3の完成コード

今回の記事での完成するコード全体は↓↓の通りです。

必要な方は開いて確認しましょう。

# 初期化(ゲームの準備をする)
import pygame, sys, random
pygame.init()
screen = pygame.display.set_mode((800, 600))
haikei_img = pygame.image.load("images/hakaba.png")
haikei_img = pygame.transform.scale(haikei_img, (800, 600))
## プレイヤーデータ
player_img = pygame.image.load("images/Player.png")
player_img = pygame.transform.scale(player_img, (60, 100))
player_rect = pygame.Rect(370, 500, 60, 100)
## 銃弾データ
bullet_img = pygame.image.load("images/bullet.png")
bullet_img = pygame.transform.scale(bullet_img, (8, 16))
bullet_rect = pygame.Rect(0, -100, 8, 16)
## ゾンビデータ
zombie_img = pygame.image.load("images/Zombie.png")
zombie_img = pygame.transform.scale(zombie_img, (60, 100))
zombies = []  # ゾンビの位置情報を入れるためのゾンビリスト
for i in range(10):
    zombie_x = random.randint(0, 800)       # 横の位置をランダムに決定
    zombie_y = -100 * i                      # 縦方向に等間隔で並べる
    zombies.append(pygame.Rect(zombie_x, zombie_y, 60, 100))  # ゾンビ1体分の情報をリストに追加
## リプレイボタンデータ
replay_img = pygame.image.load("images/replaybtn.png")
## 変数
page = 1
mx = 370
hit = 0
score = 0
start_time = pygame.time.get_ticks()  # ゲーム開始時の時間
end_time = 0  # ゲーム終了時の時間
freeze_time = False  # 時間の停止状態


# ここから各関数の定義
## ゲームステージ関数
def gamestage():
    global mx, page, hit, score, start_time
    screen.blit(haikei_img, (0, 0))
    # ユーザー入力
    key = pygame.key.get_pressed()
    # プレイヤーの処理
    if key[pygame.K_RIGHT]:
        mx += 5
    if key[pygame.K_LEFT]:
        mx -= 5
    mx = max(0, min(740, mx)) # プレイヤーが画面端から出ていかないようにする
    player_rect.x = mx
    screen.blit(player_img, player_rect)
    # 銃弾の処理
    if key[pygame.K_SPACE] and bullet_rect.y < 0:
        bullet_rect.x = player_rect.x +30 - 4
        bullet_rect.y = player_rect.y
    if bullet_rect.y >= 0:
        bullet_rect.y += -30
        screen.blit(bullet_img, bullet_rect)
    # ゾンビの処理
    for zombie in zombies:
        zombie.y += 5  # ゾンビを毎フレームごとに5ピクセル下に移動
        screen.blit(zombie_img, zombie)  # ゾンビ画像を画面に描画
        if zombie.y > 600: # もし画面下に到達したら
            zombie.x = random.randint(0, 800)
            zombie.y = -100
        # プレイヤーとの衝突判定
        if zombie.colliderect(player_rect):
            page = 2
        # 銃弾との衝突判定
        if zombie.colliderect(bullet_rect): # もしゾンビが銃弾と衝突したら
	        # ゾンビを画面外に移動
            zombie.y = -100
            zombie.x = random.randint(0, 800)
            # 弾を画面外へ移動
            bullet_rect.y = -100
    # タイムとスコアの処理
    show_time()  # タイム表示関数の呼び出し


## ゲームクリア関数

## ゲームオーバー関数
def gameover():
    screen.blit(haikei_img, (0, 0))  # 背景画像を表示
    btn1 = screen.blit(replay_img, (320, 480))  # リプレイボタン画像を表示
    font1 = pygame.font.Font(None, 150)  # フォントサイズ150で設定
    text = font1.render("GAMEOVER", True, pygame.Color("RED"))  # 「GAMEOVER」の赤い文字を描画
    screen.blit(text, (100, 200))  # テキストを画面中央に描画
    show_time()      # タイム表示関数の呼び出し
    button_to_jump()  # ジャンプ関数の呼び出し
## ジャンプ関数
def button_to_jump():
    global page
    key = pygame.key.get_pressed()  # キーの入力状態を取得
    if key[pygame.K_RETURN]:  # もしEnterキーが押されたら
        reset()               # リセット関数の呼び出し
        page = 1              # 再びゲームプレイ画面に切り替え
## リセット関数
def reset():
    global score, mx, hit, start_time, freeze_time
    score = 0             # スコアをリセット
    mx = 400              # プレイヤーの初期X座標
    # Chapter5-4でここにヒット数リセットを追加
    bullet_rect.y = -100  # 弾の位置をリセット(非表示位置へ)
    start_time = pygame.time.get_ticks()
    freeze_time = False
    for i in range(10):
        zombies[i] = pygame.Rect(random.randint(0, 800), -100*i, 50, 50)  # ゾンビの位置を再設定
## タイム表示関数
def show_time():
    global end_time, freeze_time
    font = pygame.font.Font(None, 50)  # フォントサイズを50に設定
    if page == 1:  # もしゲームプレイ中なら
        seconds = (pygame.time.get_ticks() - start_time) // 1000
        freeze_time = False
    else:  # もしゲームオーバーやクリア後なら
        if not freeze_time:
            end_time = (pygame.time.get_ticks() - start_time) // 1000
            freeze_time = True
        seconds = end_time
    text = font.render(f"TIME : {seconds} s", True, pygame.Color("YELLOWGREEN"))
    screen.blit(text, (20, 20))  # 画面の左上に表示

## スコア表示関数


# メインループ
while True:
    if page == 1:
        gamestage()   # ゲームプレイ中の処理
    elif page == 2:
        gameover()    # ゲームオーバー時の処理

    #画面描写
    pygame.display.update()
    pygame.time.Clock().tick(60)
    #終了処理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

<<前のページ

pygameの記事一覧

Pythonのゲームライブラリ pygame を使ってゲームアプリを制作するページのアイキャッチ画像

次のページ>>

質問用コンタクトフォーム

この記事を書くにあたりAIを活用しています。

人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。

pygame記事一覧へ戻る
Python記事一覧へ戻る

記事URLをコピーしました