【Pygame Zero】量産05:時間差で登場!ねずみたたきゲーム
こんにちは!
「Pythonしよう!楽しく学べるプログラミング教室」の
ラッチ先生です


スックです。よろしくね!
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Pursuit Goes on 」 by MFP【Marron Fields Production】
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Synth-Bell. E-Major[01C](LFO)」:アクセント
・ 「Power Up Item[01](Fast. Pitch Bend Up」:アクションゲームの効果音

基礎プログラムと 画像を入れた
「量産05 ねずみ たたき!」zipフォルダを ダウンロードしてください



今回は、blit( )メソッドを使って 背景画像を 入れてみたよ

学習の流れ
ねずみが 次々と現れる
ねずみが左端へ到着すると ゲームオーバー
ねずみを クリックすると 消える
BGM・効果音を 入れる
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Pursuit Goes on 」 by MFP【Marron Fields Production】
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Synth-Bell. E-Major[01C](LFO)」:アクセント
・ 「Power Up Item[01](Fast. Pitch Bend Up」:アクションゲームの効果音
プログラムを 実行してみよう
プログラミングの仕方を説明します
モジュールを 用意する

今回の「ねずみ たたき!」では、
・ ねずみを クリックする
・ ねずみに モザイクをかける
プログラムがあります。
そこで、2つのモジュールを 用意しました



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

今回は、
ねずみが 次々と現れて左へ動くプログラムを 作っていきます。
scratchで言う「クローン」。
pygama zeroでは、次の手順で プログラムします

リスト:nezumisを作成して、その中にねずみを 追加していくんだ

nezumis[:]は、『リストのコピー』と 覚えておいてね


VisualEffect( )クラスによって、
visualモジュールに入っているモザイク関連のメソッドが使えるよ


2つに 分けたよ
ねずみが 次々と現れる

最初に
ねずみを作る関数:cleate_nezumi( ) を定義します。
そして、
schedule_interval()メソッドを使って
0.8秒経ったら、ねずみを作っていきましょう

nezumis = [] #1 リストnezumisに 空のリストを代入するdef draw():
screen.blit("background", (0, 0))
for nezumi in nezumis: #9 リストnezumisから ねずみを取り出す
nezumi.draw(screen) #10 ねずみを 表示する
def create_nezumi(): #2 ねずみを作る関数を 定義する
x = 750 #3 x座標に 750を代入する
y = random.randint(50, HEIGHT-50) #4 y座標に 50~750からランダムに決めて 代入する
nezumi = VisualEffect("nezumi", (x, y)) #5 ねずみを 作る
nezumi.state = "move" #6 プロパティ:stateに moveを 代入する
nezumis.append(nezumi) #7 ねずみを リストnezumisに 追加する
clock.schedule_interval(create_nezumi, 0.8) #8 0.8秒ごとに create_nezumi()関数を 実行するdef cleate_nezumi: ねずみを作る定義
ポイント1
17. nezumi.draw(screen)
22. nezumi = VisualEffect(“nezumi“, (x, y))

ねずみを VisualEffect( )クラスで作ると 見た目を変えられます
draw( ) メソッドでは、必ず引数にscreenを入れて関連させてね
ポイント2
23. nezumi.state = “move“

Actor( ) クラスは、自分でプロパティを作成し追加することができます
プロパティ:state・・・ねずみの状態
・”move“:ねずみが 動いている
・”mosaic“:ねずみが モザイクアニメーションしている
これにより、ねずみはクリックされると その場で止まって
モザイクアニメーションを するようになります
ポイント3
24. nezumis.append(nezumi)

Actor( ) クラスで 作ったねずみを リストnezumis 追加していきます。
ポイント3
26. clock.schedule_interval(cleate_nezumi, 0.8)
schedule_interval( ) メソッドを使って
0.8秒ごとに ねずみを作るcleate_nezumi( )関数を実行します。

リストnezumisは、0.8秒ごとに ねずみが追加されます。


ここまでが、ねずみが作られるポイント!
まだ、スクリーンには 表示されないよ
def draw( ) : ねずみを表示する
ポイント4
16. for nezumi in nezumis:
17. nezumi.draw(screen)
for 文を使って、リストnezumisに入っているねずみを
順番に 変数nezumiに代入して draw( ) メソッドで 表示します。
リストに入っているねずみが 表示されるよ


この作業を 一瞬で行うんだ
ねずみが左端へ行くと ゲームオーバー

for 文を使って ねずみを 左へ動かします。
game = "play" #1 変数gameを 宣言する 初期値:playdef nezumi_move(): #2 ねずみの動きを定義する
global game #3 グローバル変数 game
if game == "play": #4 もし 変数gameが playなら
for nezumi in nezumis[:]: #5 リストnezumisから ねずみを取り出す
if nezumi.state == "move": #6 もし ねずみの状態が moveなら
nezumi.x -= 5 #7 ねずみのx座標が 5ずつ減っていくdef update(): #8 更新を 定義する
nezumi_move() #9 ねずみを 動かす
nezumis[:]については、 後で説明するよ

ねずみが左端に着いたら ゲームオーバーになります
clear( ) メソッドを使って、他のねずみを 削除して
「GAME OVER」を 表示します

message = Actor("gameover", (400, 300)) #6 メッセージを 作るdef draw():
screen.blit("background", (0, 0))
if game == "over": #7 もし 変数gameが overになったら
message.draw() #8 メッセージを 表示するdef nezumi_move():
global game
if game == "play":
for nezumi in nezumis[:]:
if nezumi.state == "move":
nezumi.x -= 5
if nezumi.x < 50: #1 もし ねずみのx座標が 50以下になったら
game = "over" #2 変数gameに overを代入する
clock.unschedule(create_nezumi) #3 create_nezumi関数を 中止する
nezumis.clear() #4 リストnezumisを 空にする
nezumis.append(nezumi) #5 リストnezumisに ねずみを追加するゲームオーバー
ポイント1
41. nezumis.clear( )
42. nezumis.append(nezumi)
リストnezumisを 空にしてから、
左端に来たねずみだけを追加したよ

ポイント2
40. clock .unschedule(cleate_nezumi)
unschedule( )メソッドを使って
cleate_nezumi()関数を中止します。


変数gameが “over“になったから
左端にあるねずみは、動かないんだよ
ねずみを クリックすると 消える

def on_mouse_down( ) 関数を使って
ねずみがクリックされたら モザイクを かけて消えるようにします

def on_mouse_down(pos): #1 クリックした座標を 引数posに代入する
for nezumi in nezumis: #2 リストnezumisから ねずみを 取り出す
if nezumi.collidepoint_pixel(pos): #3 もし ねずみにクリックされたら
nezumi.state = "mosaic" #4 プロパティ:stateに mosaicを代入する
nezumi.mosaic_animation() #5 モザイクアニメーション開始
break #6 ループを 抜けるポイント1
53. if nezumi.collidepoint_pixel(pos):
collidepoint_pixel( ) メソッドを使って ねずみをクリックしたか判定します

ポイント2
55. nezumi.mosaic_animation()
mosaic_animation( ) メソッドで、モザイクアニメーションを開始します。


process_animation( ) メソッドを 使って
プロパティstateが “mosaic“になったネズミに モザイクをかけて
削除していきます。

def nezumi_move():
global game
if game == "play":
for nezumi in nezumis[:]:
if nezumi.state == "move":
nezumi.x -= 5 elif nezumi.state == "mosaic": #1 もし プロパティ:stateが mosaicなら
result = nezumi.process_animation() #2 アニメーションを実行する
if result == "finished": #3 もし ローカル変数resultが "finished"なら
nezumis.remove(nezumi) #4 リストrezumisから ねずみを削除するここで、
for nezumi in nezumis[:] : で、リストnezumisのコピーを使うか
解説します。
もし、リストnezumisで ねずみを取り出すと
34. for nezumi in nezumis:
49. nezumis.remove(nezumi)
リストnezumisから ねずみを取り出している最中に 削除すると
ねずみの取り出し方が変になり、 エラーが起きる場合があります。

ああっ!
ねずみ「2」が 飛ばされるね
ポイント
リストnezumisを コピーして リストnezumis [ : ] にする
34. for nezumi in nezumis[:]:
49. nezumis.remove(nezumi)
元のリストnezumis から要素を削除しても、
コピーしたリストnezumis[:]には影響しません。

なるほどね!
リストnezumis[ : ]は、
最後のねずみを取り出してから コピーするんだね
BGM・効果音を 入れる
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Pursuit Goes on 」 by MFP【Marron Fields Production】
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Synth-Bell. E-Major[01C](LFO)」:アクセント
・ 「Power Up Item[01](Fast. Pitch Bend Up」:アクションゲームの効果音

それでは、BGMを 入れてみましょう
Python zeroには、musicオブジェクトが標準装備であります。
やり方、以下の手順です
BGM の 流し方
1. MP3ファイルのBGMを 用意する

☆ Pygame zeroでは英語の大文字が 使えません。 エラーが出ます
小文字 に直します
2. フォルダ『music』フォルダに 入れる

3. musicモジュールのメソッドを使う

def nezumi_move():
global game
if game == "play":
for nezumi in nezumis[:]:
if nezumi.state == "move":
nezumi.x -= 5
if nezumi.x < 50:
game = "over"
music.stop() #2 BGMを 止めるmusic.play("pursuit_goes_on") #1 BGMを 流す
今回のプログラムに「DOVA-SYNDROME」サイトから
・ 「Pursuit Goes on 」
by MFP【Marron Fields Production】
BGMの曲として お借りしました。 ありがとうございます。

最後に
効果音をつけましょう!
・ ねずみを クリックする音
・ ねずみが 左端に到達した音
Python zeroには、soundsオブジェクトが標準装備であります。
次の手順で 行います
効果音のつけ方
1. WAVファイルの効果音を 用意する


2. フォルダ『sounds』フォルダに 入れる

3. soundsモジュールのplay( )メソッドを使う


今回のプログラムに
「Chisato’s Website」サイトから
・ 「Accent. Synth-Bell. E-Major[01C](LFO)」:アクセント
・ 「Power Up Item[01](Fast. Pitch Bend Up」:アクションゲームの効果音
効果音を お借りしました。 ありがとうございます。
def nezumi_move():
global game
if game == "play":
for nezumi in nezumis[:]:
if nezumi.state == "move":
nezumi.x -= 5
if nezumi.x < 50:
game = "over"
music.stop()
sounds.accent_synth_bell_e_major_01c_lfo.play() #1 効果音を入れるdef on_mouse_down(pos):
for nezumi in nezumis:
if nezumi.collidepoint_pixel(pos):
nezumi.state = "mosaic"
sounds.power_up_item_01_fast_pitch_bend_up.play() #2 効果音を入れるBGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Pursuit Goes on 」 by MFP【Marron Fields Production】
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Synth-Bell. E-Major[01C](LFO)」:アクセント
・ 「Power Up Item[01](Fast. Pitch Bend Up」:アクションゲームの効果音

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

今回は、
左へ動くねずみを たたくプログラムを 作りました。
import pgzrun
from pgzhelper import *
import random
from visual import VisualEffect
WIDTH = 800
HEIGHT = 590
nezumis = []
message = Actor("gameover", (400, 300))
game = "play"
def draw():
screen.blit("background", (0, 0))
if game == "over":
message.draw()
for nezumi in nezumis:
nezumi.draw(screen)
def create_nezumi():
x = 750
y = random.randint(50, HEIGHT-50)
nezumi = VisualEffect("nezumi", (x, y))
nezumi.state = "move"
nezumis.append(nezumi)
clock.schedule_interval(create_nezumi, 0.8)
def nezumi_move():
global game
if game == "play":
for nezumi in nezumis[:]:
if nezumi.state == "move":
nezumi.x -= 5
if nezumi.x < 50:
game = "over"
music.stop()
sounds.accent_synth_bell_e_major_01c_lfo.play()
clock.unschedule(create_nezumi)
nezumis.clear()
nezumis.append(nezumi)
elif nezumi.state == "mosaic":
result = nezumi.process_animation()
if result == "finished":
nezumis.remove(nezumi)
def on_mouse_down(pos):
for nezumi in nezumis:
if nezumi.collidepoint_pixel(pos):
nezumi.state = "mosaic"
sounds.power_up_item_01_fast_pitch_bend_up.play()
nezumi.mosaic_animation()
break
def update():
nezumi_move()
music.play("pursuit_goes_on")
pgzrun.go()
リストからキャラクターを削除する場合は、
リストのコピーを 使ってね。

for nezumi in nezumis[:] の使い方を 覚えてね!
それじゃ、またね!
