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 コピーした顔が教える整理の時期

第6章の発展例に出てきた draw_circles も、自分で作ったメソッドでした。この章では、引数と戻り値を一つずつ確かめます。次のコードでは、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

x と y は引数です。呼び出す側から値を受け取ります。顔の描き方は 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 へ位置や大きさを渡すと、共通する描き方を保ったまま複数の案を早く比べられます。

三つの顔の間隔か大きさを一つ変え、残したい並びを保存します。動かないときは、12.1 の完成コードへ戻し、変更前の状態から試し直せます。

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

参考資料