簡単なゲーム

【Pygame Zero】簡単なゲーム10:animate( )で障害物を動かそう!

ratch2025

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

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

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

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

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
「Spirit」by TECHNOTRAIN

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
「Accent. Brilliant [02] (Low)」:アクセント
「Bump. Low-Bit [03]」: アクションゲーム
「Kiga Nukeru [01] (Long)」:アニメ                  

ラッチ先生
ラッチ先生

基礎プログラムと 画像を入れた
「簡単なゲーム10: 宇宙へ GO!」zipフォルダを
ダウンロードしてください

pythonしよう!簡単なゲーム10:boonと風船を表示する
スック
スック

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

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

pythonしよう!簡単なゲーム10:宇宙へGO!zipの中身
スック
スック

このゲームで使用している音声ファイルは、
以下のサイトからお借りしています。

各自でダウンロードして、該当するフォルダに入れてください!

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
「Spirit」by TECHNOTRAIN

効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
「Accent. Brilliant [02] (Low)」:アクセント
「Bump. Low-Bit [03]」: アクションゲーム
「Kiga Nukeru [01] (Long)」:アニメ                  

pythonしよう!簡単なゲーム10:宇宙へGO!zipの中身
スポンサーリンク

左右キーで 動かす

雲が 下へ 流れる

ゲーム クリア

ゲームオーバー

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

ラッチ先生
ラッチ先生

今回の「宇宙へ GO!」では、
・ boonが、雲や風船に 触れる
・ 雲の大きさを 変える
・ 雲や風船をランダムに選んだ場所へ 動かす
プログラムがあります。

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

pythonしよう!簡単なゲーム10:pgzheplerモジュールの解説
pythonしよう!簡単なゲーム10:randomモジュールの解説
スック
スック

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

ラッチ先生
ラッチ先生

Actorアクター( )クラスが入っている 変数boonボーン には、
オブジェクトを動かす属性(データ)やメソッド(命令)が
あります。

ラッチ先生
ラッチ先生

今回のプログラミングには、ポイントが 3つあります

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

リストcloudsクラウズ を作成して、
cleateクリエイト_cloudクラウド関数で 作成された雲を 入れるよ

スック
スック

これで、雲を 好きな時に止められるね

pythonしよう!簡単なゲーム10:ポイント3の解説
スック
スック

クリアとゲームオーバーのプログラムを まとめたよ

ラッチ先生
ラッチ先生

boonボーンオブジェクトに プロパティ:onオン を 追加します。
boonボーンの動きと止めるのスイッチにします。

pythonしよう!簡単なゲーム10:プロパティ:onの解説
Python
boon.on = True       #1 プロパティ:onに Trueを 設定する

def boon_move():     #2 boon_move()関数を 定義する
    if boon.on:      #3 もし プロパティonが Trueなら
        boon.y -= 1  #4 boonのy座標を 1ずつ減らす

        if boon.top < 0:    #5 もし プロパティtopが 0未満になったら
            boon.on = False #6 プロパティ:onを Falseにする

def update():
    boon_move()      #7 boon_move()関数を 実行する
Q
プロパティ:top とは?
pythonしよう!簡単なゲーム10:プロパティ:topの解説
スック
スック

おおっ! 止まった

ラッチ先生
ラッチ先生

次に、左右キーを押したら boonボーンが左右に動くよう
boonボーン_moveムーヴ( ) 関数を 定義するよ

minミン( ), maxマックス( ) 関数を使って
左右の端で止まるようにしました。

pythonしよう!簡単なゲーム10:mix() ,max()関数の解説
Python
def boon_move():
    if boon.on:
        boon.y -= 1

        if keyboard.right:  #1 もし 右キーが 押されたら
            boon.x = min(boon.x + 5, 700)  #2 boonのx座標に x座標+5と700 の最小値を設定する

        elif keyboard.left: #3 もし 左キーが 押されたら 
            boon.x = max(boon.x - 5, 100)  #3 boonのx座標に x座標-5と100 の最大値を設定する

        if boon.top < 0:
            boon.on = False
Q
keyboard オブジェクトとは?
pythonしよう!簡単なゲーム10:keyboardオブジェクトの解説
スック
スック

これで、boonの動ける範囲が できたね

ラッチ先生
ラッチ先生

それでは、cleateクリエイト_cloudクラウド()関数を作って 雲を 発生させましょう

雲を量産させるので、リストcloudsクラウズを 作るよ

pythonしよう!簡単なゲーム10:ポイント1の解説
Python
clouds = []    #1 リストcloudsに 空リストを代入する

def create_cloud():            #2 create_cloud()関数を 定義する
    x = random.randint(0, 800) #3 x座標に 0~800からランダムに選んだ数字を 代入する
    cloud = Actor("cloud", (x, 0)) #4 変数cloudに cloudオブジェクトを代入する
    cloud.scale = random.uniform(0.8, 2.0) #5 プロパティscaleに 0.8~2.0からランダムに選んだ数値を 設定する
    clouds.append(cloud)  #6 リストcloudsに cloudオブジェクトを追加する
    clock.schedule(create_cloud, random.uniform(0.2, 1.5)) #7 0.2~1.5からランダムに選んだ時間後に create_cloud関数を 実行する

clock.schedule(create_cloud, random.uniform(0.2, 1.5)) #8 0.2~1.5からランダムに選んだ時間後に create_cloud関数を 実行する
Python
def draw():
    screen.fill("aqua")
    balloon.draw()
    boon.draw()
    for cloud in clouds:  #9 リストcloudsから cloudオブジェクトを取り出す
        cloud.draw()  #10 cloudオブジェクトを 表示する
Q
プロパティ:scale とは?
pythonしよう!簡単なゲーム10:プロパティ:scaleの解説
Q
uniform( )関数 とは?
pythonしよう!簡単なゲーム10:uniform()関数の解説
Q
schedule( )メソッド とは
pythonしよう!簡単なゲーム10:schedule( )メソッドの解説
スック
スック

雲が どんどん現れてくるね

ラッチ先生
ラッチ先生

animateアニメイト( )関数を 使って雲を下へ 動かしていくよ

cleateクリエイト_cloudクラウド( )関数の中に 追加します。

pythonしよう!簡単なゲーム10:animate( )関数の解説
Python
def create_cloud(): 
    x = random.randint(0, 800) 
    cloud = Actor("cloud", (x, 0)) 
    cloud.scale = random.uniform(0.8, 2.0)
    target_x = random.randint(0, 800) #1 変数target_xに 0~800からランダムに選んだ数字を 代入する
    dur_time = random.uniform(1, 4) #2 変数dur_timeに 1~4からランダムに選んだ 小数値を代入する
    cloud.anim = animate(cloud, pos = (target_x, 600), duration= dur_time, on_finished=lambda:clouds.remove(cloud)) #3 プロパティanimに アニメーションを 代入する
    clouds.append(cloud) 
    clock.schedule(create_cloud, random.uniform(0.2, 1.5))
スック
スック

lambdaラムダ って、なあに?

スック
スック

ほんとだ! 動きがどれも違って いいねぇ

スック
スック

雲が 下で 止まっちゃったね

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

しかし、これでは、エラーが出てしまします

スック
スック

あっ!
もしかして、removeリムーヴ( )メソッドに ( )が あるから…

ラッチ先生
ラッチ先生

そうなんです。
関数に( )が あると、今すぐ実行するということ。
アニメーションしたと同時に雲を削除しようとするから
エラーが出るんだ

そこで、lambdaラムダ(ラムダ)を 使います。

pythonしよう!簡単なゲーム10:lambda 無名関数の解説
スック
スック

lambdaラムダ :によって、
removeリムーヴ(cloudクラウド)に ( )が あっても すぐ実行されなくなったね

これで、雲の動きを 途中で止めることが できます。

スック
スック

これで、雲の動きのプログラムは O.K!

ラッチ先生
ラッチ先生

まずは、ゲームを終了するgameゲーム_endエンド( )関数を 定義します・

pythonしよう!簡単なゲーム10:ポイント3の解説
Python
boon.on = True
boon.bg = None  #2 プロパティbgに None(無し)を設定する
Python
def game_end(bg, costume, sounds): #5 game_end()関数を 定義する
    boon.on = False #6 プロパティ:onを Falseに設定する
    boon.bg = bg #7 プロパティbgに 引数bgを設定する
    boon.image = costume #8 プロパティimageに 引数costumeを設定する
    sounds.play() #9 変数soundを 再生する
    music.stop() #10 BGMを 止める
Python
def draw():
    screen.fill("aqua")
    if boon.bg:     #3 もし プロパティbgに データが入ったら
        screen.blit(boon.bg, (0, 0)) #4 プロパティbgのデータを 表示する
    balloon.draw()
    boon.draw()
    for cloud in clouds: 
        cloud.draw()    

music.play("spirit") #1 BGMを 流す
Q
music モジュールとは
pythonしよう!簡単なゲーム10:musicモジュールの解説

60. music.play(“spirit”)

BGM提供:DOVA-SYNDROME
https://dova-s.jp/
Spiritby TECHNOTRAIN             

曲名の大文字は、小文字にしないとエラーが出るよ

Q
blit( )メソッドとは
pythonしよう!簡単なゲーム10:blit( )メソッドの解説

53. if boon.bg:
54. screen.blit(boon.bg, (0, 0))

game_end( bg, …)関数で、引数bgに 画像が設定されたら
53 if boon.bgで Trueに なります。

スック
スック

これで、gameゲーム_endエンド( )関数が 定義できました。

bgビージー は、backgroundバックグランドの 略語だよ

ラッチ先生
ラッチ先生

それでは、boonボーンが 上まで行ったら
gameゲーム_endエンド( )関数を 実行させて、ゲームクリアにします

Python
def boon_move():
    if boon.on:
        boon.y -= 1

        if keyboard.right: 
            boon.x = min(boon.x + 5, 700) 
Python
        if boon.top < 0:    
            game_end("bg_clear", "boon_ok", sounds.accent_brilliant_02_low) #1 game_end()関数を 実行する
スック
スック

あれっ? クリアになっても 雲が 動いているよ

ラッチ先生
ラッチ先生

unscheduleアンスケジュール( )メソッドで、cleateクリエイト_cloudクラウド関数を止めましょう。
それで、雲は 新しく作り出されません。

また、今動いている雲は、プロパティ:animアニメ
stopストップ()メソッドを設定して 止めます。

最後に、clearクリア()メソッドを使って
リストcloudsクラウズを空にすれば、雲は一斉に 消えるよ

Python
def game_end(bg, costume, sounds): 
    boon.on = False 
    boon.bg = bg 
    boon.image = costume 
    sounds.play() 
    music.stop() 
    clock.unschedule(create_cloud) #1 create_cloudスケージュールを中止
    for cloud in clouds: #2 リストcloudsから 雲を取り出す
        cloud.anim.stop() #3 アニメーションを 中止にする
    clouds.clear()  #4 リストcloudsの中身を 削除する
Q
unschedule( )メソッドとは
pythonしよう!簡単なゲーム10:unschedule( )メソッドの解説
Q
clear( )メソッドとは
pythonしよう!簡単なゲーム10:clear( )メソッドの解説
スック
スック

おおっ! 雲が なくなったね

ラッチ先生
ラッチ先生

つぎは、boonsボーンズが 雲に当たったら、下へ 移動させるよ

boonsボーンズに プロパティ:hitヒット を追加して、
雲に当たったらどうか わかるようにしよう

pythonしよう!簡単なゲーム10:プロパティ:hitの解説
雲に 触れた時のプログラム

1. boonボーン の画像を ”boonボーン_ouchアウチィ“に する
2. 効果音を 鳴らす (bump_lowbit_03)
3. boonボーンのy座標を 600にする

pythonしよう!簡単なゲーム10:雲に触れるプログラムの解説
Python
boon.on = True
boon.bg = None
boon.hit = False #1 プロパティhitに Falseを設定する

def boon_move():
    if boon.on:
        boon.y -= 1

        if keyboard.right: 
            boon.x = min(boon.x + 5, 700) 
Python
        if boon.top < 0:
            game_end("bg_clear", "boon_ok", sounds.accent_brilliant_02_low)

        for cloud in clouds: #2 リストcloudsから 雲を取り出す
            if cloud.collide_pixel(boon) and not boon.hit:  #3 もし boonに 触れて そして プロパティhitが Falseだったら
                boon.hit = True #4 プロパティhitを Trueに設定する
                boon.image = "boon_ouch" #5 画像を ”boon_ouch"にする
                sounds.bump_lowbit_03.play() #6 効果音を 鳴らす
                boon.y = 600 #7 boonのy座標を 600に設定する
                break #8 繰り返しを 抜ける
Q
collide_pixel( )メソッドとは
pythonしよう!簡単なゲーム10:collide_pixel( )メソッドの解説
スック
スック

あれっ? 1回だけだね…

ラッチ
ラッチ

おおっぉぉぉ…!
これだと、プロパティhitヒットTrueトゥルーのままだから
雲に衝突しても 反応しないぞ

それでは、boonボーンが上昇してx座標が550以下になったら
プロパティhitヒットFalseフォルスにして 元にもどそう!

Python
def boon_move():
    if boon.on:
        boon.y -= 1

        if keyboard.right: 
            boon.x = min(boon.x + 5, 700) 
Python
        for cloud in clouds: 
            if cloud.collide_pixel(boon) and not boon.hit:  
                boon.hit = True 
Python
        if boon.y < 550 and boon.on: #1 y座標が 550未満 かつ プロパティonが Trueなら
            boon.hit = False        #2 プロパティhitを Falseに設定する
            boon.image = "boon"     #3 画像を "boon"に設定する
スック
スック

見事クリア!

スック
スック

風船に 触れると ゲームオーバーに なるんだね

ラッチ先生
ラッチ先生

そうです。
それでは、風船を animateアニメイト( )関数を使って、
風船を動かす balloonバルーン_moveムーヴ()関数を 定義しましょう

targetターゲット_x : 次の到着地点のx座標
targetターゲット_y : 次の到着地点のy座標
durデュレ_timeタイム: 次の到着地点へ動く時間

この3点を ランダムに決めます。

pythonしよう!簡単なゲーム10:風船の動ける範囲の解説
Python
def game_end(bg, costume, sounds): 
    boon.on = False 
    boon.bg = bg 
Python
def balloon_move(): #1 balloon_move()関数を 定義する
    target_x = random.randint(0, 800) #2 変数target_xに 0~800からランダムに選んだ数値を 設定する
    target_y = random.randint(100, 400) #3 変数target_yに 100~400からランダムに選んだ数値を 設定する
    dur_time = random.uniform(1, 2)     #4 変数dur_timeに 1~2からランダムに選んだ小数を 設定する
    animate(balloon, pos = (target_x, target_y), duration = dur_time, on_finished = balloon_move) #5 風船の動きアニメーションを作る
      
balloon_move() #6 balloon_move()関数を実行する
Q
uniform( )関数 とは?
pythonしよう!簡単なゲーム10:uniform()関数の解説
Q
animate( )関数 とは
pythonしよう!簡単なゲーム10:animate( )関数の解説
スック
スック

あれっ? boonボーンが クリアにしても まだ 風船が 動いているよ

ラッチ
ラッチ

おぉぉぉ…と いけない!

風船のアニメーションも プロパティanimアニメに 代入しましょう
そうすれば、stopストップ( )メソッドで ゲームクリアした時に
止めることが できますね

Python
def game_end(bg, costume, sounds): 
    boon.on = False 
    boon.bg = bg 
Python
    clouds.clear()
    balloon.anim.stop() #2 風船のアニメーションを 止める

def balloon_move(): 
    target_x = random.randint(0, 800) 
    target_y = random.randint(100, 400) 
    dur_time = random.uniform(1, 2)     
    balloon.anim = animate(balloon, pos = (target_x, target_y), duration = dur_time, on_finished = balloon_move) #1 プロパティanimに アニメーションを代入する
スック
スック

いいねぇ! クリアしたら 止まったね

ラッチ先生
ラッチ先生

それでは、最後に collideコライド_pixelピクセル()メソッドを使って
風船に 触れたら ゲームオーバーに するよ

pythonしよう!簡単なゲーム10:ポイント3の解説
Python
def boon_move():
    if boon.on:
        boon.y -= 1

        if keyboard.right:
            boon.x = min(boon.x + 5, 700)  
Python
        if boon.collide_pixel(balloon): #1 風船に 触ったら
            game_end("bg_over", "boon_ouch", sounds.kiga_nukeru_01_long) #2 game_end( )関数を 実行する
Q
collide_pixel( )メソッド とは?
pythonしよう!簡単なゲーム10:collide_pixel( )メソッドの解説
スック
スック

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

ラッチ先生
ラッチ先生

今回は、
animateアニメイト( )関数を使って雲や風船をランダムに動かすプログラムを作りました。

宇宙へ GO!
Python
import pgzrun
from pgzhelper import *
import random

WIDTH = 800
HEIGHT = 600

boon= Actor("boon", (400, 600))
balloon = Actor("balloon", (400, 100))

boon.on = True  
boon.bg = None 
boon.hit = False  

def boon_move(): 
    if boon.on:  
        boon.y -= 1 

        if keyboard.right: 
            boon.x = min(boon.x + 5, 700) 

        elif keyboard.left: 
            boon.x = max(boon.x - 5, 100) 

        if boon.top <0:    
            game_end("bg_clear",
                     "boon_ok",
                     sounds.accent_brilliant_02_low) 

        for cloud in clouds: 
            if cloud.collide_pixel(boon) and not boon.hit:  
                boon.hit = True 
                boon.image = "boon_ouch" 
                sounds.bump_lowbit_03.play() 
                boon.y = 600 
                break 

        if boon.y < 550 and boon.on: 
            boon.hit = False        
            boon.image = "boon"     

        if boon.collide_pixel(balloon): 
            game_end("bg_over", "boon_ouch", sounds.kiga_nukeru_01_long) 
            
clouds = [] 

def create_cloud(): 
    x = random.randint(0, 800) 
    cloud = Actor("cloud", (x, 0)) 
    cloud.scale = random.uniform(0.8, 2.0) 
    target_x = random.randint(0, 800) 
    dur_time = random.uniform(1, 4) 
    cloud.anim = animate(cloud,
                         pos = (target_x, 600),
                         duration= dur_time,
                         on_finished=lambda:clouds.remove(cloud)) 
    clouds.append(cloud)
    clock.schedule(create_cloud, random.uniform(0.2, 1.5))

clock.schedule(create_cloud, random.uniform(0.2, 1.5)) 

def game_end(bg, costume, sounds): 
    boon.on = False 
    boon.bg = bg 
    boon.image = costume 
    sounds.play() 
    music.stop() 
    clock.unschedule(create_cloud) 
    for cloud in clouds: 
        cloud.anim.stop() 
    clouds.clear()  
    balloon.anim.stop() 
    
def balloon_move(): 
    target_x = random.randint(0, 800) 
    target_y = random.randint(100, 400) 
    dur_time = random.uniform(1, 2)     
    balloon.anim = animate(balloon,
                           pos = (target_x, target_y),
                           duration = dur_time,
                           on_finished = balloon_move) 
     
balloon_move() 

def update():
    boon_move() 

def draw():
    screen.fill("aqua")
    if boon.bg:     
        screen.blit(boon.bg, (0, 0)) 
    balloon.draw()
    boon.draw()
    for cloud in clouds: 
        cloud.draw()    

music.play("spirit") 

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

animateアニメイト( )関数で作ったアニメーションは、
最後まで 実行されてしまいます。

アニメーションの途中で止めたい時は、
変数やプロパティに animateアニメイトオブジェクトとして 代入しておこう

スック
スック

stopストップ() メソッドで止められちゃう。便利だね

それじゃ、またね!

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

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

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