一つ前のページではゲームオーバーの設定方法について学習しました。
今回は ゲームクリアの設定方法 について見ていきましょう。
Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
・Chapter3-1:衝突判定に基本を理解しよう
・Chapter3-2:画面に敵を配置しよう
・Chapter3-3:ゲームオーバーを設定しよう
・Chapter3-4:ゲームクリアを設定しよう ◁今回はここ
・Chapter3-5:追跡してくる敵を実装しよう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
Chapter6:pygameのお役立ち情報
これまでの章では、プレイヤーキャラクター(猫)の移動や、敵との衝突によるゲームオーバーの処理を実装してきました。
今回の章ではついに「ゲームクリア」の処理を追加し、プレイヤーがゴール地点に到達したときにゲームが終了する演出を取り入れていきます。
ゲームにゴールを設定することで、単なる「避けゲー」から「目的地を目指すゲーム」へと進化し、プレイヤーに達成感を与えることができます。
学習内容としては、画面への画像表示、キャラクターとの当たり判定、そして画面の切り替えといった重要な要素を扱っていきます。
それでは、さっそくゴール地点の設置から始めていきましょう!
ゲームクリアの条件とは?概要を確認
ゲームクリアとは、プレイヤーがゲーム内で定められた目標やゴールを達成したときに表示される演出や処理のことです。
たとえば敵をすべて倒したときや、特定の場所にたどり着いたときにゲームクリアとするケースが一般的です。
今回制作しているアクションゲームでは、画面右下に猫が好きな「魚の山」を設置し、これをゴール地点とします。
プレイヤーが操作する猫がこの魚の山に接触するとゲームがクリアとなり、特別な「ゲームクリア画面」に切り替わるようにします。
ゴール画像の設置と表示
ゲームクリアの判定を行うには、まずゴール地点をゲーム画面に表示する必要があります。
今回はゴールとして魚の山の画像を使用します。これを画面右下に配置することで、プレイヤーが目指す場所を視覚的にわかりやすくします。
魚の山を表示するためには、以下の手順を踏みます。
画像の読み込みとリサイズ
まずは使用する画像ファイルを読み込みます。
画像のファイル名は sakana.png
とし、images
フォルダの中に保存しておきましょう。
pygame.image.load()
で画像を読み込み、pygame.transform.scale()
でサイズを変更しています。
ここではゴール地点としてわかりやすいように、100×100ピクセルの大きさに調整しています。
ゴールの座標設定
次に画面のどこに画像を表示するかを指定します。
今回は画面右下の少し上(座標:680, 480)に配置します。
このコードでは Rect
(矩形)オブジェクトを使って、画像の表示位置とサイズを定義しています。
この矩形は、後ほど衝突判定にも使用します。
画面への描画方法
最後に、gamestage()
関数の中で画像を描画します。
blit()
関数を使うことで、画面に画像が表示されます。
プレイヤーとゴールの衝突を判定
次はプレイヤーがゴールにたどり着いたかどうかを判定し、ゲームクリア画面に切り替える処理を追加します。
この判定には、矩形同士の衝突(当たり判定)を行う colliderect()
関数 を使用します。
この colliderect()
は、2つの Rect
オブジェクトが重なっているかどうかを調べる関数です。
重なっていれば True
が返され、今回のように page = 3
としてゲームクリア画面へ進めるようにできます。
page
という変数は、現在の画面状態を表すために使用しています。これまでの処理では:
page == 1
→ 通常のゲームプレイ画面page == 2
→ ゲームオーバー画面page == 3
→ ゲームクリア画面
というように使い分けています。
今回の処理では猫が魚の山に触れた瞬間に page
を 3
に変更して、メインループ内でゲームクリア画面を表示させています。
ゲームクリア画面の作成
プレイヤーが無事ゴール地点に到達したら、ゲームがクリアされたことを知らせる特別な画面を表示しましょう。
ゲームクリア画面の見た目を作成し、リセットボタンを設置して再挑戦できるようにする方法を学びます。
ゲームクリア画面の関数を作る
まずゲームクリア画面専用の関数を定義します。この関数は page == 3
のときに呼び出されます。
順を追って、各部分の意味を説明します。
背景とテキストの描画
ゲームクリア時は画面の背景を明るく目立つ色にし、中央に「GAMECLEAR」という文字を表示します。
screen.fill(pygame.Color("GOLD")) font = pygame.font.Font(None, 150) text = font.render("GAMECLEAR", True, pygame.Color("RED")) screen.blit(text, (60,200))
screen.fill()
:画面全体を指定した色で塗りつぶします。pygame.font.Font()
:テキストのフォントとサイズを指定します。render()
:指定した文字列を描画可能なオブジェクトに変換します。blit()
:テキストを画面に描画します。
リセットボタンの追加
クリア後にもう一度プレイしたいときのために、「リプレイボタン(resetボタン)」を設置します。
btn1 = screen.blit(replay_img, (320,480)) button_to_jump(btn1, 1)
このボタンはあらかじめ画像として読み込んだ replaybtn.png
を使い、クリックされたときにゲーム画面(page = 1
)に戻るようになっています。
メインループへの追加
ゲームのメインループに以下の分岐を追加することで、page == 3
のときに gameclear()
が呼び出されるようにします。
まとめ
今回はゲームに「ゴール地点」を設け、プレイヤーがその場所にたどり着いたときに「ゲームクリア」となる処理を実装しました。
これによりゲームに目的が生まれ、プレイヤーに達成感を与えることができるようになりました。
ここまで学習してきたあなたは、アクションゲームの基本的な構成要素をしっかりと理解し、使いこなせるようになってきています。
次回はいよいよ、プレイヤーを追いかけてくる敵キャラクター「幽霊」を実装し、さらにゲーム性を高めていきましょう。
お疲れさまでした!ぜひこの調子で、次のステップにも挑戦していきましょう。
- Chapter3-4の完成コード
-
今回の記事での完成するコード全体は↓↓の通りです。
必要な方は開いて確認しましょう。
# 初期化(ゲームの準備をする) import pygame, sys, random pygame.init() screen = pygame.display.set_mode((800,600)) ## 背景画像の設定 haikei_img = pygame.image.load("images/shibafu.png") haikei_img = pygame.transform.scale(haikei_img, (800, 600)) ## プレイヤーの猫の設定 neko_imgR = pygame.image.load("images/neko.png") neko_imgR = pygame.transform.scale(neko_imgR, (50,50)) neko_imgL = pygame.transform.flip(neko_imgR, True, False) neko_rect = pygame.Rect(50,50,50,50) # 猫のRect ## 敵の犬の設定 enemy_img = pygame.image.load("images/inu.png") enemy_img = pygame.transform.scale(enemy_img,(50,50)) enemys = [] # 複数の犬のRectを格納する空のリスト for i in range(13): wx = 100 + i * 50 wy = random.randint(20,550) enemys.append(pygame.Rect(wx,wy,50,50)) # 犬のRect ## 敵の幽霊の設定 ## ゴールの設定 sakana_img = pygame.image.load("images/sakana.png") sakana_img = pygame.transform.scale(sakana_img,(100,100)) sakana_rect = pygame.Rect(680,480,100,100) ## 壁の設定 walls = [pygame.Rect(0,0,800,20), pygame.Rect(0,0,20,600), pygame.Rect(780,0,20,600), pygame.Rect(0,580,800,20)] ## リセットボタンの設定 replay_img = pygame.image.load("images/replaybtn.png") ## メインループ内で使う変数 rightFlag = True # 猫の向き pushFlag = False # リセットボタンが押されたか page = 1 # 表示するページ(1:ゲーム画面、2:ゲームオーバー画面、3、ゲームクリア画面) # ここから関数の定義 ## ゲームステージ def gamestage(): global rightFlag global page # 画面の初期化 screen.blit(haikei_img, (0,0)) vx = 0 vy = 0 #ユーザー入力 key = pygame.key.get_pressed() if key[pygame.K_RIGHT]: # 右キーが押されたら右へ移動 vx = 4 rightFlag = True if key[pygame.K_LEFT]: # 左キーが押されたら左へ移動 vx = -4 rightFlag = False if key[pygame.K_UP]: # 上キーが押されたら上へ移動 vy = -4 if key[pygame.K_DOWN]: # 下キーが押されたら下へ移動 vy = 4 ## 猫の処理 neko_rect.x += vx neko_rect.y += vy if neko_rect.collidelist(walls) != -1: # 壁と衝突したらそれ以上動かない neko_rect.x -= vx neko_rect.y -= vy if rightFlag: # 猫の向きの指定 screen.blit(neko_imgR, neko_rect) else: screen.blit(neko_imgL, neko_rect) ## 犬の処理 for enemy in enemys: # enemysリストの全要素(敵のRect) screen.blit(enemy_img, enemy) if neko_rect.collidelist(enemys) != -1: # 猫と犬との衝突判定 page = 2 ## 幽霊の処理 ## ゴールの処理 screen.blit(sakana_img,sakana_rect) if neko_rect.colliderect(sakana_rect): # 猫と魚の山との衝突判定 page = 3 ## 壁の処理 for wall in walls: # wallsリストの全要素(壁のRect) pygame.draw.rect(screen, pygame.Color("DARKGREEN"),wall) ## ジャンプ関数(ボタンが押されたらnewpageへジャンプする) def button_to_jump(btn, newpage): global page, pushFlag #ユーザー入力 mdown = pygame.mouse.get_pressed() (mx, my) = pygame.mouse.get_pos() if mdown[0]: if btn.collidepoint(mx, my) and pushFlag == False: page = newpage pushFlag = True else: pushFlag = False ## リセット関数(リセットボタンが押されたらゲームをリセットする) def reset(): # 猫を再配置 neko_rect.x = 50 neko_rect.y = 50 # 犬を再配置 for i in range(13): enemys[i].x = 100 + i * 50 enemys[i].y = random.randint(20,550) # 幽霊を再配置 ## ゲームオーバー関数 def gameover(): reset() # リセット関数の呼び出し screen.fill(pygame.Color("NAVY")) font = pygame.font.Font(None, 150) text = font.render("GAMEOVER", True, pygame.Color("RED")) screen.blit(text, (100,200)) btn1 = screen.blit(replay_img,(320,480)) button_to_jump(btn1, 1) # ジャンプ関数の呼び出し ## ゲームクリア関数 def gameclear(): reset() # リセット関数の呼び出し screen.fill(pygame.Color("GOLD")) font = pygame.font.Font(None, 150) text = font.render("GAMECLEAR", True, pygame.Color("RED")) screen.blit(text,(60,200)) btn1 = screen.blit(replay_img,(320,480)) button_to_jump(btn1,1) # ジャンプ関数の呼び出し # メインループ 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()
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。