Processingで学ぶ 実践的プログラミング専門課程

第2回 動く絵を描く,あるいはマウスやキーボードに反応するプログラムを書く

この記事を読むのに必要な時間:およそ 4 分

導入

Processingはインタラクティブなソフトウェア作品を手軽に作ることができます。ユーザの働きかけに応じて様子の変化するソフトウェアは楽しいものです。あるいはユーザは何もせず,ソフトウェアの様子が刻々と変化するのを眺めているのも,心癒されるものです。せっかくアニメーションの得意なProcessingを使うのですから,今回はそんな「動く」sketchを作ってみましょう。

ここではProcessingでアニメーションを作る方法とその仕組み,そしてキーボードやマウスに反応する仕組みを学びます。

展開

アニメーションの仕掛け,draw()メソッド

アニメーションの仕掛けは次の通りです。

sketchの中にdraw()メソッドがある場合,Processingのシステムによって,draw()メソッドがとても短い一定時間ごとに繰り返し呼び出されます。ディスプレイウィンドウに表示したい図形の命令を,draw()メソッドの中に書き並べておけば,その図形が画面に描き込まれ続けます。

draw()メソッドは人間にとって大変な早さで繰り返し呼び出されますから,少しずつ違う図形を画面に描けば,人間の目にはなめらかに動いているように見せることができます。

アニメーションの滑らかさの単位,fps

アニメーションを滑らかにするか,ストップモーションのようにするかはdraw()メソッドを呼び出す時間の間隔,すなわち画面更新の速さで決まります。この画面更新の速さを表すのがフレームレート(frame rate)です。特に指定しなければ画面の更新は1秒間に60回行われます。60回/sと表現することもできますが,慣習として60fpsと表現します。

fpsは"Frame Par Seconds"の頭文字を取っています。Frameは,コンピュータによって描きかえられる画面1枚を表す言葉です。

変更が必要ならば,フレームレートはsetup()関数内で設定変更すると良いでしょう。

sketch実行の準備に使うsetup()メソッド

setup()メソッドは,sketchが実行されると最初に1度だけ呼び出されるメソッドです。このメソッドの中で,これから実行するsketchに必要な準備をするコードを書きます。

例えば,setup()メソッドに次のように書くと,フレームレートは30fpsになります。sketchの実行途中でフレームレートを変更したい場合には,その他のメソッドの中で変更しても結構です。

フレームレートを30fpsに変更するコード

void setup(){
  frameRate(30);
}

[作業] Processingとともにインストールされているサンプルコードの中からParticles.pdeを選択します。メニューバーから,Demos > Graphics > Particles.pdeと選択してください。このコードのsetup()メソッドの中にframeRate(3)と記入し実行してみましょう。記入する前と動作の変化を観察しましょう。さらにフレームレートを2や1に変更して試してください。

アニメーションの例

ソフトウェアがひとりで動き続けるアニメーションの例を紹介します。これはProcessingに付属のサンプルBounce.pdeです。白い丸がディスプレイウィンドウの中をゆっくり動き,壁にぶつかると動く方向を変えます。このsketchは,前項で解説したアニメーションの仕組みで動きます。

setup()メソッドでディスプレイウィンドウの設定と丸のスタート地点を設定しています。draw()メソッドで背景と丸を描いています。丸の位置はdraw()メソッド実行の度に再計算しています

Bounce.pdeのソースコード

/**
 * Bounce. 
 * 
 * When the shape hits the edge of the window, it reverses its direction. 
 */
 
int rad = 60;        // Width of the shape
float xpos, ypos;    // Starting position of shape    

float xspeed = 2.8;  // Speed of the shape
float yspeed = 2.2;  // Speed of the shape

int xdirection = 1;  // Left or Right
int ydirection = 1;  // Top to Bottom


void setup() 
{
  size(640, 360);
  noStroke();
  frameRate(30);
  ellipseMode(RADIUS);
  // Set the starting position of the shape
  xpos = width/2;
  ypos = height/2;
}

void draw() 
{
  background(102);
  
  // Update the position of the shape
  xpos = xpos + ( xspeed * xdirection );
  ypos = ypos + ( yspeed * ydirection );
  
  // Test to see if the shape exceeds the boundaries of the screen
  // If it does, reverse its direction by multiplying by -1
  if (xpos > width-rad || xpos < rad) {
    xdirection *= -1;
  }
  if (ypos > height-rad || ypos < rad) {
    ydirection *= -1;
  }

  // Draw the shape
  ellipse(xpos, ypos, rad, rad);
}

このsketchを実行すると,次のスクリーンショット(図2.1)のようになります。

図2.1 Bounce.pdeの実行結果

画像

[作業] sketchを変更して,丸の動く速度を変更してください。サンプルコードよりも速い場合と遅い場合,2つ試しましょう。

マウスに対応する

マウス操作に応じて動作が変化するコード例を紹介します。

Getting Started with Processing(以下GSWP)のP.10にある次のコードMakeCircles.pdeを打ち込んで実行しましょう。

MakeCircles.pdeのソースコード

void setup() {
  size(480, 120);
  smooth();
}

void draw() {
  if (mousePressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 80, 80);
}

実行(RUN)ボタンをクリックし,ディスプレイウィンドウ上でマウスを動かすと,次のスクリーンショット(図2.2)のような出力が得られるでしょう。

図2.2 MakeCircles.pdeの実行結果

画像

このsketchは,ユーザがディスプレイウィンドウの上にマウスカーソルを持っていくと次々と丸が表示されます。マウスボタンを押さえると,押さえている間だけ丸の色が変わります。

draw()メソッドの中のif文の構造に注目してください。⁠もし,マウスボタンが押されていたら,明るさ0(黒))塗りつぶし。そうでなければ,明るさ最大の255(白)で塗りつぶし」と書かれています。

[作業] 丸の色が,マウスボタンをおさえていない時は白,おさえている時は赤になるようにsketchを変更してください。

キーボードに対応する

次のsketchを実行すると,hキーを押すとHが,nキーを押すとNがディスプレイウィンドウに表示されます。

システム変数keyPressedは,キーボードのキーが押されているときに値trueをとります。押されていなければfalseをとります。

システム変数keyには,その時点で押されているキーの文字が入ります。

システム変数とは,プログラマが特に宣言しなくても使える変数です。Processingが状況に応じた値をセットしますので,プログラマはそれを上手に利用するのです。

Example05-20.pdeのソースコード

// Example 05-20 from "Getting Started with Processing" 
// by Reas & Fry. O'Reilly / Make 2010

void setup() {
  size(120, 120);
  smooth();
}

void draw() {
  background(204);
  if (keyPressed) {
    if ((key == 'h') || (key == 'H')) {
      line(30, 60, 90, 60);
    }
    if ((key == 'n') || (key == 'N')) {
      line(30, 20, 90, 100);
    }
  }
  line(30, 20, 30, 100);
  line(90, 20, 90, 100);
}

[作業] o(オー)キーを押した時にOが表示されるようにsketchを変更しましょう。

演習

演習1(難易度:easy)

MakeCircles.pdeを変更して,マウスボタンを押さえている間は赤い丸を描き,マウスボタンを押さえていない時にはなにも描かないようにしてください(図2.3)⁠ファイル名はMakeRedCircles.pdeとしてください。

図2.3 MakeRedCircles.pdeの実行結果

画像

演習2(難易度:easy)

Bounce.pdeを変更して,マウスボタンをクリックすると丸の色が変わるようにしてください。色はランダムに変わるようにしてください。乱数はrandomメソッドで取得します。randomメソッドについて調査し利用してください(図2.4)⁠ファイル名はColorChangeBounce.pdeとしてください。

図2.4 ColorChangeBounce.pdeの実行結果

画像

演習3(難易度:middle)

ディスプレイウィンドウの大きさは幅600ピクセル,高さ400ピクセルにし,直径30ピクセルの白い円Aと直径100ピクセルの円Bを飛び回らせてください。円A, Bは壁にぶつかると跳ね返るようにしてください。 円Aと円Bが衝突したら円Bが跳ね返り,円Bは移動方向を変えるようにしてください。 円Aと円Bが衝突したら互いに跳ね返り,移動方向を変えるようにしてください。衝突時にAは色をランダムに変えます。マウスをクリックすると,円Bの色がランダムに変わるようにしましょう(図2.5)⁠sketchのファイル名はColorChangeBounceAndCollision.pdeにしてください。

図2.5 ColorChangeBounceAndCollision.pdeの実行結果

画像

まとめ

  • Processingのsketchが連続的に動くしくみを学習しました。
  • マウスとキーボードからの入力を取り扱う方法を学習しました。

学習の確認

それぞれの項目で,Aを選択できなければ,本文や演習にもう一度取り組みましょう。

  1. Processingのsketchを連続的に動かすしくみが理解できましたか?
    1. 理解できた。自分でコードを書くこともできる。
    2. 理解できた。しかし,自分でコードを書くことはできない。
    3. 理解できない。
  2. Processingのsketchでマウスやキーボードを利用する方法がわかりましたか?
    1. わかった。自分でコードを書くこともできる。
    2. わかった。しかし,自分でコードを書くことはできない。
    3. わからない。
  3. setup()メソッドとdraw()メソッドの働きを説明できますか?
    1. 説明できる。
    2. なんとなく分かったが,言葉にできない。
    3. 本文を理解できなかった。

参考文献

  • 『Getting Started with Processing』⁠Casey Reas, Ben Fry著)⁠

演習解答

  1. MakeRedCircles.pde
  2. ColorChangeBounce.pde
  3. ColorChangeBounceAndCollision.pde

著者プロフィール

平田敦(ひらたあつし)

地方都市の公立工業高等学校教諭。趣味はプログラミングと日本の端っこ踏破旅行。やがては結城浩氏のような仕事をしたいと妄想している。

Twitter : @hirata_atsushi

コメント

  • 演習3の出題ミス ご指摘ありがとうございました。

    秋元悠史 さん 記事の誤りを指摘くださりありがとうございました。ご指摘の通り、問題文と解答例に齟齬があります。検討した結果、以下のように演習問題の問題文を変更いたします。

    元の問題文
    <ここから>
    演習3(難易度:middle)
    ディスプレイウィンドウの大きさは幅600ピクセル,高さ400ピクセルにし,直径30ピクセルの白い円Aと直径100ピクセルの円Bを飛び回らせてください。円A,Bは壁にぶつかると跳ね返るようにしてください。円Aと円Bが衝突したら円Bが跳ね返り,円Bは移動方向を変えるようにしてください。衝突時にAは色をランダムに変えます。マウスをクリックすると,円Bの色がランダムに変わるようにしましょう(図2.5)。sketchのファイル名はColorChangeBounceAndCollision.pdeにしてください。
    <ここまで>

    修正した問題文
    <ここから>
    演習3(難易度:middle)
    ディスプレイウィンドウの大きさは幅600ピクセル,高さ400ピクセルにし,直径30ピクセルの白い円Aと直径100ピクセルの円Bを飛び回らせてください。円A,Bは壁にぶつかると跳ね返るようにしてください。円Aと円Bが衝突したら互いに跳ね返り,移動方向を変えるようにしてください。衝突時にAは色をランダムに変えます。マウスをクリックすると,円Bの色がランダムに変わるようにしましょう(図2.5)。sketchのファイル名はColorChangeBounceAndCollision.pdeにしてください。
    <ここまで>

    変更部分比較
    旧:円Aと円Bが衝突したら円Bが跳ね返り,円Bは移動方向を変えるようにしてください。
    新:円Aと円Bが衝突したら互いに跳ね返り,移動方向を変えるようにしてください。

    問題文を生かし、解答例を変更する場合、進行方向を変更しない円Aの処理に困ります。問題文を変更し、両方の円が進行方向を変えるほうが、解答が単純になりますので、そのようにしたいと考えました。

    記事をお読みいただき、演習にまで取り組んでいただけたことありがとうございました。お返事が遅くなりましたこと、お詫びいたします。近日中に本文を訂正させていただきます。

    Commented : #2  平田 敦 (2015/12/09, 21:26)

  • 演習3(難易度:middle)の出題ミスについて

    演習3の出題と模範解答の仕様が異なります。
    具体的には、演習では「円Aと円Bが衝突したら円Bが跳ね返り,円Bは移動方向を変えるようにしてください。」とありますが、模範解答では円A、円Bともに移動方向を変える仕様となっております。

    Commented : #1  秋元悠史 (2015/11/30, 19:30)

コメントの記入