【Pygame Zero】キャラクターを点滅させよう!

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


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

基礎プログラムと 画像を入れた
「見た目07 boonのねらえ!No.4」zipフォルダを ダウンロードしてください



この基礎プログラムは、こちらの記事で解説しています

学習の流れ
矢印をクリックすると 飛び出す
boonが ななめに 動き続ける
点滅する
プログラムを 実行してみよう
プログラミングの仕方を説明します
モジュールを 用意する

今回の「boonをねらえ!No.4」では、
・ 矢印を クリックする
・ boonが ななめに動き続ける
・ boon の明るさを 変える
プログラムが あります
そこで、2つのモジュールを 用意しました



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

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


これで、変数boonに「 . (ドット)」を付ければ 使えるよ


明るさ100にすると、見えなくなるよ


それぞれの動きが わかりやすくなるよ


両方 2つに 分けたよ
矢印をクリックすると 飛び出す

最初に、
変数arrow_directionに 「-1」を代入して、
矢印を 右回りに回転させます

arrow.angle = 180
arrow_direction = -1 #1 変数arrow_direction(方向)に -1を 代入する
arrow_state = "rotate" #2 変数arrow_state(状態)に "rotate(回転)"を 代入する
def arrow_move(): #3 矢印の動きを まとめる
global arrow_state, arrow_direction #4 グローバル変数
if arrow_state == "rotate": #5 もし、変数arrow_stateが ”rotate(回転)" だったら
arrow.angle += arrow_direction #6 矢印の向きを 変数arrow_direction ずつ触れる
def update(): #7 更新する
arrow_move() #8 矢印の動きを 動かす

あららっ⁉ 回転しすぎ…

だいじょうぶ!
変数arrow_direction に、「-1」をかけることによって
矢印の方向を 反転させよう
def arrow_move():
global arrow_state, arrow_direction, boon_state, count
if arrow_state == "rotate":
arrow.angle += arrow_direction
if arrow.angle < 90 or arrow.angle > 180: #1 もし、矢印の向き 90度未満 または、 180以上なら
arrow_direction = -arrow_direction #2 -(arrow_direction) を 変数arrow_directionに 代入する

-(arrow_direction) とは、-1 × arrow_direction だよ

つぎは、
collidepoint_pixel( ) メゾットを使って
クリックしたら 矢印が 飛ぶようにしよう

def on_mouse_down(pos): #1 クリックした座標(pos)を取得する
global arrow_state #2 グローバル変数:arrow_state
if arrow_state == "rotate" and arrow.collidepoint_pixel(pos): #3 もし、変数arrow_stateが "rotate(回転)で、矢印をくりっくしたら
arrow_state = "fly" #4 変数arrow_stateに "fly"を代入する

move_forward( )メゾットを使って
矢印を 飛ばしましょう
そして、端に触れたら 元の場所で また回転させるよ
def arrow_move():
global arrow_state, arrow_direction, boon_state, count
if arrow_state == "rotate":
arrow.angle += arrow_direction
if arrow.angle < 90 or arrow.angle > 180:
arrow_direction = -arrow_direction
elif arrow_state == "fly": #1 もし、変数arrow_stateが "fly"になったら
arrow.move_forward(20) #2 矢印を 20pxずつ動かす
if arrow.x < 0 or arrow.y < 0: #3 もし、矢印のx座標が 0未満、または、y座標が 0未満だったら
arrow.pos = 700, 500 #4 矢印の座標を (700, 500)
arrow_state = "rotate" #5 変数arrow_stateに "rotate"を代入する

変数rotate_stateに “rotate“と代入するだけで、
また、矢印は、回転し始めたね
boonが ななめに動き続ける

move_forward( ) メゾットを使って
boonを 動かしましょう

def boon_move(): #1 boonの動きをまとめる
global boon_state #2 グローバル変数:boon_state
if boon_state == "move": #3 もし、変数boon_stateが "move"なら
boon.move_forward(10) #4 10pxずつ動く
if boon.x > WIDTH-50 or boon.x < 50: #5 boonのx座標が 750px以上 または、 boonのx座標が 50px以下なら
boon.angle = 180 - boon.angle #6 boonの向きに 180-boonの向き の角度を代入する
boon.flip_y = not boon.flip_y #7 boonの上下を反転する
elif boon.y < 50 or boon.y > HEIGHT-50: #8 boonのy座標が 50px以下 または boonのy座標が 540px以上なら
boon.angle = -boon.angle #9 boonの向きに -(boonの向き)の角度を代入する
def update():
arrow_move()
boon_move() #10 boonを 動かす
ポイント1
○跳ね返りの角度
63. boon.angle = 180 – boon.angle
67. boon.angle = – boon.angle

ポイント2
64. boon.flip_y = not boon.flip_y
左右の壁に 当たって 向きを変えると boonが 逆さに見えます。
そこで、 プロパティ『flip_y 』を True・False にして 上下反転させます。


not を 使った not boon.flip_y は、
『True』⇔ 『False』の切り替えスイッチになるよ
点滅する

まず、
set_brightness()メゾットを使って
boonを点滅させる関数を 作りましょう

def boon_flash(): #1 boonの点滅を まとめる
global count, boon_state #2 グローバル変数 count, boon_state
if count < 10: #3 もし、変数countが 10未満だったら
boon.set_brightness(50 * ((-1)**count)) #4 boonの明るさを 50, -50 に する
count += 1 #5 変数countの数値を 1ずつ増やす
clock.schedule_unique(boon_flash, 0.1) #6 0.1秒後に boon_flash関数を 実行する
else: #7 それ以外(変数countが 10以上だったら
boon.set_brightness(0) #8 boonの明るさを 元に戻す
boon_state = "move" #9 変数boon_stateに "move"を 代入する
ポイント
boonの点滅は、
明るさ:50 と -50 を 0.1秒ごとに 交互に5回ずつ(合計:10回) 変えたものです。

1.変数count を 作り、明るさを変えた回数を 入れて 点滅回数を数えます
2.明るさ:「50」と 「-50」を交互にする
48. boon.set_brightness(50 * ((-1)**count))
「(-1)**count 」は、(-1)を count回数 かけます(べき乗演算子)

「1」と「-1」が 交互に なることを 利用しています

これは、便利だね!

それでは、
矢印がboonに当たった時に
boon_flash()関数を 実行させましょう
boon = VisualEffect("boon", (400, 300)) #1 ビジュアルエフェクトに変える
def draw():
screen.fill("white")
boon.draw(screen) #2 ビジュアルエフェクトが 使える
arrow.draw()

def arrow_move():
global arrow_state, arrow_direction, boon_state, count #1 グローバル変数 boon_state, count
elif arrow_state == "fly":
arrow.move_forward(20)
if arrow.x < 0 or arrow.y < 0:
arrow.pos = 700, 500
arrow_state = "rotate"
elif arrow.collide_pixel(boon) and boon_state == "move": #2 もし、boonに当たったら、そして、 変数boon_stateが "move"なら
boon_state = "hit" #3 変数boon_stateに "hit"を 代入する
count = 0 #4 変数count 初期値:0
boon_flash() #5 boon_flash()関数を 実行する

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

今回は、
矢印に当たると boonが点滅するプログラムを 作りました。
import pgzrun
from pgzhelper import *
from visual import VisualEffect
WIDTH = 800
HEIGHT = 590
boon = VisualEffect("boon", (400, 300))
arrow = Actor("arrow", (700, 500))
arrow.angle = 180
arrow_direction = -1
arrow_state = "rotate"
boon_state = "move"
boon.angle = 40
def draw():
screen.fill("white")
boon.draw(screen)
arrow.draw()
def arrow_move():
global arrow_state, arrow_direction, boon_state, count
if arrow_state == "rotate":
arrow.angle += arrow_direction
if arrow.angle < 90 or arrow.angle > 180:
arrow_direction = -arrow_direction
elif arrow_state == "fly":
arrow.move_forward(20)
if arrow.x < 0 or arrow.y < 0:
arrow.pos = 700, 500
arrow_state = "rotate"
elif arrow.collide_pixel(boon) and boon_state == "move":
boon_state = "hit"
count = 0
boon_flash()
def boon_flash():
global count, boon_state
if count < 10:
boon.set_brightness(50 * ((-1)**count))
count += 1
clock.schedule_unique(boon_flash, 0.1) #4-6 光らせる
else:
boon.set_brightness(0)
boon_state = "move"
def boon_move():
global boon_state
if boon_state == "move":
boon.move_forward(10)
if boon.x > WIDTH-50 or boon.x < 50:
boon.angle = 180 - boon.angle
boon.flip_y = not boon.flip_y
elif boon.y < 50 or boon.y > HEIGHT-50:
boon.angle = -boon.angle
def update():
arrow_move()
boon_move()
def on_mouse_down(pos):
global arrow_state
if arrow_state == "rotate" and arrow.collidepoint_pixel(pos):
arrow_state = "fly"
pgzrun.go()

キャラクターの見た目を 変えるVisualEffect( )を使って、
boonの 明るさを 変えるプログラムを作りました。


キャラクターの明るさを変えるプログラムを作る手順です。



点滅させる関数だよ
def boon_flash(): #1 boonの点滅を まとめる
global count, boon_state #2 グローバル変数 count, boon_state
if count < 10: #3 もし、変数countが 10未満だったら
boon.set_brightness(50 * ((-1)**count)) #4 boonの明るさを 50, -50 に する
count += 1 #5 変数countの数値を 1ずつ増やす
clock.schedule_unique(boon_flash, 0.1) #6 0.1秒後に boon_flash関数を 実行する
else: #7 それ以外(変数countが 10以上だったら
boon.set_brightness(0) #8 boonの明るさを 元に戻す
boon_state = "move" #9 変数boon_stateに "move"を 代入する

みんなも試してみてね
それじゃ、またね!