【Pygame Zero】的当てゲームを作ろう!左右移動

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


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

今回のプロジェクトには、
boonの他に 青いボールが登場します。
青いボールの画像と基礎プログラムを入れた
「動き2-2 ボーンをねらえ」zipフォルダを ダウンロードしてください



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

学習の流れ
プログラミングの仕方を説明します
sayモジュールを 用意する

今回のプロジェクトでは、
boon が セリフを 言うので sayモジュールを用意しました
import pgzrun
from pgzhelper import *
from say import text_display

ボールをクリックしたら斜めに動く

今回の的当てゲームのプログラムを作る上で
大事なポイントが 2つあります

ボールが 動いている時が “play”
ゲーム中だよ


わかりやすくなるね

それでは、
ボールを クリックしたら 動くプログラムを 作ります。
変数ball
には、Actor()クラス(設計図)が 入って
ボールを動かす属性やメゾットが たくさん入っています

変数ball に、「 . (ドット)」を属性やメゾットを 使いましょう

まずは、ボールをクリックしたら
変数game が “ready” から “play” になるプログラムです。
game = "ready" #1 変数gameの最初のデータ:"ready"
ball.angle = 50 #2 ボールの向きに 50度 代入する
def draw():
screen.fill("white")
boon.draw()
ball.draw()
def on_mouse_down(pos): #3 クリックした座標を取得
global game #4 グローバル変数game
if ball.collidepoint(pos): #5 もし、ボールにクリックしたら
game = "play" #6 変数gameに "play" 代入する
ポイント1
19.on_mouse_down(pos) 関数で
クリックした場所を引数「pos」に 入れる

ポイント2
22. ball.collidepoint(pos) メゾットで、ボールのクリック判定を する


20. global game
変数game を グローバル変数にすることを 忘れないでね
“ready” から “play“に 変わるよ

つぎは、
ball_move関数にボールの動きを まとめよう

def ball_move(): #1 ボールを動かす関数
global game #2 グローバル
if game == "play": #3 もし、変数gameが "play"なら
ball.move_forward(10) #4 ボールを10pxずつ 動かす
if ball.x > WIDTH-35 or ball.x < 35: #5 もし、左右の壁に当たったら
ball.angle = 180 - ball.angle #6 跳ね返りの向きにする
if ball.y > HEIGHT-35 or ball.y < 35: #7 もし、上下の壁に当たったら
ball.angle = -ball.angle #8 跳ね返りの向きにする
ポイント
ballの画像の大きさは、70 × 70 px
35. 37. ボール左右・上下の跳ね返りの角度



ball_move関数に、ボールの動きをまとめましたが、
このままでは、動きません。
def update関数の中に 入れましょう

def update(): #1 更新する
ball_move() #2 ball_move関数
pgzrun.go()

クリックしたら ボールが 動いたね
boonを 左右に動き続ける

boonのx座標を変えて左右の動きを作ります。
boon_speed = 5 boonの動く速さ
変数boon_speed を 作ります。初期値:5
def boon_move(): #1 boonを動かす関数
global boon_speed #2 グローバル
boon.x += boon_speed #3 boonを動かす
if boon.x > WIDTH-50 or boon.x <50: #4 跳ね返る
boon_speed = -boon_speed #ステップ1 スピード反転
boon.angle = 180-boon.angle #ステップ2 向きを反転
boon.flip_y = not boon.flip_y #ステップ3 上下反
def update():
ball_move()
boon_move() #1 boon_move関数を更新する
ポイント1
boonの画像の大きさは、100 × 100 px
跳ね返り地点
45. if boon.x > WIDTH-50 or boon.x <50:

ポイント2
boon の 逆さを直す
47. boon.flip_y = not boon.flip_y True ⇔ False スイッチになる


boonも 動いたよ
ボールに当たったら セリフを言う

text_displayオブジェクトを使って
キャラクターに セリフを 言わせるよ
def draw():
screen.fill("white")
boon.draw()
ball.draw()
text_display.draw(screen) #1 画面に セリフを表示できる


これで、キャラクターにセリフを言わせる準備が できました

ボールが boonに衝突したら、セリフを言わせるよ
衝突判定は、collide_pixel( ) メゾットを使います。

def ball_move():
global game #2-2 グローバル
if game == "play": #2-3 ボールを動かす #4-4 or "hit"
ball.move_forward(10)
if ball.x > WIDTH-35 or ball.x < 35: # 2-5 跳ね返る
ball.angle = 180 - ball.angle
if ball.y > HEIGHT-35 or ball.y < 35:
ball.angle = -ball.angle
if ball.collide_pixel(boon): #2 もし、boonに衝突したら
boon.say("Ouch!", 2, size=70, color="red", y_offset=-70) #3 boonに、セリフを言わせる

セリフの位置(初期値)は、
(キャラクターのx座標, y座標-50)に しています。
x_offset, y_offsetを 記入しなければ
セリフは、この位置になります。

セリフを好きな場所へ移動させたい時に
x_offset, y_offset を使って、セリフの座標を決めてください

あれっ? boonは、セリフを言いながら動いてるよ

はい。これでもいいんだけれど、
お好みでセリフを言っている時、boonの動きを止めたい場合は
is_talking( )メゾットと使おう

def boon_move():
global boon_speed
if not boon.is_talking(): #もしboonが話していなければ
boon.x += boon_speed
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.is_talking( ):
boonが話し中「True」

if not boon.is_talking🙁 )
boonが話していないが「True」
not をつけると 「False」が 『True』に なります。


44~48.インデント(字下げ:4文字下げる)してね

これで、boonが「Ouch!」と言わない時だけ 動く。
つまり、
boonが「Ouch!」と言っている間は 動かないんだ

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

今回は、
クリックしたらボールが動き boonに衝突したら「Ouch!」と言うプログラムを作りました。
import pgzrun
from pgzhelper import *
from say import text_display
WIDTH = 800
HEIGHT = 590
boon = Actor("boon", (400, 100))
ball = Actor("blueball", (400, 500))
game = "ready"
ball.angle = 50
boon_speed = 5
def draw():
screen.fill("white")
boon.draw()
ball.draw()
text_display.draw(screen)
def on_mouse_down(pos):
global game
if ball.collidepoint(pos):
game = "play"
def ball_move():
global game
if game == "play":
ball.move_forward(10)
if ball.x > WIDTH-35 or ball.x < 35:
ball.angle = 180 - ball.angle
if ball.y > HEIGHT-35 or ball.y < 35:
ball.angle = -ball.angle
if ball.collide_pixel(boon):
boon.say("Ouch!", 2, size=70, color="red", y_offset=-70)
def boon_move():
global boon_speed
if not boon.is_talking():
boon.x += boon_speed
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
def update():
ball_move()
boon_move()
pgzrun.go()


今回は、
キャラクターごとに 動きをまとめた関数を 作りました。
プログラムが長くなっていくと、
このようにキャラクターごとにプログラムをまとめておくと
見やすく、わかりやすいです。
みなさんも 挑戦してみてください

それじゃ、またね!