ながみえ

一つ前のページではゲームオーバーの設定方法について学習しました。

今回は ゲームクリアの設定方法 について見ていきましょう。

Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
 ・Chapter3-1:衝突判定に基本を理解しよう
 ・Chapter3-2:画面に敵を配置しよう
 ・Chapter3-3:ゲームオーバーを設定しよう
 ・Chapter3-4:ゲームクリアを設定しよう ◁今回はここ
 ・Chapter3-5:追跡してくる敵を実装しよう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
Chapter6:pygameのお役立ち情報

これまでの章では、プレイヤーキャラクター(猫)の移動や、敵との衝突によるゲームオーバーの処理を実装してきました。

今回の章ではついに「ゲームクリア」の処理を追加し、プレイヤーがゴール地点に到達したときにゲームが終了する演出を取り入れていきます。

ゲームにゴールを設定することで、単なる「避けゲー」から「目的地を目指すゲーム」へと進化し、プレイヤーに達成感を与えることができます。

学習内容としては、画面への画像表示、キャラクターとの当たり判定、そして画面の切り替えといった重要な要素を扱っていきます。

それでは、さっそくゴール地点の設置から始めていきましょう!

注意点

Chapter3-1から3-5でまでを通して1つのゲームを作成しています。

直接このページに来た人は pygameのトップページ から基本セットを 無料 でダウンロードしてChapter3-1から学習を始めるか、以下のコードをコピーしてください。

Q
Chapter3-3の完成コード
# 初期化(ゲームの準備をする)
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))  # 画像サイズを50x50ピクセルに変更
enemys = []  # 犬の位置情報を格納する空のリストを作る
for i in range(13):  # 13体の敵を生成
    wx = 100 + i * 50  # 横方向に等間隔で配置
    wy = random.randint(20, 550)  # 縦の位置はランダムに
    enemys.append(pygame.Rect(wx, wy, 50, 50))  # リストに敵のRect(位置と大きさ)を追加
## 敵の幽霊の設定

## ゴールの設定

# 壁の設定(四辺に配置)
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
    ## 幽霊の処理

    ## ゴールの処理

    ## 壁の処理
    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)  # フォントサイズ150で設定
    text = font.render("GAMEOVER", True, pygame.Color("RED"))  # 赤文字で「GAMEOVER」と表示
    screen.blit(text, (100,200))  # テキストを画面に表示(x=100, y=200)

    btn1 = screen.blit(replay_img, (320,480))  # リセットボタンを描画
    button_to_jump(btn1, 1)  # ジャンプ関数の呼び出し
## ゲームクリア関数


# メインループ
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()

Chapter3-4の記事の末尾にある完成コードをコピーしておいてください。

<<前のページ

pygameの記事一覧

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

次のページ>>

ゲームクリアの条件とは?概要を確認

ゲームクリアとは、プレイヤーがゲーム内で定められた目標やゴールを達成したときに表示される演出や処理のことです。

たとえば敵をすべて倒したときや、特定の場所にたどり着いたときにゲームクリアとするケースが一般的です。

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

今回制作しているアクションゲームでは、画面右下に猫が好きな「魚の山」を設置し、これをゴール地点とします。

プレイヤーが操作する猫がこの魚の山に接触するとゲームがクリアとなり、特別な「ゲームクリア画面」に切り替わるようにします。

ゴール画像の設置と表示

ゲームクリアの判定を行うには、まずゴール地点をゲーム画面に表示する必要があります。

今回はゴールとして魚の山の画像を使用します。これを画面右下に配置することで、プレイヤーが目指す場所を視覚的にわかりやすくします。

魚の山を表示するためには、以下の手順を踏みます。

画像の読み込みとリサイズ

まずは使用する画像ファイルを読み込みます。

画像のファイル名は sakana.png とし、images フォルダの中に保存しておきましょう。

コードを書いてみよう

action.py の「初期化(ゲームの準備をする)」の部分に、以下のコードを書き足しましょう。

## ゴールの設定
sakana_img = pygame.image.load("images/sakana.png")
sakana_img = pygame.transform.scale(sakana_img, (100, 100))

pygame.image.load() で画像を読み込み、pygame.transform.scale() でサイズを変更しています。

ここではゴール地点としてわかりやすいように、100×100ピクセルの大きさに調整しています。

ゴールの座標設定

次に画面のどこに画像を表示するかを指定します。

今回は画面右下の少し上(座標:680, 480)に配置します。

コードを書いてみよう

先ほど書き足した「ゴールの設定」の下に以下のコードを追記しましょう。

sakana_rect = pygame.Rect(680, 480, 100, 100)

このコードでは Rect(矩形)オブジェクトを使って、画像の表示位置とサイズを定義しています。

この矩形は、後ほど衝突判定にも使用します。

画面への描画方法

最後に、gamestage() 関数の中で画像を描画します。

コードを書いてみよう

action.py の gamestage関数 の中の「## ゴールの処理」の部分に以下のコードを書き足しましょう。

    ## ゴールの処理
    screen.blit(sakana_img,sakana_rect)

blit() 関数を使うことで、画面に画像が表示されます。

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

プレイヤーとゴールの衝突を判定

次はプレイヤーがゴールにたどり着いたかどうかを判定し、ゲームクリア画面に切り替える処理を追加します。

この判定には、矩形同士の衝突(当たり判定)を行う colliderect()関数 を使用します。

コードを書いてみよう

action.py の gamestage関数 の中の「## ゴールの処理」の部分に以下のコードを書き足しましょう。

先ほど書いたblit()関数の真下です。

if neko_rect.colliderect(sakana_rect): # 猫と魚の山との衝突判定
    page = 3  # ゲームクリア画面へ

この colliderect() は、2つの Rect オブジェクトが重なっているかどうかを調べる関数です。

重なっていれば True が返され、今回のように page = 3 としてゲームクリア画面へ進めるようにできます。

page という変数は、現在の画面状態を表すために使用しています。これまでの処理では:

  • page == 1 → 通常のゲームプレイ画面
  • page == 2 → ゲームオーバー画面
  • page == 3 → ゲームクリア画面

というように使い分けています。

今回の処理では猫が魚の山に触れた瞬間に page3 に変更して、メインループ内でゲームクリア画面を表示させています。

ゲームクリア画面の作成

プレイヤーが無事ゴール地点に到達したら、ゲームがクリアされたことを知らせる特別な画面を表示しましょう。

ゲームクリア画面の見た目を作成し、リセットボタンを設置して再挑戦できるようにする方法を学びます。

ゲームクリア画面の関数を作る

まずゲームクリア画面専用の関数を定義します。この関数は page == 3 のときに呼び出されます。

コードを書いてみよう

action.py の gamestage関数 の下に以下のコードを書き足しましょう。

## ゲームクリア関数
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)  # ジャンプ関数の呼び出し

順を追って、各部分の意味を説明します。

背景とテキストの描画

ゲームクリア時は画面の背景を明るく目立つ色にし、中央に「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():テキストを画面に描画します。
【Python】勉強猫がコーヒーを片手にリラックスしている様子。記事内の休憩用イラスト

リセットボタンの追加

クリア後にもう一度プレイしたいときのために、「リプレイボタン(resetボタン)」を設置します。

btn1 = screen.blit(replay_img, (320,480))
button_to_jump(btn1, 1)

このボタンはあらかじめ画像として読み込んだ replaybtn.png を使い、クリックされたときにゲーム画面(page = 1)に戻るようになっています。

メインループへの追加

ゲームのメインループに以下の分岐を追加することで、page == 3 のときに gameclear() が呼び出されるようにします。

コードを書いてみよう

action.py の 「# メインループ」の部分に以下のコードを書き足しましょう。

    elif page == 3:
        gameclear()

まとめ

今回はゲームに「ゴール地点」を設け、プレイヤーがその場所にたどり着いたときに「ゲームクリア」となる処理を実装しました。

これによりゲームに目的が生まれ、プレイヤーに達成感を与えることができるようになりました。

ここまで学習してきたあなたは、アクションゲームの基本的な構成要素をしっかりと理解し、使いこなせるようになってきています。

次回はいよいよ、プレイヤーを追いかけてくる敵キャラクター「幽霊」を実装し、さらにゲーム性を高めていきましょう。

お疲れさまでした!ぜひこの調子で、次のステップにも挑戦していきましょう。

Q
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()

<<前のページ

pygameの記事一覧

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

次のページ>>

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

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

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

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

記事URLをコピーしました