Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第12章 メソッドで自分の描画命令を作る

同じ顔を 3 か所へ描こうとすると、楕円の行が何度も並びます。コピーは実験の入口として役立ちますが、あとから目の大きさを変えるとき、すべてのコピーを直す必要があります。メソッドは、繰り返した処理へ名前を付け、自分の作品専用の命令にします。

12.1 コピーした顔が教える整理の時期

最初は、メソッドとsetupを一つにした次の完成コードをそのまま実行します。次のコードでは、def draw_faceから最初のendまでが自分で作る描画命令、その後のsetupがキャンバスを用意して命令を3回使う部分です。

def draw_face(x, y)
  fill(250, 170, 80)
  ellipse(x, y, 100, 100)
  fill(30)
  ellipse(x - 20, y - 10, 12, 18)
  ellipse(x + 20, y - 10, 12, 18)
end

def setup
  createCanvas(500, 300)
  background(245)

  draw_face(120, 150)
  draw_face(250, 120)
  draw_face(390, 170)
end

xyは引数です。呼び出す側から値を受け取ります。顔の描き方は1か所にまとまり、位置だけを変えて3回使えます。顔の楕円をコピーして別々に直す方法でも試作できますが、目の大きさなどを一度に変えたくなったら、メソッドへまとめる理由が生まれます。

薄い灰色の500×300のキャンバスに、同じ描き方で作ったオレンジ色の顔が三つ、異なる位置へ並んでいる実行結果
図 12-1 同じdraw_faceメソッドへ別の座標を渡し、三つの位置へ描く。

12.2 名前は作品の語彙になる

draw_face は、rbCanvas/p5 に最初から存在する命令ではありません。自分で定義したメソッドです。作品が植物なら draw_leaf、都市なら draw_window のように、その作品の言葉をコードへ作れます。

メソッド名は短さだけで決めません。thing より draw_sleeping_eye のほうが、何を描くか伝わる場合があります。一方、1 章だけの小さな実験で長い名前を付けすぎると読みづらくなります。今の自分が戻って読める名前で十分です。

12.3 引数で違いを残す

すべて同じ顔ではなく、大きさを変えたい場合は size を受け取ります。12.1で作った draw_face 全体を、次の変更部分と置き換えます。

def draw_face(x, y, size)
  fill(250, 170, 80)
  ellipse(x, y, size, size)

  eye_width = size * 0.12
  eye_height = size * 0.18
  eye_offset = size * 0.2

  fill(30)
  ellipse(x - eye_offset, y - size * 0.1, eye_width, eye_height)
  ellipse(x + eye_offset, y - size * 0.1, eye_width, eye_height)
end

目の位置と大きさを顔全体の size から計算しています。顔が大きくなれば、目も同じ比率で大きくなります。続く3行は変更部分で、setup にある3回の draw_face 呼び出しと置き換えます。

draw_face(120, 160, 70)
draw_face(260, 140, 120)
draw_face(410, 170, 90)
薄い灰色の500×300のキャンバスに、小・大・中の三つのオレンジ色の顔が並ぶ実行結果
図 12-2 同じdraw_faceへ異なるsizeを渡すと、顔と目の比率を保ったまま大きさが変わる。

図12-1では位置だけが違い、図12-2では位置と大きさが違います。メソッドへsizeを足した効果を、三つの顔で比べられます。

12.4 戻り値で計算を分ける

描画しないメソッドも作れます。キャンバス外へ出ない x 座標を返すメソッドです。次の変更部分は、draw_face と同じく setup の外側へ置きます。

def keep_inside(value, minimum, maximum)
  return minimum if value < minimum
  return maximum if value > maximum
  value
end

Rubyでは、最後に計算・確認した値が戻り値になります。これを「最後に評価した式の値」と呼ぶことがあります。範囲内なら最後のvalue、小さすぎればminimum、大きすぎればmaximumを返します。続く2行は変更部分です。動きを見るには新しいdef drawの中へ入れ、setupにある顔の呼び出しは削除します。

safe_x = keep_inside(mouseX, 50, width - 50)
draw_face(safe_x, mouseY, 100)

描画と計算を分けると、計算だけを別の場所で再利用できます。ただし短い一度きりの式まで、すべてメソッドにする必要はありません。重複して困ったとき、名前を付けると読みやすくなるときが整理の合図です。

12.5 小作品「同じ家族、違う三人」

12.3の大きさが違う三つの顔へ、短い題名を付けます。「朝が早い三人」「遠くを見る家族」のように、画面から感じた関係を一つ選びます。その題名に合わせ、次のうち一つだけを変えます。

  • 三つの顔の間隔を、近くまたは遠くする
  • 一つだけ大きさを極端に変える
  • 全員を画面の上半分または下半分へ寄せ、余白を作る

同じdraw_faceを使うからこそ、位置や大きさの違いが見えます。整理はコードを短くするだけでなく、同じ規則から多くの案を早く比べる道具です。

この章の小さな区切り

  • draw_faceを3回呼び、三つの顔を表示できた
  • 引数の数字を一つ変え、見た目の違いを説明できた
  • いちばん気になった配置を、題名の分かるファイル名で保存した

全部できなくても、三つの顔が表示できれば第13章へ進めます。困ったら12.1の完成コードへ戻ります。

第13章では、同じメソッドをいくつもの位置データへ適用します。メソッドが「描き方」、配列が「何をいくつ持つか」を担当します。

参考資料