簡単なゲーム

【Pygame Zero】簡単なゲーム16:ベストタイムに挑戦!

ratch2025

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

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

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

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

BGM提供: DOVA-SYNDROME
https://dova-s.jp/
「Are You Ready? 」 written by FLASH☆BEAT

効果音提供:otosozai.com
https://otosozai.com/
「se_sac02」: コミカル
「se_sad04」: 効果音
「se_moc07」: 効果音
「se_sud02」 :着信音

ラッチ先生
ラッチ先生

基礎プログラムと 画像を入れた
「簡単なゲーム16: ベストタイムを めざせ!」zipフォルダを
ダウンロードしてください

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

今回は、スクリーンの色を “lemonchiffonレモンシフォン“にしたよ

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

pythonしよう!簡単なゲーム16:ベストタイムを めざせ!zipの中身
スック
スック

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

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

BGM提供: DOVA-SYNDROME
https://dova-s.jp/
「Are You Ready? 」 written by FLASH☆BEAT

効果音提供:otosozai.com
https://otosozai.com/
「se_sac02」: コミカル
「se_sad04」: 効果音
「se_moc07」: 効果音
「se_sud02」 :着信音

pythonしよう!簡単なゲーム16:ベストタイムを めざせ!zipの中身
スポンサーリンク

車を 左右キーで 動かす

ポイントを ランダムに配置する

ベストタイムを 表示する

pythonしよう!簡単なゲーム16:ベストタイム表示の解説

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




ラッチ先生
ラッチ先生

今回の「ベストタイムを めざせ!」では、
・車が 動かす
・ポイントを ランダムに配置する
プログラムがあります。

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

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

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

ラッチ先生
ラッチ先生

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

pythonしよう!簡単なゲーム16:変数carの解説
スック
スック

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




ラッチ先生
ラッチ先生

今回は、
スクリーンに タイマーを表示します・

スック
スック

0.01秒ずつ増えていくタイマーを作るよ




ラッチ先生
ラッチ先生

最初に
スペースキーを押したら 車を動くプログラムを作りましょう

プロパティactiveアクティブを追加して、
Trueトゥルー/Falseフォルス で 車が動かすスイッチにします

pythonしよう!簡単なゲーム16:プロパティactiveの解説
Python
car.angle = 90
car.active = False  #1 プロパティactiveに Falseを設定する

def on_key_down(key): #2 キーが 押されたプログラムを 定義する
    if key == keys.SPACE: #3 もし スペースキーが 押されたら
        car.active = True #4プロパティactiveに Trueを設定する

def update():
スック
スック

スペースキーを押したら True になったね

ラッチ先生
ラッチ先生

つぎに、defデフ carカー_moveムーヴ()関数で、車の動きを定義しよう。

keyboardキーボードオブジェクトを使って
左右キーを使って 車を動かすよ

pythonしよう!簡単なゲーム16:keyboardオブジェクトの解説
Python
def car_move(): #1 car_move()関数を 定義する
    if car.active: #2 もし プロパティactiveが Trueなら
        if keyboard.right: #3 もし 右キーが 押されたら
            car.angle -= 3 #4 車の向きを 3° 減らす

        if keyboard.left: #5 もし 左キーが 押されたら
            car.angle += 3 #6 車の向きを 3° 増やす

        car.move_forward(5) #7 5pxずつ動かす
        
def update():
    car_move() #8 car_move()関数を 実行する
    
Q
move_forward( )メソッドとは?
pythonしよう!簡単なゲーム16:move_forward()メソッドの解説
スック
スック

あれれっ! 車が どっかへ行っちゃったよ

ラッチ先生
ラッチ先生

それでは、上下左右の端に当たったら 跳ね返るようにしよう

バウンディングボックスを使って プログラムを作ります。

スック
スック

跳ね返りの角度の出し方です。

pythonしよう!簡単なゲーム16:跳ね返りの角度の解説
Python
def car_move(): 
    if car.active: 
        if keyboard.right: 
            car.angle -= 3 

        if keyboard.left: 
            car.angle += 3 

        car.move_forward(5)

        if car.left < 0 or car.right > WIDTH: #1 左右の壁に当たったら
            car.left = max(car.left, 0) #2 左は、 左と0の大きい方を設定する
            car.right = min(car.right, WIDTH) #3 右は 右と800の小さい方を設定する
            sounds.se_sac02.play() #4 効果音を 鳴らす
            car.angle = 180 - car.angle #5 向きに 跳ね返った角度を設定する 

効果音提供:otosozai.com
https://otosozai.com/

「se_sac02」: コミカル

Q
min( )関数、max( )関数とは?
pythonしよう!簡単なゲーム16:min()関数、max()関数の解説
Q
soundsオブジェクト
pythonしよう!簡単なゲーム16:soundsオブジェクトの解説
ラッチ先生
ラッチ先生

今度は、上下の跳ね返りです。

Python
def car_move(): 
    if car.active: 
        if keyboard.right: 
            car.angle -= 3 
Python
        if car.top < 0 or car.bottom > HEIGHT: #1 上下の壁に当たったら
            car.top = max(car.top, 0) #2 上は、上と0の大きい方を設定する
            car.bottom = min(car.bottom, HEIGHT) #3 下は 下と600の小さい方を設定する
            sounds.se_sac02.play() #4 効果音を 鳴らす
            car.angle = -car.angle #5 向きに 跳ね返る角度を設定する
            
def update():
スック
スック

これで、車を動かすプログラムは完成!




ラッチ先生
ラッチ先生

5つのポイントを ランダムに配置しましょう

pythonしよう!簡単なゲーム16:跳ねポイント量産するの解説
スック
スック

リスト:point_images には、
用意したポイントの画像を 入れましょう

pythonしよう!簡単なゲーム16:リストpoint_images
Python
car.active = False  

points = [] #1 空のリストpointsを 準備する
point_images = ["1", "2", "3", "4", "5"] #2 リストpoint_imagesに 画像1~5 を代入する

def create_point(): #3 create_point関数を 定義する
    for i in range(5): #4 5回繰り返す
        x = random.randint(35, WIDTH-35) #5 変数xに 35~765からランダムに選んだ数値を 設定する
        y = random.randint(35, HEIGHT-35) #6 変数yに 35~565からランダムに選んだ数値を 設定する
        point = Actor(point_images[i], (x, y)) #7 ポイントを生成する 画像は i番目
        point.num = i #8 プロパティ番号に カウント変数iを設定する
        points.append(point) #9 リストpointsに 追加する

create_point() #10 create_point()関数を 実行する
Python
def draw():
    screen.fill("lemonchiffon")
    for point in points: #11 リストpointsから ポイントを取り出す
        point.draw() #12 ポイントを表示する
    car.draw()
Q
range( )関数とは?
pythonしよう!簡単なゲーム16:range()関数の解説
Q
append()メソッドとは?
pythonしよう!簡単なゲーム16:append()メソッドの解説
スック
スック

あれっ⁉ 車の下に 配置されたり、
ポイント同士 重なる時も あるねぇ…

ラッチ先生
ラッチ先生

そういう時は、
ポイントを配置する条件を 作成しましょう

★ ポイントを配置する 条件 ★

pythonしよう!簡単なゲーム16:ポイント:条件を変数に代入を解説
Q
collidelist_pixel( )メソッドとは?
pythonしよう!簡単なゲーム16:collidelist_pixel()メソッドの解説
Q
distance_to()メソッドとは?
pythonしよう!簡単なゲーム16:distance_to()メソッドの解説
ラッチ先生
ラッチ先生

whileホワイル Trueトゥルー: 構文で ポイントの場所を決めましょう

2つの条件が Trueトゥルーになったら
breakブレイク で このwhileホワイル構文を抜けて、 リストpoints に 追加しましょう

pythonしよう!簡単なゲーム16:while Ture構文の解説
Python
def create_point(): 
    for i in range(5):
        while True: #1 繰り返す
            x = random.randint(35, WIDTH-35) 
            y = random.randint(35, HEIGHT-35) 
            point = Actor(point_images[i], (x, y)) 
            point.num = i
            check_point = point.collidelist_pixel(points) == -1 #2 変数check_pointに 条件:他のポイントとは 重ならないを 代入する
            check_car = point.distance_to(car) > 100 #3 変数check_carに 条件:車との距離を 100px以上にするを 代入する
            if check_point and check_car: #4 2つの条件ともTureなら
                break #5 抜ける
        points.append(point) 
スック
スック

おおっ!お見事!




pythonしよう!簡単なゲーム16:ベストタイム表示の解説
ラッチ先生
ラッチ先生

get_point()関数で、
順番にポイントに触れたら きえるよう 定義しましょう

スック
スック

enumerate( )関数を 使って
リストpoints から ポイントと リスト番号も いっしょに取り出すよ

pythonしよう!簡単なゲーム16:enumerate()関数の解説
Python
point_images = ["1", "2", "3", "4", "5"]

def get_point(): #1 get_point()関数を定義する
    
    for i, point in enumerate(points): #2 リスト番号と ポイントを取り出す
        if point.collide_pixel(car) and i==0: #3 もし 車に 触れ かつ リスト番号が 0 なら
            sounds.se_sad04.play() #4 効果音を 鳴らす
            points.remove(point) #5 ポイントを リストpointsから削除する
Python
def update():
    car_move()
    get_point() #6 get_point()関数を 実行する
Q
remove( )メソッドとは?
pythonしよう!簡単なゲーム16:remove()メソッドの解説

効果音提供:otosozai.com
https://otosozai.com/
「se_sad04」: 効果音

スック
スック

なるほど! 
リストに入っている最初のポイントに触れれば
削除するように プログラムしたのね

ラッチ先生
ラッチ先生

そうです!スック。

次は、timer()関数で タイマーを定義しましょう

Python
point_images = ["1", "2", "3", "4", "5"]

time = 0 #1 変数time 初期値:0

def timer(): #2 timer()関数を 定義する
    global time #3 グローバル変数 time

    time += 0.01 #4 変数timeを 0.01ずつ増える
    time = round(time, 2) #5 変数timeを 小数点2桁にする
Python
def on_key_down(key): 
    if key == keys.SPACE: 
        car.active = True
        music.play("are_you_ready?") #7 BGMを 流す
        clock.schedule_interval(timer, 0.01) #8 0.01秒ごとに タイマーを 実行する
Python
def draw():
    screen.fill("lemonchiffon")
    screen.draw.text(f"TIME : {time}",
                     topleft=(10, 60),
                     fontsize=70,
                     color="blue") #6 タイマーを 表示する
Q
round( )関数とは?
pythonしよう!簡単なゲーム16:round()関数の解説
Q
play()メソッドとは?
pythonしよう!簡単なゲーム16:play()メソッドの解説
Q
schedule_interval()メソッドとは?
pythonしよう!簡単なゲーム16:schedule_interval()メソッドの解説
Q
text()メソッドとは?
pythonしよう!簡単なゲーム16:text()メソッドの解説

BGM提供: DOVA-SYNDROME
https://dova-s.jp/
「Are You Ready? 」 written by FLASH☆BEAT

スック
スック

あれっ? タイマーが 止まらないね…

ラッチ先生
ラッチ先生

大丈夫!
ちゃんとタイマーを止めるプログラムを作りますね

len()関数を使って、ポイントが なくなったらゴールです

pythonしよう!簡単なゲーム16:len()関数の解説
Python
def get_point(): 
    
    for i, point in enumerate(points): 
        if point.collide_pixel(car) and i==0: 
            sounds.se_sad04.play() 
            points.remove(point)

            if len(points) == 0: #1 もし リストpointsの要素が 0になったら
                clock.unschedule(timer) #2 timer関数を 止める
                music.stop() #3 BGMを 止める
                car.active = False #4 プロパティactiveを Falseに設定する
スック
スック

おおっ!タイマーが止まったね

ラッチ先生
ラッチ先生

プロパティ bg を追加して、
ゴールしたら、背景画像が表示できるようにしよう

pythonしよう!簡単なゲーム16:プロパティbgの解説
Python
car.active = False
car.bg = None #1 プロパティbgに None(無し)を設定する
Python
def get_point():    
    for i, point in enumerate(points): 
        if point.collide_pixel(car) and i==0: 
            sounds.se_sad04.play() 
            points.remove(point)

            if len(points) == 0: 
                clock.unschedule(timer) 
                music.stop() 
                car.active = False
                sounds.se_sud02.play() #2 効果音を 鳴らす
                car.bg = "bg_goal"   #3 プロパティbgに "bg_goal"画像を設定する
Python
def draw():
    if car.bg: #4 もし プロパティbgに 画像が入ったら
        screen.blit(car.bg, (0, 0)) #5 プロパティbgの背景画像を表示する
    else: #6 その他
        screen.fill("lemonchiffon")

効果音提供:otosozai.com
https://otosozai.com/
「se_sud02」 :着信音

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

ゴールしたことが わかるね

ラッチ先生
ラッチ先生

Rキーを押したら、リスタートできるよう
def reset() 関数を 定義しましょう

Python
time = 0

def reset(): #1 reset()関数を 定義する
    global time #2 グローバル変数 time

    car.image = "car" #3 車の画像を carに設定する
    car.pos = (400, 500) #4 車の位置を (400, 500)に設定する
    car.angle = 90 #5 車の向きを 90°に設定する
    car.bg = None #6 背景画像を None(無し)に設定する
    time = 0 #7 変数timeに 0を代入する
    create_point() #8 create_point()関数を 実行する
Python
def on_key_down(key): 
    if key == keys.SPACE: 
        car.active = True
        music.play("are_you_ready?") 
        clock.schedule_interval(timer, 0.01)

    elif key == keys.DOWN: #9 もし 下ボタンを押したら
        reset() #10 reset()関数を 実行する
スック
スック

これで、何回もチャレンジできるね

ラッチ先生
ラッチ先生

さあ、ベストタイムを 表示させましょう!

準備として、
・ 変数 best_time : ベストタイムを 入れる
を 用意して、初めのタイムを 最初のベストタイムにします

Python
time = 0
best_time = None #1 変数best_timeに None(無し)を設定する
Python
def get_point():
    global best_time #2 グローバル変数best_time
    
    for i, point in enumerate(points): 
        if point.collide_pixel(car) and i==0: 
            sounds.se_sad04.play() 
            points.remove(point)

            if len(points) == 0: 
                clock.unschedule(timer) 
                music.stop() 
                car.active = False
                if not best_time: #3 もし 変数best_timeに データが入っていなかったら
                    best_time = time #4 変数best_timeに 変数timeのデータを 代入する
                sounds.se_sud02.play() 
                car.bg = "bg_goal" 
Python
def draw():
    if car.bg: 
        screen.blit(car.bg, (0, 0)) 
    else: 
        screen.fill("lemonchiffon")
    if best_time: #5 もし 変数best_timeに データが入っていたら
        screen.draw.text(f"BEST : {best_time}",
                         topleft = (10, 10),
                         fontsize=60,
                         color="red") #5 変数best_timeを 表示する
スック
スック

あれっ?ベストタイムを 出しているのに 変わらないよ

ラッチ先生
ラッチ先生

だいじょうぶ!

2回目以降は、ベストタイムより早いタイムを出したら
更新するプログラムを作るよ

Python
def get_point():
    global best_time 
    
    for i, point in enumerate(points): 
        if point.collide_pixel(car) and i==0: 
            sounds.se_sad04.play() 
            points.remove(point)

            if len(points) == 0: 
                clock.unschedule(timer) 
                music.stop() 
                car.active = False

                if (best_time and #1 もし変数best_timeに データがあり
                 best_time >= time): #2 かつ 変数beat_timeより 変数timeが小さいなら
                    best_time = time #2 変数best_timeに 変数timeの当たりを 代入する
                    sounds.se_moc07.play() #3 効果音を 鳴らす
                    car.image = "car_best" #4 車の画像を "car_best"に設定する
                    car.bg = "bg_best" #5 プロパティbgに "bg_best"画像を設定する
                else: #6 その他は
                    if not best_time:
                        best_time = time 

効果音提供:otosozai.com
https://otosozai.com/
「se_moc07」: 効果音

スック
スック

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




ラッチ先生
ラッチ先生

今回は、
ベストタイムを表示するプログラムを作りました。

ベストタイムを めざせ!
Python
import pgzrun
from pgzhelper import * 
import random 

WIDTH = 800
HEIGHT = 600

car = Actor("car", (400, 500))
car.angle = 90
car.active = False  
car.bg = None 

points = [] 
point_images = ["1", "2", "3", "4", "5"] 

time = 0 
best_time = None

def reset(): 
    global time 

    car.image = "car" 
    car.pos = (400, 500) 
    car.angle = 90 
    car.bg = None 
    time = 0 
    create_point() 
    
def timer(): 
    global time 

    time += 0.01 
    time = round(time, 2) 

def get_point(): 
    global best_time 
    for i, point in enumerate(points): 
        if point.collide_pixel(car) and i==0: 
            sounds.se_sad04.play() 
            points.remove(point) 

            if len(points) == 0: 
                clock.unschedule(timer) 
                music.stop() 
                car.active = False 

                if (best_time and
                    best_time >= time): 
                    best_time = time 
                    sounds.se_moc07.play() 
                    car.image = "car_best" 
                    car.bg = "bg_best" 
                else: 
                    if not best_time:   
                        best_time = time 
                    sounds.se_sud02.play() 
                    car.bg = "bg_goal"   
                    
def create_point(): 
    for i in range(5): 
        while True: 
            x = random.randint(35, WIDTH-35) 
            y = random.randint(35, HEIGHT-35) 
            point = Actor(point_images[i], (x, y)) 
            point.num = i 
            check_point = point.collidelist_pixel(points) == -1 
            check_car = point.distance_to(car) > 100 
            if check_point and check_car: 
                break 
        points.append(point) 

create_point() 

def on_key_down(key): 
    if key == keys.SPACE: 
        car.active = True 
        music.play("are_you_ready?") 
        clock.schedule_interval(timer, 0.01) 

    elif key == keys.DOWN: 
        reset() 

def car_move(): 
    if car.active: 
        if keyboard.right: 
            car.angle -= 3 

        if keyboard.left: 
            car.angle += 3 

        car.move_forward(5) 

        if car.left < 0 or car.right > WIDTH: 
            car.left = max(car.left, 0) 
            car.right = min(car.right, WIDTH) 
            sounds.se_sac02.play() 
            car.angle = 180 - car.angle 
        
        if car.top < 0 or car.bottom > HEIGHT: 
            car.top = max(car.top, 0) 
            car.bottom = min(car.bottom, HEIGHT) 
            sounds.se_sac02.play() 
            car.angle = -car.angle 

def update():
    car_move() 
    get_point() 

def draw():
    if car.bg: 
        screen.blit(car.bg, (0, 0)) 
    else: 
        screen.fill("lemonchiffon")
    if best_time:
        screen.draw.text(f"BEST : {best_time}",
                         topleft = (10, 10),
                         fontsize=60,
                         color="red")
    screen.draw.text(f"TIME : {time}",
                     topleft=(10, 60),
                     fontsize=70,
                     color="blue") 
    for point in points: 
        point.draw() 
    car.draw()

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

タイマーを表示する時
小数の場合は、 roundラウンド( )関数 を使って小数点以下の桁数を
そろえましょう

pythonしよう!簡単なゲーム16:round()関数の解説
スック
スック

みんなも、タイマー付きのゲームをつくってみよう!

それじゃあ、またね!

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

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

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