前回は、Processingで簡単な図形を描く方法を学びました。描きっぱなしなので静止画でしたが、本来プログラムは、さまざまな情報を入力としてインタラクティブに表情を変えることができます。
今回は簡単なインタラクションの導入として、マウスに反応させる方法を学んでいきましょう。
mousePressed()
Processingでは、マウスに反応するブロックが複数用意されています。例えば mousePressed()
は、マウスボタンを押したときに実行されるブロックです。
// 最初に1回だけ実行されるブロック
void setup() {
size(600, 600);
background(255, 255, 255);
}
// マウスボタンを押したときに実行されるブロック
void mousePressed() {
}
// (もうひとつ別のブロックも一緒に追加するが、理由は後ほど)
void draw() {
}
なぜか一緒に draw()
という名前の空のブロックが追加されていますね。理由は後ほど説明しますが、Processingではこれがないとマウスに反応できないのです。現時点では「マウスに反応させるためには draw()
ブロックも必要なんだ」程度の理解でOKです。
さて、 mousePressed()
ブロック内に文を追加して、マウスボタンが押されたときに円を描いてみましょう。
void mousePressed() {
ellipse(300, 300, 200, 200);
}
うまく実行できたでしょうか?
中央に円が表示されるだけではつまらないので、クリックした位置に円を描画するように改良してみましょう。
円を描く位置は ellipse()
内の数値で指定できましたが、どうやってカーソルの位置を円の中心にするのでしょうか?
Processingでは mouseX
, mouseY
という特別なキーワードが用意されていて、それぞれカーソルのX/Y座標として数値のように使うことができます。
void mousePressed() {
// カーソル位置を中心に円を描く
ellipse(mouseX, mouseY, 200, 200);
}
このように書けば、クリックしたときにカーソル位置を中心に円が描かれます。 mouseX
, mouseY
と書かれた場所は、そのときどきのカーソル位置に置き換わるイメージです。
マウスボタンを押すたびに mousePressed()
ブロックが実行されるので、何度もクリックすれば円がたくさん描かれます。
mouseMoved()
mouseMoved()
ブロックは、マウスカーソルが動いたときに実行されるブロックです。先ほどのコードの mousePressed
を mouseMoved
に書き換えて実行してみましょう。どのような変化があるでしょうか?
void setup() {
size(600, 600);
background(255, 255, 255);
}
void mouseMoved() {
ellipse(mouseX, mouseY, 200, 200);
}
void draw() {
}
マウスカーソルが少し動くごとに頻繁にブロックが実行され、たくさんの円が連なって描かれるようになりました。もう一息でお絵かきツールのペンにも使えそうな気がしてきます。
mouseReleased()
ここでは詳しく解説しませんが、 mousePressed()
がマウスのボタンを押したとき、 mouseReleased()
は離したときに実行されるブロックです。
mouseDragged()
mouseDragged()
ブロックはマウスをドラッグしているときに実行されるブロックです。先ほどのコードの mouseMoved()
ブロックをさらに mouseDragged()
に書き換えてみましょう。どんな変化がありましたか?
マウスのボタンを押してドラッグしたときだけ円が描かれるようになりました。
このまま塗り色とサイズを調整すれば、ペンツールとして不便なく使えるでしょうか?やってみましょう。
void setup() {
size(600, 600);
background(255, 255, 255);
}
// マウスがドラッグされたときに実行されるブロック
void mouseDragged() {
// 図形を描く前に塗りと線を設定
noStroke();
fill(0);
// カーソル位置に円を描く
ellipse(mouseX, mouseY, 5, 5);
}
void draw() {
}
描けないことはないのですが、マウスを素早く動かすと途切れてしまいますね。これを防ぐためには、円で表現するのではなく、少し前のカーソル位置から現在のカーソル位置まで線を引いてあげるのがよいでしょう。
Processingには pmouseX
, pmouseY
という便利なキーワードが用意されていて、それぞれ少し前のカーソルのX/Y座標として使うことができます。 p
は「Previous=以前の」の頭文字です。
線を引くのは line()
でした。 pmouseX
, pmouseY
, mouseX
, mouseY
を組み合わせると…。
void setup() {
size(600, 600);
background(255, 255, 255);
}
// マウスがドラッグされたときに実行されるブロック
void mouseDragged() {
// 少し前のカーソル位置から現在のカーソル位置まで線を引く
line(pmouseX, pmouseY, mouseX, mouseY);
}
void draw() {
}
途切れず描けています。ペンツールが完成しました!
ほとんどのプログラミング言語ではコード中に計算式を書くことができまして、この講義で扱うProcessingでも可能です。コンピューターは式を解釈したうえで結果を計算してくれます。
よく使う演算 | 記号 | 例 | 計算結果 |
---|---|---|---|
足し算 | + | 10 + 2 | 12 |
引き算 | - | 10 - 2 | 8 |
掛け算 | * | 10 * 2 | 20 |
割り算 | / | 10 / 2 | 5 |
割り算の余り | % | 10 % 7 | 3 |
計算の優先順序を変える括弧 ()
も使えます。これまで出てきた特別なキーワード mouseX
, mouseY
なども、数値と同様に扱えるので計算式に含めることができます。
// これ自体はまったく意味のないコードですが、
// このような込み入った計算式も問題なく使えるという例です
rect(
(mouseX + 10) * 2,
mouseY / 7,
100 + (2 * (100 - mouseX)) % 3,
(mouseX + 20) / mouseY * 0.1
);
もう少し実用的な例として、カーソル位置と少しずらしたところにもう1本線を引くスケッチを作成してみましょう。
void mouseDragged() {
// メインの線を引く
stroke(0, 0, 0);
line(pmouseX, pmouseY, mouseX, mouseY);
// Y軸方向に少しずらして、薄い線(影)を引く
stroke(0, 0, 0, 20);
line(pmouseX, pmouseY + 10, mouseX, mouseY + 10);
}
mouseY + 10
でカーソル位置のY座標に10を足すことで、Y軸方向に少しずれた位置に線を描くことができています。
文法さえ外さなければ、計算式は自由に書き換えられます。例えば掛け算に変えると、結果はどのように変化するでしょうか?
line(pmouseX, pmouseY * 1.2, mouseX, mouseY * 1.2);
余裕がある人は、いろいろ書き換えて試しながら、どうしてそのような結果が得られるのか考えてみてください。トライアル&エラーの繰り返しが上達への近道です。
これまで習得した知識を駆使して、自分だけのペンツールを作ってみましょう。とはいえ、何を作ればよいかいきなりはわからない人も多いと思いますので、アイディアのタネとなる例をいくつか紹介しておきます。
line()
や ellipse()
に指定しているXとYを入れ替えてみると、どんな模様ができるでしょうか?(→yx_pen
)
カーソル位置と、固定の位置(例えば画面端や画面中央)で線を引いてみるとどうなるでしょうか?(→fixed_pen
)
色を変える fill()
や stroke()
にも、カーソル位置 mouseX
, mouseY
を指定することができます。工夫して綺麗な色が出せないでしょうか?(→gradient_pen
)
mousePressed()
, mouseDragged()
, … )mouseX
, mouseY
で使える