【Pygame Zero】量産01:100個の風船を表示しよう!

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


スックです。よろしくね!
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「おとぼけダンス(Silly dance) 」 by 蒲鉾さちこ
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「accent_synth_bell_e_major_01b_poly」:アクセント
・ 「button_06_3_cancel」:ボタン音

基礎プログラムと 画像を入れた
「量産01 boonを 探せ!」zipフォルダを ダウンロードしてください



この基礎プログラムは、こちらの記事で解説しています

学習の流れ
100個の風船を ランダムに 表示する

風船を クリックすると 消える
boonを クリックすると、すべての風船が 消える
プログラムを 実行してみよう
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「おとぼけダンス(Silly dance) 」 by 蒲鉾さちこ
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「accent_synth_bell_e_major_01b_poly」:アクセント
・ 「button_06_3_cancel」:ボタン音
プログラミングの仕方を説明します
モジュールを 用意する

今回の「boonを 探せ!」では、
・ 風船やboonを クリックする
・ 風船を ランダムな場所へ
・ boon が セリフを言う
プログラムが あります
そこで、3つのモジュールを 用意しました




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

今回は、
100個の風船を 表示するプログラムを 作っていきます。
scratchで言う「クローン」。
pygama zeroでは、次の手順で プログラムします


リスト:balloonsを作成して、その中に100個の風船を 入れるんだ
100個の風船を 表示する


最初に
boonをランダムに選んだ場所へ動かし 隠しましょう
boon_x = random.randint(50, WIDTH-50) #1 boonのx座標に 50~750からランダムに選んだ数字を 代入する
boon_y = random.randint(50, HEIGHT-50) #2 boonのy座標に 50~540からランダムに選んだ数字を 代入する
boon = Actor("boon", (boon_x, boon_y)) #3 ランダムに選んだ座標に する

これで、boonは、毎回 違う場所になるね

次に、100個の風船のインスタンスを
リストballoonに入れるよ

balloons = [] #1 手順1:変数balloonsに、空のリストを代入する
for i in range(100): #2 100回 繰り返す
balloon_x = random.randint(50, WIDTH-50) #3 風船のx座標に 50~750からランダムに選んだ数値を 代入する
balloon_y = random.randint(50, HEIGHT-50) #4 風船のy座標に 50~540からランダムに選んだ数値を 代入する
balloon = Actor("balloon", (balloon_x, balloon_y)) #5 手順2:変数balloonに 風船のインスタンスを 代入する
balloons.append(balloon) #6 手順2:リストballoonsに 風船を 追加していく
def draw():
screen.fill("white")
boon.draw()
for balloon in balloons: #7 手順3:リストballoonsから 風船を取り出し
balloon.draw() #8 風船を 表示する

風船をゆっくり表示させました。
ホントは、100個の風船を 一瞬で表示させるよ
ポイント1
Actor( )クラスで balloonインスタンスを作ったら リストballoonsに 追加する
19. balloons.append(balloon)

これを for文を 使って 100回 繰り返します。
*今回は、カウンター変数:i は 利用しません

リストballoonsの中に 100個の風船が 入りました。
しかし、まだスクリーンに表示されません。

へぇ~、変数balloonsの中に 100個も風船が入れるんだぁ…
すごくたくさん入るんだね
ポイント2
表示させるためには、for文を使い
リストballoonsから順番に変数balloonに代入し、 draw( )メソッドで 表示させます

この作業を リストballoonsの最後の要素まで 行いますが
パソコンは一瞬に処理し、パッと画面に 表示します。

おおっ!100個の風船が、一瞬で現れたぞ!
風船を クリックすると 消える

次に、
for 文 を 使って、クリックされた風船を 消していきます


def on_mouse_down(pos): #1 クリックした座標posを 取得する
for balloon in balloons: #2 風船を 取り出す
if balloon.collidepoint_pixel(pos): #3 もし 風船をクリックしたら
sounds.button_06_3_cancel.play() #4 効果音を出す
balloons.remove(balloon) #5 風船を 削除する
return #6 この関数(on_mouse_down) 終了

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「button_06_3_cancel」:ボタン音

あれっ?
クリックした風船が消えなくて、その下にある風船が 消えてる

おぉ…と、いけない!
これだと、風船が重なっている場合、下の風船が 消えてしまう
ポイント
なぜ、風船が重ねっている時に、下の風船が消えるのか
リストballoonsに入っている順番に判定するからです
29. for balloon in balloons:
30. if balloon.collidepoint_pixel(pos)
10個の大きな風船が解説します
for balloon in balloons: では、
リストballoonsに入っている風船から取り出して表示するため
風船が重なった場合、後から表示された風船が上になります。

なるほど!
どの風船にクリックしたのか調べる時も
for balloon in bballoons を使って リストを順番に処理しているんだ
そうです! クリックした時、
リストの順に、風船がクリックされたか 確認していきます。
クリックした場所(pos)が、風船の中にあったら消えます。
そして、 風船が消えたら、
33. return
ここで、on_mouse_down( ) 関数は、終了します

原因は、わかったよ。
それじゃあ、自分が消したい風船が 消えないよ

まかせなさい!
reversed( )関数を使えば、
リストの要素を最後から順番に 変数balloonに 代入します
ポイント
reversed(balloons)

リストに入っている風船の順番を 反対にして 1つずつ変数balloonに 代入します
そうすれば、風船が重なっていても、クリックした上の風船が 消えます
def on_mouse_down(pos):
for balloon in reversed(balloons): #1 リストballoonsを逆順で取り出す

おおっ! これで、クリックした風船が 消えたね
風船を クリックすると 消える

listクラスにある clear( )メソッドを使って
boonを クリックしたら、リストballoon にある要素を すべて削除しましょう

def draw():
screen.fill("white")
boon.draw()
for balloon in balloons:
balloon.draw()
text_display.draw(screen) #1 テキストディスプレイを装備する
def on_mouse_down(pos):
for balloon in reversed(balloons):
if balloon.collidepoint_pixel(pos):
sounds.button_06_3_cancel.play()
balloons.remove(balloon)
return
if boon.collidepoint_pixel(pos): #2 もし boonをクリックしたら
music.stop()
sounds.accent_synth_bell_e_major_01b_poly.play() #3 効果音を入れる
balloons.clear() #4 リストballoonsの風船を全部削除する
boon.image = "ok_boon" #5 boonの画像を "ok_boon"にする
boon.say("O.K!", 2, color = "red", size = 70, y_offset = -70) #6 boonが「O.K!」と2秒間 言う
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「accent_synth_bell_e_major_01b_poly」:アクセント

おおっ! boonを一発で クリックできたね

最後に、
musicオブジェクトを使って BGMを 流してみよう

def on_mouse_down(pos):
for balloon in reversed(balloons):
if balloon.collidepoint_pixel(pos):
sounds.button_06_3_cancel.play()
balloons.remove(balloon)
return
if boon.collidepoint_pixel(pos):
music.stop() #2 BGMを 停止する
music.play("おとぼけダンス(silly_dance)") #1 BGMを 流す
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「おとぼけダンス(Silly dance) 」 by 蒲鉾さちこ
pygame zeroのプログラムでは、ファイル名は 全部小文字です。
大文字が入ると エラーが出ます。
ですので、
「S」の文字を 「s」小文字にして、”おとぼけダンス(silly_dance)” にします。

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

今回は、
風船を 量産したプログラムを 作りました。
import pgzrun
from pgzhelper import *
import random
from say import text_display
WIDTH = 800
HEIGHT = 590
boon_x = random.randint(50, WIDTH-50)
boon_y = random.randint(50, HEIGHT-50)
boon = Actor("boon", (boon_x, boon_y))
balloons = []
for i in range(100):
balloon_x = random.randint(50, WIDTH-50)
balloon_y = random.randint(50, HEIGHT-50)
balloon = Actor("balloon", (balloon_x, balloon_y))
balloons.append(balloon)
def draw():
screen.fill("white")
boon.draw()
for balloon in balloons:
balloon.draw()
text_display.draw(screen)
def on_mouse_down(pos):
for balloon in reversed(balloons):
if balloon.collidepoint_pixel(pos):
sounds.button_06_3_cancel.play()
balloons.remove(balloon)
return
if boon.collidepoint_pixel(pos):
music.stop()
sounds.accent_synth_bell_e_major_01b_poly.play()
balloons.clear()
boon.image = "ok_boon"
boon.say("O.K!", 2, color = "red", size = 70, y_offset = -70)
music.play("おとぼけダンス(silly_dance)")
pgzrun.go()

キャラクターを量産するには、
この3つの流れで、プログラミングします。

ポイント1
Actor( )クラスで balloonインスタンスを作ったら リストballoonsに 追加する
19. balloons.append(balloon)

これを for文を 使って 100回 繰り返します。
*今回は、カウンター変数:i は 利用しません

リストballoonsの中に 100個の風船が 入りました。
しかし、まだスクリーンに表示されません。
ポイント2
表示させるためには、for文を使い
リストballoonsから順番に変数balloonに代入し、 draw( )メソッドで 表示させます

この作業を リストballoonsの最後の要素まで 行いますが
パソコンは一瞬に処理し、パッと画面に 表示します。

キャラクターを量産するには、for 文 をマスターしようね
1. for i in range( ) 文で、
キャラクターを たくさん作って、リストに追加する。
2. for キャラクター in リスト文で、
リストの中のキャラクターを 表示する

みんなも好きなキャラクターを たくさん作ってみてね
それじゃ、またね!