一つ前のチャプターでは画面にプレイ時間を表示させる方法を学習しました。
今回は 画面にスコアを表示 し、いよいよゲームを完成させます。
Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
・Chapter5-1:画面にゾンビを出現させよう
・Chapter5-2:ゲームオーバーを設定しよう
・Chapter5-3:プレイ時間を表示しよう
・Chapter5-4:スコアを表示しよう ◁今回はここ
Chapter6:pygameのお役立ち情報
ここまでのチャプターを通して、あなたはプレイヤーの操作方法を学び、敵を出現させて撃退する仕組みや、ゲームオーバーの判定、プレイ時間の表示など、少しずつゲームとしての形を整えてきました。
いよいよこの章で「ゾンビを倒すシューティングゲーム」が完成します。
今回のテーマは「スコアの表示」です。
ゲームにおけるスコアとは、プレイヤーの頑張りを数値化する仕組みです。これによりプレイヤーは「どれくらいゾンビを倒したか」や「どれだけ長く生き残れたか」を客観的に振り返ることができます。
スコア機能があることで、ゲームはぐっと楽しく、やりがいのあるものになります。
この章は pygameを使ったゲーム制作の集大成 です。
これまでのすべての知識を活かし、完成度の高いゲームを一緒に作り上げていきましょう。
本記事は会員向けの有料記事ですが、現在は期間限定で無料公開中です。
スコアとは?どのように計算するのか
まずは「スコア」という概念について確認しておきましょう。
スコアとは、ゲーム中のプレイヤーの成果や成績を数値で表したものです。
アクションゲームやシューティングゲームでは、「何体の敵を倒したか」「どれだけ早くクリアしたか」などに応じてスコアが計算され、プレイヤーの腕前を数値で示すことができます。
このゲームでは以下の2つの要素をもとにスコアを計算します。
- ゾンビを倒した回数(変数
hit
) - ゲームのプレイ時間(秒数、変数
seconds
)
この2つを組み合わせ、以下の式でスコアを算出することにしました。
score = hit * 1000 + seconds * 100
- ゾンビを1体倒すごとに1000点加算
- 1秒プレイするごとに100点加算
つまり、たくさんのゾンビを倒し、長く生き延びることで高スコアが得られる仕組みになっています。
そしてこのスコアが50,000点を超えたときに、ゲームクリアとしましょう。
ゲーム中にスコアを計算して表示しよう
スコアの計算方法が分かったところで、実際にゲーム中にスコアをリアルタイムで計算し、画面に表示してみましょう。
今回の変更で行うのは以下の3点です。
- スコアを計算する処理の追加
- スコアを画面に描画する関数の作成
- ゲームプレイ中にその関数を呼び出す
スコアの計算処理を追加
ゾンビを倒した数を数え、それと経過時間からスコアを計算するコードを作成しましょう。
これでプレイ中にリアルタイムでスコアが更新されるようになります。
スコア表示用の関数を作成
スコアは時間と同様に画面の左上に表示するのが分かりやすいため、新しくshow_score()
という関数を作って、スコアを描画します。
この関数を、show_time()
と並べて使うことで、時間とスコアを同時に表示できます。
最後に、「## ゲームステージ関数」の中の「# タイムとスコアの処理」の部分に、この「show_score()関数」の呼び出しを行うコードを書きましょう。
ゲームクリア機能を追加しよう
スコアを表示する仕組みを追加しましたが、ここではそのスコアを使ってゲームクリアの判定を実装します。
スコアが目標に到達したらゲームクリアへ
今回はスコアが 50,000点以上 に到達するとゲームクリアとなるように設定します。
これでスコアが条件を満たしたときにゲーム画面がゲームクリア画面へと切り替わるようになります。
ゲームクリア画面の実装
スコア条件を満たした後に表示する「ゲームクリア画面」を新しく作る必要があります。gameclear()
関数を作成しましょう。
この画面では「GAMECLEAR」の文字に加えて、クリア時の時間とスコアも表示されるようにしています。
メインループでgameclearを呼び出す
最後に、メインループ内のページ管理において page == 3
のときにgameclear()
が呼ばれるようにします。
これでスコアが5万点を超えると自動的にゲームクリア画面に移動し、見た目にも達成感のある演出が実現できます。
最後の仕上げ
ゲームを繰り返しプレイする場合、前回のスコアやヒット数が残ったままだと、正しくスコアを計算できません。
そのため、ゲームをリセットする際には ゾンビを倒した回数(hit
)の値もリセットする必要があります。
「## リセット関数」の中に「hit = 0」という行をいれましょう。
また、ゲームオーバー画面でもスコアが表示されるように、「## ゲームオーバー関数」の中に「show_score()関数」を入れておきましょう。
まとめ
これにて、ゾンビを倒すシューティングゲームの制作がすべて完了しました。
Chapter5-1から始まり、ゾンビの出現、ゲームオーバーの設定、時間の表示、そしてこの最終章ではスコアの計算と表示、ゲームクリアの実装と、少しずつ機能を積み重ねて一つの完成されたゲームへと仕上げることができました。
またpygameを使ったゲーム制作講座自体も、ここで一区切りとなります。ここまで読み進め、実際に手を動かしながら学習を続けてきた皆さん、本当にお疲れさまでした。
「プログラミングでゲームが作れる」── これは多くの人が夢見る体験です。そして今、あなたはその夢を実現しました。
ここからはあなた自身のアイデアでキャラクターを変えてみたり、さらに独自のゲームを発展させてみるのも面白いでしょう。後述の「チャレンジ!さらに面白いゲームに改造しよう!」にも是非挑戦してください^^
これまで学んだ知識は、きっとあなたの創作活動の力になります。
ぜひこれからも楽しみながら、プログラミングの世界を広げていってください!
- Chapter5-4の完成コード
-
今回の記事での完成するコード全体は↓↓の通りです。
必要な方は開いて確認しましょう。
# 初期化(ゲームの準備をする) 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): # もしゾンビが銃弾と衝突したら hit += 1 # ゾンビを画面外に移動 zombie.y = -100 zombie.x = random.randint(0, 800) # 弾を画面外へ移動 bullet_rect.y = -100 # タイムとスコアの処理 seconds = (pygame.time.get_ticks() - start_time) // 1000 score = hit * 1000 + seconds * 100 show_time() # タイム表示関数の呼び出し show_score() # スコア表示関数の呼び出し if score >= 50000: page = 3 ## ゲームクリア関数 def gameclear(): screen.blit(haikei_img, (0, 0)) # 背景を描画 btn1 = screen.blit(replay_img, (320, 480)) # リプレイボタンを表示 # ゲームクリアの文字を表示 font1 = pygame.font.Font(None, 150) text = font1.render("GAMECLEAR", True, pygame.Color("SKYBLUE")) screen.blit(text, (50, 200)) show_time() # プレイ時間の表示 show_score() # スコアの表示 button_to_jump() # エンターキーで再スタートするための処理 ## ゲームオーバー関数 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() # タイム表示関数の呼び出し show_score() # スコアの表示 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座標 hit = 0 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)) # 画面の左上に表示 ## スコア表示関数 def show_score(): font = pygame.font.Font(None, 50) # フォントサイズ50の文字を作る text = font.render("SCORE : " + str(score), True, pygame.Color("YELLOWGREEN")) # スコア表示用の文字列を作る screen.blit(text, (20, 60)) # 画面の左上に描画 # メインループ while True: if page == 1: gamestage() elif page == 2: gameover() elif page == 3: gameclear() #画面描写 pygame.display.update() pygame.time.Clock().tick(60) #終了処理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
チャレンジ!さらに面白いゲームに改造しよう!
ゾンビシューティングゲームの製作講座はここで終了ですが、このゲームはまだまだ面白くできる余地があるとおもいませんか?
以下のアイディアをベースにして、あなたの手でより面白いゲームへ作り変えてみて下さい。
ダウンロードした画像ファイルなども有効活用してくださいね^^
- 銃を連射可能に改造:銃弾データをゾンビデータのようにリスト化すれば可能
- 必殺技の実装:限られた回数だけ使える技で、画面中の敵を一掃
- ゾンビ以外の敵:違った動きをする敵がいるとよりゲーム性が上がる
- プレイヤーを追跡する敵:Chapter3の学習内容を活用
- ボスの実装:スコアが一定以上になると特別な敵が出現
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。