一つ前のチャプターではゲームにゲームオーバーを設定しました。
今回は プレイ時間の表示方法 について見ていきましょう。
Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
・Chapter5-1:画面にゾンビを出現させよう
・Chapter5-2:ゲームオーバーを設定しよう
・Chapter5-3:プレイ時間を表示しよう ◁今回はここ
・Chapter5-4:スコアを表示しよう
Chapter6:pygameのお役立ち情報
ゾンビシューティングゲームが少しずつ形になってきましたね。
前回はプレイヤーがゾンビにぶつかったときにゲームオーバーになる機能を追加しましたが、今回はゲームに「プレイ時間の表示」機能を追加していきます。
プレイ時間が画面に表示されると、プレイヤーは自分がどれだけ長く生き延びているのかを意識しながらプレイすることができ、ゲームの緊張感がグッと高まります。
本記事ではゲーム開始からの経過時間をカウントし、それを画面上に表示する方法を、順を追って丁寧に解説していきます。
本記事は会員向けの有料記事ですが、現在は期間限定で無料公開中です。
プレイ時間とは何か?
今回追加する「プレイ時間」とは、ゲームが始まってから現在までに経過した時間のことを指します。
今回は「秒数」で表します」。たとえばゲームを始めてから30秒経過していれば「TIME : 30 s」となります。
ゲームにおけるプレイ時間の表示には、以下のような意味やメリットがあります。
- プレイヤーの努力の可視化:どれだけ長くプレイできたかを確認できる
- 達成感の向上:長く生き延びたことが数字として残り、達成感を得られる
また、このゲームではプレイ時間に応じてスコアも加算される(Chapter5-4で追加)ため、プレイ時間は単なる装飾ではなく、ゲームの根幹に関わる重要な仕組みとなります。
プレイ時間を測定するには?
プレイ時間を測るには、ゲームが開始された時刻を記録し、その後の経過時間を計算する必要があります。
pygameではこのような処理を簡単に行うための便利な関数が用意されています。
pygame.time.get_ticks()
この関数は、pygameが初期化されてからの経過時間をミリ秒(1秒=1000ミリ秒)で返してくれる関数です。たとえば、ゲームが始まってから3秒経ったタイミングでこの関数を呼び出すと、3000という値が返ってきます。
この関数を使ってプレイ時間を測定するには、次のような流れで処理を行います。
- ゲーム開始時に
start_time
という変数に現在時刻を記録する。 - 毎フレームごとに
現在の時刻 - start_time
を計算する。 - 得られた値を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
を繰り返し更新しないためのフラグ。ゲーム終了時に一度だけ時間を保存し、画面が更新されるたびに再計算されてしまうのを防ぐ。
これらの変数は、スクリプトの冒頭部分(グローバル領域)に定義しておくことで、すべての関数からアクセス可能になります。
タイム表示用の関数を作成しよう
プレイ時間を画面に表示するには、時間を計算して文字として描画する専用の関数を作成するのが一般的です。
今回は show_time()
という関数を使ってこれを実現しています。
- 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()
をゲームオーバー時にも呼び出すことで、画面が切り替わってもプレイ時間が保持されたまま表示されるようになります。
ここで活躍するのが前章で解説した freeze_time
変数です。
この変数によって、「何度も end_time
を更新してしまう問題」を防ぎ、ゲームオーバーになった瞬間の時間を固定表示することができます。
リセット時に時間も初期化しよう
プレイヤーがゲームオーバーになったあとに「もう一度プレイしたい」と思ったとき、Enterキーを押すことでゲームが最初から再スタートできるようになっています。
この処理は reset()
関数で行われています。
ここで大切なのが、プレイ時間のリセットです。前回のプレイで計測された時間が次のプレイに持ち越されないように、ゲーム再開時には時間関連の変数も初期化する必要があります。
リセット時にも時間の管理をきちんと行うことで、ゲームが何度でも正しく繰り返しプレイできるようになります。
まとめ
今回はゾンビを倒すシューティングゲームに「プレイ時間の表示機能」を追加しました。
ゲームをプレイしている間に時間がリアルタイムで表示されることで、プレイヤーの集中力や達成感を高めることができました。
また、ゲームが終了した後にもそのプレイ時間が画面に残るように工夫を加えることで、結果を見返す楽しさも生まれました。
こういった小さな機能の積み重ねが、ゲームの完成度やプレイヤー体験をぐっと向上させてくれます。
次回のChapter5-4では、この時間と連動する「スコアの表示機能」を追加していきます。
スコアが表示されるようになるとゲームのやり込み要素がグッと増し、さらに楽しい作品に仕上がっていきます。
あなたには着実にゲーム開発の力が身に付いています。引き続き、楽しみながら一歩一歩進んでいきましょう!
- 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()
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。