【Pygame Zero】簡単なゲーム21:運命の分かれ道!あみだくじゲーム
こんにちは!
「Pythonしよう!楽しく学べるプログラミング教室」の
ラッチ先生です


スックです。よろしくね!
BGM提供: DOVA-SYNDROME
https://dova-s.jp/
・ 「晴色カレイドスコープ」 written by まんぼう二等兵
効果音提供:効果音ラボ
https://soundeffect-lab.info/
・ 「間抜け4」: アニメ
・ 「決定ボタンを押す3」: ボタン・システム音
・ 「成功音」: ボタン・システム音

基礎プログラムと 画像を入れた
「簡単なゲーム21: boon あみだくじ!」zipフォルダを
ダウンロードしてください



このゲームで使用している音声ファイルは、
以下のサイトからお借りしています。
各自でダウンロードして、該当するフォルダに入れてください!
BGM提供: DOVA-SYNDROME
https://dova-s.jp/
・ 「晴色カレイドスコープ」 written by まんぼう二等兵
効果音提供:効果音ラボ
https://soundeffect-lab.info/
・ 「間抜け4」: アニメ
・ 「決定ボタンを押す3」: ボタン・システム音
・ 「成功音」: ボタン・システム音

学習の流れ
あみだくじを 作る
3つのボタンを作る
boonが 動く
結果発表

プログラムを 実行してみよう
プログラミングの仕方を説明します
モジュールを 用意する
★ラッチ先生の言葉から

今回の「boon あみだくじ!」では、
・ あみだくじを 作る
・ ボタンを クリックする
プログラムがあります。
そこで、2つのモジュールを 用意しました



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


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

今回のプログラミングのポイントが こちらです


『dir』 は、「duration(方向)」の略語だよ
あみだを 作る

最初に
左側の横棒を 全部表示しましょう
空リストbars を 作成して、9本のbar を生成して追加しましょう

bg_img = "bg"
bars = [] #1 空リストbarsを 作成する
for i in range(9): #2 9回繰り返す
bar = Actor("bar", (275, 100 + 50 * i)) #3 線を 生成する
bars.append(bar) #4 リストbarsに 追加するdef draw():
screen.blit(bg_img, (0, 0))
for bar in bars: #5 リストbarsから barを取り出す
bar.draw() #6 barを表示する
boon.draw()
- range関数とは?

- append( )メソッドとは?


barのy座標を 50pxずつ ずらしたんだね

そうです!
同じように 右側の横棒も全部表示しましょう
for i in range(9):
bar = Actor("bar", (275, 100 + 50 * i))
bars.append(bar)
for i in range(8): #1 8回繰り返す
bar = Actor("bar", (525, 125 + 50 * i)) #2 線を 生成する
bars.append(bar) #2 リストbarsに 線を追加する
def update():

左側のbar のy座標から 25pxずれてるね

random( )メソッドを使って
横棒の出る確率を80%にします。
そうすると、毎回違うあみだくじができます

for i in range(9):
if random.random() < 0.8: #1 もし 0.8未満なら
bar = Actor("bar", (275, 100 + 50 * i))
bars.append(bar)
for i in range(8):
if random.random() < 0.8: #2 もし 0.8未満なら
bar = Actor("bar", (525, 125 + 50 * i))
bars.append(bar) 
おおっ!いいねぇ
3つのボタンを 作る

まず、スタート地点に、
ボタンとして3つのboonを 表示しよう。
buttons = [] #1 空リストbuttonsを 作成する
for i in range(3): #2 3回繰り返す
button = Actor("boon", (150 + 250 * i, 50)) #3 ボタンを生成する
buttons.append(button) #4 リストbuttonに ボタンを追加する
def update():
pass
def draw():
screen.blit(bg_img, (0, 0))
for bar in bars:
bar.draw()
boon.draw()
for button in buttons: #5 リストbuttonsから ボタンを取り出す
button.draw() #6 ボタンを 表示する

変数game を 作成して、
あみだくじの ゲームを 3つに 構成します。

bg_img = "bg"
game = "ready" #1 変数gameを 宣言する 初期値:ready
変数game で、ゲームの流れがわかるんだね

on_mouse_down関数で
ボタンをクリックしたら boon を表示させるよ

def on_mouse_down(pos): #2 クリックした関数を 定義する
global game #3 グローバル変数 game
for button in buttons: #4 リストbuttonsから ボタンを取り出す
if button.collidepoint_pixel(pos): #5 もし ボタンをクリックしたら
sounds.決定ボタンを押す3.play() #6 効果音を 鳴らす
game = "play" #7 変数gameを playに設定する
boon.x = button.x #8 boonのx座標に ボタンのx座標を設定する
buttons.clear() #9 リストbuttonsを 空にする
break #10 ループが 終わる
def update():効果音提供:効果音ラボ
https://soundeffect-lab.info/
・ 「決定ボタンを押す3」: ボタン・システム音
- collidepoint_pixel( )メソッドとは?

- 効果音に ついて?

- clear( )メソッドとは?


おおっ!クリックした所に boonが登場したね
boonが 動く

それでは、boon を動かすプログラムを作ろう
boon_move関数では、
プロパティ:dir を使って
・ ”down“: move_down関数(下へ動く関数)
・ “side” :move_side関数(横へ動く関数)
それぞれの関数を 実行させるプログラムを作ります


boon の動く速さを 定数SPEEDに 「5」と設定します。
SPEED = 5 #1 定数SPEED 5 と設定する
boon = Actor("boon", (150, 50))
boon.dir = "down" #2 プロパティ:dir "down"と設定する
bg_img = "bg"def boon_move(): #3 boon_move関数を 定義する
if game != "play": #4 もし 変数gameが playでなければ
return #5 返す
if boon.dir == "down": #6 もし プロパティdirが downなら
move_down() #7 move_down関数を 実行する
def move_down(): #8 move_down関数を 定義する
if boon.y < 550: #9 もし y座標が 550未満なら
boon.y += SPEED #10 y座標は 定数SPEEDずつ増やす
def update():
boon_move() #11 boon_move関数を 実行する
def draw():
y:550で 止まるね

次に、boon が 横棒の左右どちらに動くか判断する
check_bar関数を 作ります。
基本は以下の3点です。

boon = Actor("boon", (150, 50))
boon.dir = "down"
boon.target_x = 0 #1 プロパティtarget_xに 0を設定する

追加プロパティ:target_x には、
横棒で進むときの 目的地のx座標が 入ります。
最初は、「0」に 設定しておくよ
def move_down():
if boon.y < 550:
boon.y += SPEED
check_bar() #2 check_bar関数を 実行する
def check_bar(): #3 check_bar関数を 定義する
for bar in bars: #4 リストbarsから バーを取り出す
left_x = bar.x - 125 #5 変数left_xに バーのx座標-125を設定する
right_x = bar.x + 125 #6 変数right_xに バーのx座標+125を設定する
if boon.y == bar.y: #7 もし boonのy座標が barのy座標と同じなら
if boon.x == left_x: #8 もし boonのx座標が 変数left_xと同じなら
boon.dir = "side" #9 プロパティdirに sideを設定する
boon.target_x = right_x #10 プロパティtarget_xに 変数right_xを設定する
elif boon.x == right_x: #11 もし boonのx座標が 変数right_xと同じなら
boon.dir = "side" #12 プロパティdirに sideを設定する
boon.target_x = left_x #13 プロパティtarget_xに 変数left_xを設定する
def update():

「ステップごと」「自動」をクリックしてみよう
check_bar関数のプログラムの動きが わかるよ!

プロパティdir が、side になった時の
boon が横に動く move_side関数を 定義しましょう
def boon_move():
if game != "play":
return
if boon.dir == "down":
move_down()
elif boon.dir == "side": #1 もし プロパティdirが sideなら
move_side() #2 move_side関数を 実行する
def move_down(): def move_side(): #3 move_side関数を 定義する
if boon.x < boon.target_x: #4 もし x座標が プロパティtarget_xより 小さかったら
boon.flip_x = False #5 プロパティflip_xを Falseに 設定する
boon.x += SPEED #8-6 x座標を SPEEDごと増やす
else: #7 その他
boon.flip_x = True #8 プロパティflip_xを Trueに 設定する
boon.x -= SPEED #9 x座標を SPEEDごと 減らす
if boon.x == boon.target_x: #10 もし x座標が プロパティtarget_xを同じになったら
boon.dir = "down" #11 プロパティdirに downを設定する
def update():
これで、boonの動きは OK!

boonが y座標:400になるまで、カバーをかけて
おもしろくするよ
def draw():
screen.blit(bg_img, (0, 0))
for bar in bars:
bar.draw()
boon.draw()
for button in buttons:
button.draw()
if boon.y < 400: #1 もし boonのy座標が400以下なら
screen.blit("cover", (0, 400)) #2 カバーを (0, 400)に表示する

おおっ、いいねえ!
結果発表


最初に、
ゴールの位置をrandint()関数を使って 決めます
boon.target_x = 0
goal = Actor("goal",
(150 + 250 * random.randint(0, 2), 550)) #1 ゴールの 生成する
bg_img = "bg"def draw():
screen.blit(bg_img, (0, 0))
for bar in bars:
bar.draw()
goal.draw() #2 ゴールを 表示する
boon.draw()
for button in buttons:
button.draw()
if boon.y < 400:
screen.blit("cover", (0, 400))
- randint関数とは?


これで、ゴールがランダムに 表示されるね

set_result関数で
結果発表のプログラムを定義しましょう

bg_img = "bg"
game = "ready"
result_txt = None #1 変数result_txtを宣言する 初期値:None(無し)
def set_result(bg,
costume,
sound,
text): #3 set_result()関数を 定義する
global game, bg_img, result_txt #4 グローバル変数 game, bg_img, result_txt
game = "result" #5 変数gameを resultに設定する
music.stop() #6 BGMを 止める
bg_img = bg #7 変数bg_imgに 引数bgを設定する
boon.image = costume #8 プロパティimageに 引数costumeを設定する
sound.play() #9 引数soundを 鳴らす
result_txt = text #10 変数result_txtに 引数textを設定する
def update():music.play("晴色カレイドスコープ") #2 BGMを 流す
pgzrun.go()- musicモジュールとは?


このset_result関数で、
クリアやゲームオーバーのプログラムを作るよ

move_down()関数で
boonのy座標が 550になった地点で 結果発表に なります
def move_down():
if boon.y < 550:
boon.y += SPEED
check_bar()
else: #1 その他(boonのy座標が 550以上なら)
if boon.x == goal.x: #2 もし x座標が ゴールのx座標と同じなら
set_result("bg_clear",
"boon_clear",
sounds.成功音,
"txt_clear") #3 set_result関数を 実行する
else: #4 その他(ゴールのx座標でないなら)
set_result("bg_over",
"boon_over",
sounds.間抜け4,
"txt_over") #4 set_result関数を 実行するdef draw():
screen.blit(bg_img, (0, 0))
for bar in bars:
bar.draw()
goal.draw()
boon.draw()
for button in buttons:
button.draw()
if boon.y < 400:
screen.blit("cover", (0, 400))
if result_txt: #5 もし 変数result_txtに データが入ったら
screen.blit(result_txt, (200, 150)) #6 テキストを 表示するBGM提供: DOVA-SYNDROME
https://dova-s.jp/
・ 「晴色カレイドスコープ」 written by まんぼう二等兵
効果音提供:効果音ラボ
https://soundeffect-lab.info/
・ 「間抜け4」: アニメ
・ 「決定ボタンを押す3」: ボタン・システム音
・ 「成功音」: ボタン・システム音

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

今回は、
あみだくじ ゲームを作りました。
import pgzrun
import random
from pgzhelper import *
WIDTH = 800
HEIGHT = 600
SPEED = 5
boon = Actor("boon", (150, 50))
boon.dir = "down"
boon.target_x = 0
goal = Actor("goal",
(150+250*random.randint(0, 2), 550))
bg_img = "bg"
game = "ready"
result_txt = None
bars = []
for i in range(9):
if random.random() < 0.8:
bar = Actor("bar", (275, 100 + 50 * i))
bars.append(bar)
for i in range(8):
if random.random() < 0.8:
bar = Actor("bar", (525, 125 + 50 * i))
bars.append(bar)
buttons = []
for i in range(3):
button = Actor("boon", (150 + 250 * i, 50))
buttons.append(button)
def on_mouse_down(pos):
global game
for button in buttons:
if button.collidepoint_pixel(pos):
sounds.決定ボタンを押す3.play()
game = "play"
boon.x = button.x
buttons.clear()
break
def boon_move():
if game != "play":
return
if boon.dir == "down":
move_down()
elif boon.dir == "side":
move_side()
def move_down():
if boon.y < 550:
boon.y += SPEED
check_bar()
else:
if boon.x == goal.x:
set_result("bg_clear",
"boon_clear",
sounds.成功音,
"txt_clear")
else:
set_result("bg_over",
"boon_over",
sounds.間抜け4,
"txt_over")
def check_bar():
for bar in bars:
left_x = bar.x - 125
right_x = bar.x + 125
if boon.y == bar.y:
if boon.x == left_x:
boon.dir = "side"
boon.target_x = right_x
elif boon.x == right_x:
boon.dir = "side"
boon.target_x = left_x
def move_side():
if boon.x < boon.target_x:
boon.flip_x = False
boon.x += SPEED
else:
boon.flip_x = True
boon.x -= SPEED
if boon.x == boon.target_x:
boon.dir = "down"
def set_result(bg,
costume,
sound,
text):
global game, bg_img, result_txt
game = "result"
music.stop()
bg_img = bg
boon.image = costume
sound.play()
result_txt = text
def update():
boon_move()
def draw():
screen.blit(bg_img, (0, 0))
for bar in bars:
bar.draw()
for button in buttons:
button.draw()
if boon.y < 400:
screen.blit("cover", (0, 400))
goal.draw()
if result_txt:
screen.blit(result_txt, (200, 150))
boon.draw()
music.play("晴色カレイドスコープ")
pgzrun.go()
check_bar()関数で
boonが あみだくじ上を動いています。


みなさんも、 あみだくじを作ってみよう!
それじゃあ、またね!






