第9章 キーボードと状態の切り替え
マウスは連続した位置を渡します。キーボードは、押されたキーに応じて「夜へ変える」「動きを止める」「色を選ぶ」といった切り替えに向いています。ここではキー入力を、作品の状態を変える合図として使います。
9.1 矢印キーで位置を変える
keyIsDown(キー・イズ・ダウン)を使うと、指定したキーが現在押されているかを調べられます。
def setup
createCanvas(500, 320)
@x = width / 2
@y = height / 2
end
def draw
@x -= 3 if keyIsDown(LEFT_ARROW)
@x += 3 if keyIsDown(RIGHT_ARROW)
@y -= 3 if keyIsDown(UP_ARROW)
@y += 3 if keyIsDown(DOWN_ARROW)
background(245)
fill(235, 90, 120)
ellipse(@x, @y, 60, 60)
end
if を行末へ置く書き方は、Ruby の後置 if です。条件が短く、実行する処理も 1 行なら、動きの対応が見やすくなります。複雑な条件では通常の複数行の if のほうが読みやすくなります。
9.2 押している状態と押した瞬間
移動では、押している間ずっと位置を変えたいので keyIsDown が合います。一度だけ色を切り替える処理を毎フレーム実行すると、押している短い間に何度も切り替わることがあります。
rbCanvas/p5 では、キーが押されたときに呼ばれるイベントメソッドを定義できます。
def setup
createCanvas(500, 320)
@dark = false
end
def draw
if @dark
background(20, 25, 40)
fill(255, 220, 120)
else
background(240, 230, 200)
fill(235, 90, 120)
end
ellipse(width / 2, height / 2, 100, 100)
end
def keyPressed
@dark = !@dark if key == " "
end
実行結果のキャンバスを一度クリックしてから、スペースキーを押します。押すたびに、明るい背景と暗い背景が切り替わります。@dark は「今は暗い場面か」を覚えており、false なら明るい場面、true なら暗い場面です。! はこの二つの値を入れ替えます。
key(キー)は押されたキーに対応する文字を返します。" " のように文字を半角の "(ダブルクォート)で囲んだものを文字列(もじれつ)と呼びます。ここでは、二つの " の間に半角スペースが一つ入っています。key == " " は「押されたのはスペースキーか」を比べています。エラーになったら、keyPressed の中の行を上のコードへ戻し、スペースと左右の " が残っているか確かめます。
keyPressed(キー・プレスド)は、キーを押したときに呼ばれるメソッドです。0.5.1 ではkey_pressedという書き方でも呼ばれますが、本書では公式 API 一覧に合わせてkeyPressedに統一します。途中のPは大文字です。
9.3 状態は画面の現在を説明する
@dark は背景色そのものを保存していません。「今は暗い場面か」という意味を保存しています。描画側は、その状態から背景色と円の色を決めます。
色を直接何度も書き換える方法もあります。しかし要素が増えると、背景は夜なのに太陽だけ昼の色という、ちぐはぐな状態が起こりやすくなります。状態を一つ持ち、すべての描画をその状態から決めると関係を保てます。
9.4 3 つ以上ならシンボルで名前を付ける
昼と夜の 2 状態は真偽値で表せます。朝、昼、夜の 3 状態になると、true と false では足りません。Ruby のシンボルで名前を付けます。シンボルは :morning のように、名前の先頭へ半角の :(コロン)を付けた値です。ここでは場面を区別する名前として使います。
def setup
createCanvas(500, 320)
@scene = :morning
end
def draw
case @scene
when :morning
background(250, 180, 150)
fill(255, 235, 190)
when :day
background(120, 200, 250)
fill(255, 220, 80)
when :night
background(20, 25, 50)
fill(255, 220, 120)
end
ellipse(width / 2, height / 2, 100, 100)
end
def keyPressed
@scene = :morning if key == "1"
@scene = :day if key == "2"
@scene = :night if key == "3"
end
case(ケース)は、@scene の値に合う when だけを実行します。背景と円の色を同じ状態から決めているため、「夜の背景なのに昼の円」というずれが起こりません。実行したら、数字の 1、2、3 を順に押して画面の変化を確かめます。
状態へ名前を付けると、morning、day、night のどの場面を描いているか、コードから読み取れます。
図 9-1 と図 9-2 を見比べると、円の位置と大きさは同じまま、状態から選ぶ色だけが変わっています。
9.5 キーで世界の季節を変える
状態は背景色だけでなく、同じ風景の読み方をまとめて変えられます。1 を春、2 を夏、3 を夜として、背景、地面、空に浮かぶものを場面ごとに選びます。
- 春では小さなピンクの楕円を散らす
- 夏では黄色い円と濃い影を置く
- 夜では月と窓の明かりだけを残す
最初は図形の位置を共通にし、色だけを切り替えます。その後、一つの場面にだけ図形を足すと、同じ場所の時間や天候が変わったように見せられます。
昼と夜のどちらを最初の場面にするか決めて保存します。次章では、文字も画面を構成する形として動かします。
参考資料
- rbCanvas/p5 0.5.1 API リファレンス —
keyIsDown、keyPressed、矢印キー定数の説明 - Ruby 公式「リテラル」 —
:morningなどのシンボル