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

第15章 状態を分けて小さな世界を保つ

タイトル画面、遊んでいる画面、終わった画面を一つの draw に足していくと、条件分岐が互いに影響し始めます。作品全体の状態を一つに決め、その状態に必要な処理だけを呼ぶと、今どこにいるかを追いやすくなります。

15.1 3 つの場面を一つの @scene で表す

def setup
  createCanvas(600, 360)
  @scene = :title
  @x = 0
end

def draw
  case @scene
  when :title
    draw_title
  when :playing
    update_playing
    draw_playing
  when :finished
    draw_finished
  end
end

def draw_title
  background(30, 35, 55)
  fill(255)
  textAlign(CENTER, CENTER)
  textSize(36)
  text("SPACE ではじめる", width / 2, height / 2)
end

@scene は同時に一つの値だけを持ちます。タイトルと終了画面が同時に表示される矛盾を避けられます。

この段階では@scene:titleなので、drawから呼ばれるのは、いちばん下で定義したdraw_titleだけです。そのまま実行するとタイトル画面が表示されます。まだSPACEキーは反応しませんが、エラーではありません。次の節から、残りの場面と動きを一つずつ足します。

15.2 場面ごとに描画を分ける

タイトル画面を描くdraw_titleは15.1で定義しました。次の2つのメソッドは変更部分です。15.1の長いコードのあとへ続けて足します。

def draw_playing
  background(245)
  fill(235, 90, 120)
  ellipse(@x, height / 2, 60, 60)
end

def draw_finished
  background(235, 90, 120)
  fill(255)
  textAlign(CENTER, CENTER)
  textSize(36)
  text("もう一度 SPACE", width / 2, height / 2)
end

各メソッドは、自分の場面だけを描きます。色や文字を変えるとき、別の場面へ影響しにくくなります。

濃紺の600×360のキャンバス中央に、白い文字で「SPACE ではじめる」と表示されたタイトル画面
図 15-1 title 状態では開始案内だけを描く。

図15-2と図15-3は、15.3と15.4まで追加した完成後の画面を先に示しています。この15.2の段階ではまだSPACEキーは反応しません。二つのメソッドを追加できたら、図を見て先の変化を予想し、15.3へ進みます。

薄い灰色の600×360のキャンバスで赤い円が左から右へ進んでいる実行中の画面
図 15-2 SPACEキーを押したあとのplaying状態では、位置を更新して円を描く。
赤い600×360のキャンバス中央に白い文字で「もう一度 SPACE」と表示された終了画面
図 15-3 円が画面外へ出るとfinished状態へ移り、終了案内を描く。

15.3 更新と描画を分ける理由

次のメソッドも変更部分で、15.2の2つのメソッドのあとへ足します。

def update_playing
  @x += 4
  @scene = :finished if @x > width + 30
end

update_playing は値を変え、draw_playing は現在値を画面へ描きます。この分離により、一時停止では更新だけ止め、同じ画面を描き続ける設計ができます。

必ず分けなければならない規則ではありません。小さなスケッチでは一つの draw が読みやすい場合があります。状態が増え、変更する処理と見せる処理を別々に考えたくなったときに分けます。

15.4 キーで遷移する

次のイベントメソッドも変更部分で、同じコードの末尾へ足します。

def keyPressed
  return unless key == " "

  case @scene
  when :title
    @x = 0
    @scene = :playing
  when :finished
    @x = 0
    @scene = :playing
  end
end

状態が変わることを遷移と呼びます。タイトルから実行中へ、実行中から終了へ移ります。終了から実行中へ戻るときは、@x も初期値へ戻します。

状態だけ変えて値を戻し忘れると、再開した瞬間にまた終了します。場面を切り替えるとき、その場面が必要とする値をどこで初期化するかまで考える必要があります。

15.5 デバッグ表示は作品の裏側を見せる

制作中だけ、現在の状態を左上へ表示できます。次の変更部分は drawcase が終わった直後、draw 最後の end より前へ足します。

fill(0, 160)
rect(6, 6, 210, 26)
fill(255)
textAlign(LEFT, TOP)
textSize(14)
text("scene: #{@scene}  x: #{@x}", 10, 10)

見えない状態を文字へ変えると、「キーは反応したが位置を戻していない」といった違いを見つけやすくなります。完成時に消しても、調べる道具として残してもかまいません。

この章の小さな区切り

  • 15.1だけを実行し、エラーなしでタイトル画面を表示できた
  • SPACEキーでtitleからplayingへ移れた
  • 円が画面外へ出たあとfinishedが表示され、もう一度SPACEで始められた

三つの場面を全部作らなくても、タイトルから実行中へ一度移れれば次章へ進めます。途中で分からなくなったら、15.1の動くタイトル版へ戻ります。

第4部で、作品を増やしても追える構造を作りました。第5部では、この構造を土台に音、3D、ゲームへ進みます。

参考資料