簡単なゲーム

【Pygame Zero】簡単なゲーム03:複数のキャラクターを個別に動かす

ratch2025

こんにちは!
「Pythonしよう!楽しく学べるプログラミング教室」
ラッチ先生です

ラッチ先生
ラッチ先生
スック
スック

スックです。よろしくね!

今回のプロジェクトは、こちら!

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
No_Nameby VeryGoodMan

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
「Accent. Brilliant [01] (High. Fast)」:アクセント
「Button [06-3] (Cancel)」:ボタン
・ 「Thought Babble/Cloud [02]」:アニメ

ラッチ先生
ラッチ先生

基礎プログラムと 画像を入れた
「簡単なゲーム03 コウモリを ねらえ!」zipフォルダを ダウンロードしてください

pythonしよう!簡単なゲーム03:画面を表示する
スック
スック

今回は、スクリーンの色を “silver”に したよ

「原色大事典」サイトには、URL:https://www.colordic.org/
pygame zeroで使える色が載っています

pythonしよう!簡単なゲーム03:風船スロット!zipの中身
スポンサーリンク

10匹のコウモリが 飛び回る

コウモリをクリックして 撃退する

15秒以内に 撃退する

pythonしよう!簡単なゲーム03:15秒以内に撃退する

BGM・効果音を 入れる

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
No_Nameby VeryGoodMan

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
「Accent. Brilliant [01] (High. Fast)」:アクセント
「Button [06-3] (Cancel)」:ボタン
・ 「Thought Babble/Cloud [02]」:アニメ

プログラムを 実行してみよう

ラッチ先生
ラッチ先生

今回の「コウモリを ねらえ!」では、
・ コウモリを クリックする
・ コウモリのコスチュームの切り替え
・ セリフを 言う
プログラムがあります。

そこで、3つのモジュールを 用意しました

pythonしよう!簡単なゲーム03:pgzhelperモジュールの解説
pythonしよう!簡単なゲーム03:sayモジュールの解説
スック
スック

モジュールとは、
関数やプログラムが書かれているファイルのことだよ

ラッチ先生
ラッチ先生

Actorアクター()クラスが入っている変数batバットには、
コウモリを 動かす属性(データ)やメソッド(命令)が あります。

pythonしよう!簡単なゲーム03:変数batの詳しい解説
スック
スック

属性(データ)やメソッド(命令)は、
『 . (ドット)』を付ければ、使えるよ

ラッチ先生
ラッチ先生

今回は、
10匹のコウモリが、別々の動きなるプログラムを作っていきます。

pythonしよう!簡単なゲーム03:ポイント1の詳しい解説
スック
スック

リストbatsバッツを作成して、その中に10匹のコウモリを入れるよ

pythonしよう!簡単なゲーム03:ポイント2の詳しい解説
スック
スック

関数の引数に batバットオブジェクトを 入れるだけだよ

スック
スック

この3つのステップで
コスチュームを 切り替えることができるよ

スック
スック

batsバッツ[:] は、リストbatsバッツのコピー と覚えてね

pythonしよう!簡単なゲーム03:ポイント5の詳しい解説
スック
スック

3つに 分けたよ

ラッチ先生
ラッチ先生

まず、空のリストbatsバッツを作成して、
10匹のコウモリを スクリーンに 表示します。

pythonしよう!簡単なゲーム03:ポイント1の詳しい解説
Python
bats = []            #1 リストbatsに 空リストを 代入する
Python
for i in range(10):  #2 10回 繰り返す
    x = random.randint(50, WIDTH-50)   #3 変数xに 50~750からランダムに決めた数値を 代入する
    y = random.randint(50, HEIGHT-50)  #4 変数yに 50~550からランダムに決めた数値を 代入する
    bat = Actor("bat1", (x, y))  #5 コウモリオブジェクトを 生成する
    bats.append(bat) 
Python
def draw(): 
    screen.fill("silver")
    for bat in bats:     #6 リストbatsから コウモリを取り出す
            bat.draw()   #7 コウモリを 表示する
スック
スック

毎回、違うところに 出現するね

ラッチ先生
ラッチ先生

コスチュームモジュールを使って、
コウモリの羽を ばたつかせるよ

Python
for i in range(10): 
    x = random.randint(50, WIDTH-50) 
    y = random.randint(50, HEIGHT-50)
    bat = Actor("bat1", (x, y)) 
    bat.images = ["bat1", "bat2"]  #1 プロパティimagesに 2つの画像を 代入する
    bat.fps = 20  #2 プロパティfpsに 20に設定する
    bats.append(bat) 
Python
def update():
    for bat in bats:   #3 リストbatsから batを取り出す
        bat.animate()  #4 コスチュームを 切り替える
スック
スック

コウモリの羽ばたく速度を変えたい時は、
fps(フレームズ・パー・セコンド)の数値を 変えようね

ラッチ先生
ラッチ先生

つぎは、animateアニメイト( ) 関数を使って
コウモリを バラバラに 動かします。

pythonしよう!簡単なゲーム03:animate() 関数の解説
Python
def bat_move(bat):   #1 コウモリの動きを 定義する 引数bat
    x = random.randint(50, WIDTH-50)  #2 x座標に 50~750からランダムに決めた数値を 代入する
    y = random.randint(50, HEIGHT-50) #3 y座標に 50~550からランダムに決めた数値を 代入する
    move_time = random.uniform(1, 3)  #4 変数move_timeに 1~3からランダムに決めた数値を 代入する
    animate(bat, duration = move_time, pos=(x, y), on_finished=lambda:bat_move(bat))  #5 コウモリが 動くアニメーションをする

for bat in bats:   #6 リストbatsから batを取り出す
    bat_move(bat)  #7 bat_move()関数を 実行する
pythonしよう!簡単なゲーム03:uniform()関数の解説
スック
スック

28. animateアニメイト(batバット, …, onオン_finishedフィニッシュド=lambdaラムダ:batバット_moveムーヴ(batバット))

lambdaラムダ』って、何?

ラッチ先生
ラッチ先生

lambdaラムダ』とは、無名関数。

lambdaラムダ:batバット_moveムーヴ(batバット) は、
batバット_moveムーヴ(batバット) 関数を 実行する」と定義した関数です。

pythonしよう!簡単なゲーム03:lambda関数の解説
ラッチ先生
ラッチ先生

なぜ、ここで『lambdaラムダ」を使うか 説明しますね

animateアニメイト( ) 関数のonオン_finishedフィニッシュド引数には、
実行させたい関数を渡します。

1.on_finished引数に、関数を渡す
スック
スック

batバット_moveムーヴ(batバット) 関数を そのまま入力すれば いいんじゃない…

2.bat_move(bat)と 引数batを入れた関数を渡す。

( )は、関数を実行する という働き。

スック
スック

えっ⁉ ( )は、関数を実行する意味だったんだ‼

ラッチ先生
ラッチ先生

そうだよ。
そこで、「lambdaラムダ」を 使います。

pythonしよう!簡単なゲーム03:lambda関数の解説
3.lambda: ○○ を 使う
スック
スック

lambdaラムダ :によって、
引数(batバット)が あっても すぐ実行されなくなったね

ポイント2

pythonしよう!簡単なゲーム03:ポイント2の詳しい解説
スック
スック

これで、コウモリが 別々に 動きます

ラッチ先生
ラッチ先生

コウモリにプロパティを2つ追加します。

1つは、「animation」プロパティ

このプロパティに コウモリのアニメーションを 設定。
コウモリのアニメーションを止めることができます

pythonしよう!簡単なゲーム03:追加プロパティanimationの詳しい解説
Python
def bat_move(bat): 
    x = random.randint(50, WIDTH-50) 
    y = random.randint(50, HEIGHT-50)
    move_time = random.uniform(1, 3)  
    bat.animation = animate(bat, duration = move_time, pos=(x, y), on_finished=lambda:bat_move(bat))  #1 プロパティanimationに amimate( )関数を 設定する
ラッチ先生
ラッチ先生

2つは、「hitヒット」プロパティ

このプロパティは、 コウモリのクリック判定

pythonしよう!簡単なゲーム03:追加プロパティhitの詳しい解説
Python
for i in range(10): 
    x = random.randint(50, WIDTH-50) 
    y = random.randint(50, HEIGHT-50)
    bat = Actor("bat1", (x, y)) 
    bat.hit = False               #1 プロパティhitに Falseを設定する
    bat.images = ["bat1", "bat2"] 
スック
スック

Actorアクター( )クラスで作られたbatオブジェクトには、
自分でプロパティを 追加できるんだ

ラッチ先生
ラッチ先生

collideコライド_pixelピクセル( ) メソッドで、コウモリをクリックしたら
・ アニメーションを止める
・ 画像を “batバット3″にする

この2つのプログラムを作りましょう

pythonしよう!簡単なゲーム03:collidepoint_pixel( )メソッドの解説
pythonしよう!簡単なゲーム03:ポイント1の解説
Python
game = "play"        #1 変数gameを宣言 初期値:play
Python
def on_mouse_down(pos):  #2 マウスがクリックした関数を定義する 引数pos
    global game          #3 グローバル変数 game
    
    if game == "play":   #4 もし 変数gameが playなら
        for bat in bats: #5 リストbatsから コウモリを取り出す
            if bat.collidepoint_pixel(pos) and not bat.hit:  #6 もし コウモリをクリックして かつ プロパティhitが Falseなら
                bat.hit = True  #7 プロパティhitが Trueに設定する                
                bat.animation.stop()  #8 コウモリのアニメーションを停止する
                bat.image = "bat3" #9 コウモリの画像に bat3を代入する
                break    #10 ループ終了
Python
def update():
    for bat in bats: 
        if not bat.hit:  #11 もし プロパティhitが Falseなら
            bat.animate() 
スック
スック

コウモリをクリックすると 動きが止まったね

ラッチ先生
ラッチ先生

sayセイモジュールを使って
・ クリックされたら セリフを1秒間言う
・ セリフを言い終わったら 削除する

このプログラムを作っていきましょう

pythonしよう!簡単なゲーム03:say( )メソッドの解説
スック
スック

isイズ_talkingトーキング( )メソッドを使って
コウモリがセリフを言い終わったタイミングで 削除するよ

pythonしよう!簡単なゲーム03:is_talking( )メソッドの解説
pythonしよう!簡単なゲーム03:remove( )メソッドの解説
Python
def draw(): 
    screen.fill("silver")
    for bat in bats[:]:   #3 リストbatsを コピーリストbats[:]にする
            bat.draw()    
            if bat.hit and not bat.is_talking(): #4 もし プロパティhitが Trueで かつ セリフを言ってなければ
                bats.remove(bat)  #5 リストbatsから batを削除する

    text_display.draw(screen)  #1 テキストディスプレイを 装備する
Python
def on_mouse_down(pos):  
    global game          
    
    if game == "play":   
        for bat in bats: 
            if bat.collidepoint_pixel(pos) and not bat.hit:  
                bat.hit = True                  
                bat.animation.stop()  
                bat.image = "bat3" 
                bat.say("Ouch!", 1, color= "red", size=60, y_offset=-60)  #2 セリフを 1秒間言う
                break     
スック
スック

ああっ!

コウモリ「2」が 飛ばされてるね

スック
スック

なるほどね!
リストbatsバッツ [ : ] は、
最後のコウモリを取り出してからコピーするんだね

pythonしよう!簡単なゲーム03:15秒以内に撃退する
ラッチ先生
ラッチ先生

15秒以内に10匹のコウモリを撃退すればクリアです。

・ 変数bg_imageイメージ : 背景画像を 保存する
・ 変数batバット_countカウント : 撃退したコウモリの数を 保存する

2つの変数を作って クリアのプログラムを 作りましょう

Python
bg_image = None  #1 変数bg_imageを宣言 初期値:None (無し)
bat_count = 0    #2 変数bat_countを宣言 初期値: 0
Python
def draw():
    if game == "play":         #3 もし 変数gameが playなら
        screen.fill("silver")
    else:                      #4 その他は
        screen.blit(bg_image, (0, 0))  #5 変数bg_imageに入っている画像を 表示する
Python
def on_mouse_down(pos): 
    global game, bat_count, bg_image  #6 グローバル変数 bat_count, bg_image

    if game == "play": 
        for bat in bats: 
            if bat.collidepoint_pixel(pos) and not bat.hit: 
                sounds.button_06_3_cancel.play() 
                bat.hit = True 
                bat_count += 1      #7 変数bat_countを 1ずつ増やす
                if bat_count == 10: #8 もし 変数bat_countが 10になったら  
                    game = "clear"  #9 変数gameに clear代入する
                    bg_image = "bg_clear"  #10 変数bg_imageに 画像bg_clearを 代入する
スック
スック

おお!クリアしたあ

ラッチ先生
ラッチ先生

つぎは、ゲームオーバーのプログラムです。

gameゲーム_overオーバー( )関数で、
・ 背景画を “bg_overオーバー“に する
・ コウモリの動きを 止める
・ 「Tooトゥー Badバッド!(残念!)」と 言う
ゲームオーバーの処理を 定義します

scheduleスケジュール( )メソッドを使って、
15秒後に gameゲーム_overオーバー( )関数を実行します

pythonしよう!簡単なゲーム03:schedule_interval()メソッドの解説
Python
def on_mouse_down(pos): 
    global game, bat_count, bg_image 

    if game == "play": 
        for bat in bats: 
            if bat.collidepoint_pixel(pos) and not bat.hit: 
                sounds.button_06_3_cancel.play() 
                bat.hit = True 
                bat_count += 1 
                if bat_count == 10: 
                    game = "clear"  
                    clock.unschedule(game_over)  #10 game_over関数を中止する
Python
def game_over():           #1 game_over( )関数を 定義する
    global game, bg_image  #2 グローバル変数game bg_imge

    game = "over"          #3 変数gameに overを代入する
    bg_image = "bg_over"   #4 変数bg_imageに 画像bg_overを代入する
    for bat in bats:       #5 リストbatsから コウモリを取り出す   
        if not bat.hit:    #6 もし プロパティhitが Falseなら 
            bat.animation.stop()  #7 プロパティanimationにあるanimate( )関数を 止める
            bat.say("Too Bad!", 2, color="blue", size=60, y_offset=-60)  #8 「Too Bad!」と2秒言う

clock.schedule(game_over, 15)  #9 15秒後に game_over関数を実行する
スック
スック

unscheduleアンスケジュール( )メソッドを使って
クリアした時は、gameゲーム_overオーバー関数を 中止させるよ

pythonしよう!簡単なゲーム03:unschedule()メソッドの解説

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
No_Nameby VeryGoodMan

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
「Accent. Brilliant [01] (High. Fast)」:アクセント
「Button [06-3] (Cancel)」:ボタン
・ 「Thought Babble/Cloud [02]」:アニメ

ラッチ先生
ラッチ先生

それでは、BGMを 入れてみましょう

Pythonパイソン zeroゼロには、musicミュージックオブジェクトが標準装備であります。
やり方、以下の手順です

pythonしよう!簡単なゲーム03:MP3ファイル

☆ Pygame zeroでは英語の大文字が 使えません。 エラーが出ます
 小文字 に直します

pythonしよう!簡単なゲーム03:mousicフォルダの解説
pythonしよう!簡単なゲーム03:musicモジュールの解説
Python
music.play("no_name")  #1 BGMを 入れる
スック
スック

今回のプログラムに「DOVA-SYNDROME」サイトから
No_Nameby VeryGoodMan
 BGMの曲として お借りしました。 ありがとうございます。

ラッチ先生
ラッチ先生

つぎに
効果音をつけましょう! 
 ・ コウモリを クリックした時
 ・ クリア
 ・ ゲームオーバー

Pythonパイソン zeroゼロには、soundsサウンズオブジェクトが標準装備であります。

次の手順で 行います

pythonしよう!簡単なゲーム03:WAVファイル
pythonしよう!簡単なゲーム03:WAVファイル
pythonしよう!簡単なゲーム03:WAVファイル
pythonしよう!簡単なゲーム03:soundsフォルダの解説
pythonしよう!簡単なゲーム03
:play()メソッドの解説
スック
スック

今回のプログラムに
Chisato’s Website」サイトから
「accent_brilliant_01_high_fast」:アクセント
「button_06_3_cancel」:ボタン
「thought_bubble_cloud_02」:アニメ

 効果音を お借りしました。 ありがとうございます。

Python
def on_mouse_down(pos): 
    global game, bat_count, bg_image 

    if game == "play": 
        for bat in bats: 
            if bat.collidepoint_pixel(pos) and not bat.hit: 
                sounds.button_06_3_cancel.play() #1 コウモリにクリックした効果音を入れる
                bat.hit = True 
                bat_count += 1 
                if bat_count == 10: 
                    game = "clear" 
                    sounds.accent_brilliant_01_high_fast.play()  #2 クリアの効果音を入れる
                    clock.unschedule(game_over) 
                    bg_image = "bg_clear" 
Python
def game_over(): 
    global game, bg_image 

    game = "over" 
    bg_image = "bg_over" 
    sounds.thought_bubble_cloud_02.play()  #3 ゲームオーバーの効果音を入れる
スック
スック

今回の学習は、これで 終了! おつかれさま

ラッチ先生
ラッチ先生

今回は、
10匹のコウモリが個別に動くプログラムを 作りました。

コウモリを ねらえ!
Python
import pgzrun
from pgzhelper import *
from costume import *
from say import text_display
import random

WIDTH = 800
HEIGHT = 600

bats = [] 
game = "play" 
bg_image = None 
bat_count = 0 

for i in range(10): 
    x = random.randint(50, WIDTH-50) 
    y = random.randint(50, HEIGHT-50)
    bat = Actor("bat1", (x, y)) 
    bat.hit = False 
    bat.images = ["bat1", "bat2"] 
    bat.fps = 20 
    bats.append(bat) 

def bat_move(bat): 
    x = random.randint(50, WIDTH-50) 
    y = random.randint(50, HEIGHT-50)
    move_time = random.uniform(1, 3)  
    bat.animation = animate(bat, duration = move_time, pos=(x, y), on_finished=lambda:bat_move(bat)) 

for bat in bats: 
    bat_move(bat) 
    
def draw():
    if game == "play":   
        screen.fill("silver")
    else: 
        screen.blit(bg_image, (0, 0)) 
        
    for bat in bats[:]:  
            bat.draw()    
            if bat.hit and not bat.is_talking(): 
                bats.remove(bat) 

    text_display.draw(screen) 
        
def on_mouse_down(pos): 
    global game, bat_count, bg_image 

    if game == "play": 
        for bat in bats: 
            if bat.collidepoint_pixel(pos) and not bat.hit: 
                sounds.button_06_3_cancel.play() 
                bat.hit = True 
                bat_count += 1 
                if bat_count == 10: 
                    game = "clear" 
                    sounds.accent_brilliant_01_high_fast.play() 
                    clock.unschedule(game_over) 
                    bg_image = "bg_clear" 
                
                bat.animation.stop() 
                bat.image = "bat3" 
                bat.say("Ouch!", 1, color= "red", size=60, y_offset=-60) 
                break 
            
def game_over(): 
    global game, bg_image 

    game = "over" 
    bg_image = "bg_over" 
    sounds.thought_bubble_cloud_02.play() 
    for bat in bats:     
        if not bat.hit:  
            bat.animation.stop() 
            bat.say("Too Bad!", 2, color="blue", size=60, y_offset=-60) 

clock.schedule(game_over, 15) 
    
def update():
    for bat in bats: 
        if not bat.hit: 
            bat.animate() 
    
music.play("no_name") 

pgzrun.go()
ラッチ先生
ラッチ先生

引数batバットに異なるコウモリを渡すことで、
同じ関数でも個別の動作が 実現できます。

pythonしよう!簡単なゲーム03:ポイント2の詳しい解説
スック
スック

たくさんのオブジェクトを動かすゲームで使えるね

それじゃ、またね!

スポンサーリンク
ABOUT ME
ラッチ先生
ラッチ先生
こんにちは!
「Pythonしよう!楽しく学べるプログラミング教室」の学長、ラッチです。

scratchのように楽しく学べるPython講座です。
・図やアニメーションを使って、わかりやすく楽しく学べる!
・毎回の授業が新しい発見の連続!
・プログラミングの考え方が身につき、自分のやりたいことが形にできるように。

この3点をモットーにサイトを立ち上げました。 よろしくお願いします
記事URLをコピーしました