【Pygame Zero】簡単なゲーム06:左右キーで車を動かそう!
こんにちは!
「Pythonしよう!楽しく学べるプログラミング教室」の
ラッチ先生です


スックです。よろしくね!
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Dancing In The Rain 」 by Kei Morimoto
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Brilliant [02] (Low)」:アクセント
・ 「Bump. Low-Bit [04B]」:アクションゲーム
・ 「Power Up Item [01] (Fast)」:アクションゲーム

基礎プログラムと 画像を入れた
「簡単なゲーム06 星を ゲット!」zipフォルダを ダウンロードしてください


今回は、スクリーンの色を “honeydew“に したよ
「原色大事典」サイトには、URL:https://www.colordic.org/
pygame zeroで使える色が載っています

学習の流れ
1秒ごとに ランダムな場所に 星を 表示する
左右キーで 車を動かす
獲得した星の数を表示する

BGM・効果音を 入れる
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Dancing In The Rain 」 by Kei Morimoto
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Brilliant [02] (Low)」:アクセント
・ 「Bump. Low-Bit [04B]」:アクションゲーム
・ 「Power Up Item [01] (Fast)」:アクションゲーム
プログラムを 実行してみよう
プログラミングの仕方を説明します
モジュールを 用意する

今回の「星を ゲット!」では、
・車が 星に触れる
プログラムがあります。
そこで、このモジュールを 用意しました


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

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


属性(データ)やメソッド(命令)は、
『 . (ドット)』を付ければ、使えるよ
今回のプログラミングのポイント

今回は、
車の跳ね返りを バウンディングボックスを使って
プログラムを作っていきます。

バウンディングボックスという四角形が
動き回っているというイメージだね

プロパティactiveが Trueなら 動く。Falseなら 止まる。だね
1秒ごとに ランダムな場所に 表示する

それでは、def star_move( )関数で 星の動きを定義しましょう。
while構文を使って
車に重ならないように 表示させましょう

star.active = True #1 プロパティactiveを Trueに設定するdef star_move(): #2 star_move()関数を 定義する
if star.active: #3 もし プロパティactiveが Trueだったら
while True: #4 繰り返す
x = random.randint(50, WIDTH-50) #5 変数xに 50~750からランダムに決めた数値を代入する
y = random.randint(50, HEIGHT-50) #6 変数yに 50~550からランダムに決めた数値を代入する
star.pos = x, y #7 星の座標に 変数x, yの数値を 代入する
if not star.collide_pixel(car): #7 もし 星が車に触れてなかったら
break #8 この関数を終了にする
星の動きを定義しただけで、実行しても、星はまだ動かないよ

そうですね。
schedule_interval()メソッドを使って
星を 1秒ごと ランダムな場所に表示させます。

clock.schedule_interval(star_move, 1.0) #9 1秒経ったら 関数star_moveを実行するを 繰り返す
これで、星の動きは、O.K!
左右キーで 車を動かす

つぎは、車を動かすプログラムを作りましょう
車の向きを 90°にして上向きにします。
プロパティactiveを追加して、Trueにしておきます。
car.angle = 90 #1 車の向きに 90°と設定する
car.active = True #2 プロパティactive(動作)に Trueを設定する

車が 上に向いたね

つぎに、def car_move()関数で、車の動きを定義しよう。
keyboardオブジェクトを使って
左右キーを使って 車を動かすよ

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(): #8 更新する
car_move() #9 car_move()関数を 実行する
あれれっ! 車が どっかへ行っちゃったよ

それでは、上下左右の端に当たったら 跳ね返るようにしよう
今回は、バウンディングボックスを使って プログラムを作ります。

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

def car_move():
if car.active:
if keyboard.right:
car.angle -= 3
if keyboard.left:
car.angle += 3
car.move_forward(5)
if car.right > WIDTH or car.left < 0: #1 もし プロパティrightが800pxより大きい また プロパティleftが 0pxより小さくなったら
if car.right > WIDTH: #2 もし プロパティrightが 800pxより大きかったら
car.right = WIDTH #3 プロパティrightに 800を代入する
elif car.left < 0: #4 もし プロパティleftが 0pxより小さかったら
car.left = 0 #5 プロパティleftに 0を代入する
car.angle = 180 - car.angle #6 車の向きに 180-車の向きを 代入する
if car.top < 0 or car.bottom > HEIGHT: #7 プロパティtopが0pxより小さい または プロパティbottomが600pxより大きかったら
if car.top < 0: #8 プロパティtopが 0より小さかったら
car.top = 0 #9 プロパティtopに 0pxを代入する
elif car.bottom > HEIGHT: #10 もし プロパティbottomが 600pxより大きかったら
car.bottom = HEIGHT #11 プロパティbottomに 600を代入する
car.angle = -car.angle #12 車の向きに -1×(車の向き)を代入する
いいね!
獲得した星の数を 表示する


変数scoreを 作って、ゲットした星の数を入れましょう
collide_pixel()メソッドを使って、
星に触れたら、1ずつ増やしていきます。

score = 0 #1 変数scoreを 宣言する 初期値: 0def car_move():
global score #2 グローバル変数 score
if car.active:
if keyboard.right:
car.angle -= 3 if car.collide_pixel(star): #3 もし 車が 星に触れたら
if star.active: #4 もし 星プロパティactiveが Trueなら
score += 1 #5 変数scoreのデータに 1増やす
star.active = False #6 星プロパティactiveに Falseを代入する
star.image = "star1" #7 星の画像に "star1"に設定する
else: #8 その他(車が星に触れていなければ)
star.active= True #9 星プロパティactiveに Trueを代入する
star.image = "star" #10 星の画像を "star"に設定する
車が 星に触れている間は、star.activeが 『False』だから
変数scoreは 1増えるだけだよ

30秒後に ゲットした星の数を 表示しましょう
まず、
結果発表として def game_result()関数で
プロパティactiveに Falseに 設定して
動きを止めるように 定義しましょう
次に、schedule_unique()メソッドを使って
30秒後に game_result()関数を 実行させましょう

def game_result(): #1 game_result()関数を 定義する
car.active = False #2 車のプロパティactiveに Falseを設定する
star.active = False #3 星のプロパティactiveに Falseを設定する
clock.schedule_unique(game_result, 30.0) #4 30秒後に game_result関数を実行する
30秒後に 止まったぞ!

blit()メソッドで、背景画像を表示します。


text()メソッドで 星の獲得した数を 表示します。

def draw():
screen.fill("honeydew")
if not car.active and not star.active: #1 もし 車のプロパティactiveがFalse かつ 星のプロパティactiveが Falseなら
screen.blit("bg_result", (0, 0)) #2 背景画像 "bg_result"を 表示する
screen.draw.text(f"Stars: {score}", center=(400, 100), fontsize=100, color="blue") #3 テキストを表示する
else: #4 その他(結果発表以外)
star.draw() #5 星を表示する☚つまり、結果発表の時 消える
car.draw()
f文字列で、簡単に文字列と変数のデータを表示できるんだ!

BGM・効果音を入れる
BGM提供:DOVA-SYNDROME
https://dova-s.jp/
・ 「Dancing In The Rain 」 by Kei Morimoto
効果音提供:Chisato’s Website
https://chisatosound.sakura.ne.jp/index.html
・ 「Accent. Brilliant [02] (Low)」:アクセント
・ 「Bump. Low-Bit [04B]」:アクションゲーム
・ 「Power Up Item [01] (Fast)」:アクションゲーム

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

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

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

def game_result():
car.active = False
star.active = False
music.stop() #2 BGMを 止めるmusic.play("dancing_in_the_rain") #1 BGMを 入れる
今回のプログラムに「DOVA-SYNDROME」サイトから
・ 「Dancing In The Rain 」 by Kei Morimoto
BGMの曲として お借りしました。 ありがとうございます。

つぎに
効果音をつけましょう!
・ 上下左右の端に触れた時
・ 星を ゲットした時
・ 結果発表
Python zeroには、soundsオブジェクトが標準装備であります。
次の手順で 行います
効果音のつけ方
1. WAVファイルの効果音を 用意する



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

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


今回のプログラムに
「Chisato’s Website」サイトから
・ 「Accent. Brilliant [02] (Low)」:アクセント
・ 「Bump. Low-Bit [04B]」:アクションゲーム
・ 「Power Up Item [01] (Fast)」:アクションゲーム
効果音を お借りしました。 ありがとうございます。
def car_move():
global score
if car.active:
if keyboard.right:
car.angle -= 3 if car.right > WIDTH or car.left < 0:
sounds.bump_lowbit_04b.play() #1 左右端 効果音入れる
if car.right > WIDTH: if car.top < 0 or car.bottom > HEIGHT:
sounds.bump_lowbit_04b.play() #2 上下端 効果音を入れる
if car.top < 0: if car.collide_pixel(star):
if star.active:
score += 1
star.active = False
star.image = "star1"
sounds.power_up_item_01_fast.play() #3 星をゲット 効果音を入れるdef game_result():
car.active = False
star.active = False
music.stop()
sounds.accent_brilliant_02_low.play() #4 結果発表 効果音を入れる
今回の学習は、これで 終了! おつかれさま
まとめ

今回は、
左右キーで 車を操作するプログラムを 作りました。
import pgzrun
from pgzhelper import *
import random
WIDTH = 800
HEIGHT = 600
car = Actor("car", (400, 500))
star = Actor("star", (100, 100))
star.active = True
car.angle = 90
car.active = True
score = 0
def draw():
screen.fill("honeydew")
if not car.active and not star.active:
screen.blit("bg_result", (0, 0))
screen.draw.text(f"Stars: {score}", center=(400, 100), fontsize=100, color="blue")
else:
star.draw()
car.draw()
def star_move():
if star.active:
while True:
x = random.randint(50, WIDTH-50)
y = random.randint(50, HEIGHT-50)
star.pos = x, y
if not star.collide_pixel(car):
break
clock.schedule_interval(star_move, 1.0)
def car_move():
global score
if car.active:
if keyboard.right:
car.angle -= 3
if keyboard.left:
car.angle += 3
car.move_forward(5)
if car.right > WIDTH or car.left < 0:
sounds.bump_lowbit_04b.play()
if car.right > WIDTH:
car.right = WIDTH
elif car.left < 0:
car.left = 0
car.angle = 180 - car.angle
if car.top < 0 or car.bottom > HEIGHT:
sounds.bump_lowbit_04b.play()
if car.top < 0:
car.top = 0
elif car.bottom > HEIGHT:
car.bottom = HEIGHT
car.angle = -car.angle
if car.collide_pixel(star):
if star.active:
score += 1
star.active = False
star.image = "star1"
sounds.power_up_item_01_fast.play()
else:
star.active= True
star.image = "star"
def game_result():
car.active = False
star.active = False
music.stop()
sounds.accent_brilliant_02_low.play()
clock.schedule_unique(game_result, 30.0)
def update():
car_move()
music.play("dancing_in_the_rain")
pgzrun.go()
キャラクターをスクリーンから はみ出さないようにするには
バウンディングボックスを使うと 便利です

みんなも バウンディングボックスを使ってみてね
それじゃ、またね!
