【Pygame Zero】キャラクターのコスチュームを変えよう2

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


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

今回のプロジェクトには、
boonの他に ブロックが 登場します。
基礎プログラムと 画像を入れた
「見た目02 ブロック落とし」zipフォルダを ダウンロードしてください



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

学習の流れ
ブロックをクリックして 落とす
コスチュームを変えながら 左右に動く
ブロックに当たると セリフを言う
プログラムを 実行してみよう
プログラミングの仕方を説明します
モジュールを 用意する

今回の「ブロック落とし」ゲームでは、
・ ブロックを クリックする
・ boonが セリフを言う
・ boonが コスチュームを 変える
プログラムが あります
そこで、3つのモジュールを 用意しました



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

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


わぁ~!いっぱい入っているね
『 . (ドット)』を付ければ、使えるよ
ブロックをクリックすると落ちる

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


コスチュームの範囲を 決められるよ


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


ブロックを 2つの状態に 分けました

それでは、
ブロックのプログラムを 作りましょう
block_state = "ready" #1 変数block_state 初期値:"ready"
def on_mouse_down(pos): #2 クリックした座標(pos)を取得
global block_state #3 グローバル変数block_state
if block.collidepoint_pixel(pos): #4 もし、ブロックをクリックしたら
block_state = "fall" #5 変数block_stateを "fall"にする
ポイント
collidepoint_pixel(pos) メゾットで、
ブロックが クリックされたか 判定されます。

27. if block.collidepoint_pixel(pos):
if 文では、
block.collidepoint_pixel(pos) が 「1」になると 『True』になります

block_move()関数で
block_state が “fall” になったら 下に落とすよ
def block_move(): #1 ブロックの動きをまとめる
global block_state #2 グローバル変数 block_state
if block_state == "fall": #3 もし、変数block_stateが "fall"だったら
block.y += 5 #4 ブロックのy座標を 5ずつ増やす
if block.y > HEIGHT: #5 もし、ブロックのy座標が スクリーンの高さ(590)より 大きくなったら
block.y = 50 #6 ブロックのy座標を 50にする
block_state = "ready" #7 変数block_stateを "ready"にする
def update(): #8 更新する
block_move() #9 ブロックを動かす

update()関数に
block_move()関数を入れることによって ブロックが 動くからね
コスチュームを変えながら 動く

まずは、boonを左右に動かしましょう
変数boon_speed を 作って、boonの速度を入れます
初期値は「5」にして、5pxずつ動くようにします
block_state = "ready"
boon_speed = 5 #1 変数boon_speed 初期値:5
def boon_move(): #2 boonの動きをまとめる
global boon_speed #3 グローバル変数 boon_speed
boon.x += boon_speed #4 boonのx座標を 変数boon_speedずつ増やす
if boon.x > WIDTH-50 or boon.x < 50: #5 もし、boonが左右の壁に当たったら
boon_speed = -boon_speed #6 -1 × 変数boon_speed
boon.flip_x = not boon.flip_x #7 boonの左右を反転する
def update(): #8 更新する
block_move()
boon_move() #9 boonを動かす
ポイント
47. boon.flip_x = not boon.flip_x
左右の壁に当たったら
flip_x を使って boonを反転させます

not boon.flip_x は、
boon.flip_x が 「True」なら、「False」
boon.flip_x が 「False」なら、 「True」 に なるよ

次に、
animate()メゾットで boonのコスチュームを変えていくよ

3ステップで できちゃうよ!
boon.images = ["boon", "blue_boon", "pink_boon", "purple_boon", "green_boon", "water_boon", "ouch_boon"] #1 imagesに画像を入れる
boon.fps = 5 #2 1秒間に変える速さを入れる
def boon_move():
global boon_speed
boon.x += boon_speed
boon.animate() #3 コスチュームを変える

あれれ…⁉
boonが、痛い顔をしているよ


おぅぅぅ…と 忘れてた!
boonが左右に動いている時のコスチュームを
set_animation_range( )メゾットで 範囲を決めよう

def boon_move():
global boon_speed
boon.x += boon_speed
boon.set_animation_range(0, 5) #1 コスチュームの範囲:0~5
boon.animate()

おおお!できてる!
ブロックに当たると セリフを言う

最後に、
sayモジュールのtext_displayオブジェクトを使って
boonに セリフを 言わせよう

★ text_displayオブジェクトの 使い方 ★
1. text_display.draw(screen)
これで、スクリーンに セリフを 表示させることができます
2. boon.say(“Ouch!”, 2, size=70, color=”red”, y_offset= -70)
sayメゾットを使って、boonにセリフを 言わせます。


ブロックとの衝突判定は、
collide_pixel( ) メゾットを 使ったよ

def draw():
screen.fill("white")
boon.draw()
block.draw()
text_display.draw(screen) #1 テキスト表示装備を 準備する
def boon_move():
global boon_speed
boon.x += boon_speed
boon.set_animation_range(0, 5)
boon.animate()
if boon.x > WIDTH-50 or boon.x < 50:
boon_speed = -boon_speed
boon.angle = 180-boon.angle
boon.flip_y = not boon.flip_y
if boon.collide_pixel(block): #2 もし、ブロックに当たったら
boon.image = "ouch_boon" #3 コスチュームを ouch_boonにする
boon.say("Ouch!", 2, size=70, color="red", y_offset=-70) #4 boonが 「Ouch!」と2秒間言う
ポイント
53. boon.image = “ouch_boon“

ouch_boon.png
Actor()クラスの属性image に、見せたい画像を入れるだけで
boonのコスチュームが 変わります

あれれ! boonの痛い顔が すぐなくなったよ

おおおっと!
is_talking( )メゾットを使って
boonがセリフを 言っていない時に動くようにします


44~55行 4文字分のインデント(右にずらす)してね
def boon_move():
global boon_speed
if not boon.is_talking(): #1 もし、boonが話していなければ
boon.x += boon_speed #2 ここから55行まで4文字分のインデントをします
boon.set_animation_range(0, 5)
boon.animate()
if boon.x > WIDTH-50 or boon.x < 50:
boon_speed = -boon_speed
boon.angle = 180-boon.angle
boon.flip_y = not boon.flip_y
if boon.collide_pixel(block):
boon.image = "ouch_boon"
boon.say("Ouch!", 2, size=70, color="red", y_offset=-70)

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

今回は、
コスチュームを変えながら左右に動くboonを当てるゲームの
プログラムを作りました。
import pgzrun
from pgzhelper import *
from say import text_display
from costume import *
WIDTH = 800
HEIGHT = 590
boon = Actor("boon", (400, 500))
block = Actor("block", (400, 50))
block_state = "ready"
boon_speed = 5
boon.images = ["boon", "blue_boon", "pink_boon", "purple_boon", "green_boon", "water_boon", "ouch_boon"]
boon.fps = 5
def draw():
screen.fill("white")
boon.draw()
block.draw()
text_display.draw(screen)
def on_mouse_down(pos):
global block_state
if block.collidepoint_pixel(pos):
block_state = "fall"
def block_move():
global block_state
if block_state == "fall":
block.y += 5
if block.y > HEIGHT:
block.y = 50
block_state = "ready"
def boon_move():
global boon_speed
if not boon.is_talking():
boon.x += boon_speed
boon.set_animation_range(0, 5)
boon.animate()
if boon.x > WIDTH-50 or boon.x < 50:
boon_speed = -boon_speed
boon.angle = 180-boon.angle
boon.flip_y = not boon.flip_y
if boon.collide_pixel(block):
boon.image = "ouch_boon"
boon.say("Ouch!", 2, size=70, color="red", y_offset=-70)
def update():
block_move()
boon_move()
pgzrun.go()

コスチュームを次々と変えるアニメーションにする場合は、
costumeモジュールをインポートして
3つのステップで プログラムを作れます

set_animation_range( ) メゾットを使うと
使うコスチュームを 選べるよ
試してみてね!


それじゃ、またね!