Processing入門-専門書をもとに分かりやすく解説します。

icatch

こんにちは、サブローです。

Processingというプログラミング言語があるということは知っているけれど、実際にどのような言語なのか知らない人は多いのではないでしょうか。

この記事では「Processingをはじめよう 第2版」をもとに、Processingの入門となる基礎的な内容について、記事としてまとめます。

記事の構成は最初に、Processingを使ってできることについて解説し、その後、Processingの基礎について解説します。

この記事を読み終えることによって、Processingの基礎的な内容について理解できるようになります。

Processingとは

Processingは、Javaをベースとしたプログラミング言語で、グラフィックスやアニメーションの表現に特化した言語です。

Processingの登場によって、本来、Javaでは手間のかかる表現であったグラフィックスやアニメーションをより簡単に表現できるようになりました。

Processingの作品例。

processing-ex

また、「Processingをはじめよう 第2版」では、Processingの利点として、プログラミングを学ぶにあたって視覚的な表現を使って学べる、ということが挙げられています。

プログラミングを勉強したことのある方は分かるかと思いますが、どの言語においても、まずは理論や構造であったりと、基本的に文字ばかりで楽しくないんですよね。

最初の理論や構造の時点でプログラミングの勉強をやめてしまう人も少なくありません。

しかし、Processingではそのようなことはありません。

実行結果で即座に視覚的なフィードバックを得られるので、プログラミングの学習意欲を削がれることなく、むしろ、学習意欲を駆り立てられながら学べます。

Processingの開発環境

開発環境の構築方法ですが、まずは、Processing公式サイトへアクセスしましょう。

Downloadから自身のOSにあったインストーラーをダウンロードします。

今回は、執筆時点で最新の「4.0 beta 1」を使用します。

Windowsであれば解凍して実行ファイル(.exe)をダブルクリック、Macであればマウントしてアプリケーションフォルダにドラッグアンドドロップで開発環境が整います。

続いて、起動画面です。

gazou1

真ん中のエリアがプログラムを書くエリア、再生ボタンが実行、停止ボタンがプログラムの停止、下のエリアがコンソールです。

Processingでは実行結果をコンソールに表示するのではなく、別ウィンドウで視覚的に表示する場合がほとんどです。

コンソールはエラーの内容を確認するときくらいしか使いません。

Processingプログラミングによる図形の描画

この章では、Processingによるプログラミングの第一歩で重要な要素である、図形の描画について解説します。

図形の種類

図形の種類を解説するために、とりあえず、図形を表示させてみましょう。

size(200, 200);
ellipse(10, 10, 20, 20);

と書いて実行すると、別ウィンドウに円が描画されます。

size()関数は別ウィンドウの幅と高さを指定する関数で、ellipse()関数はウィンドウ上に円を描画するための関数です。

したがって、上のプログラムは、200×200のウィンドウ上に、中心点を(10, 10)として、幅20、高さ20の円を描画させる、というプログラムです。

ここで、Processingで用いる座標系についての説明ですが、次の図をご覧ください。

zahyoukei

Processingでは、右をxの正方向、下をyの正方向とします。

数学で用いる座標系とはyの方向が違うので注意が必要です。

では、図形を描画するための関数をまとめて解説します。

point(x, y);

点を描画するための関数。(x, y)に点を描画する。

line(x1, y1, x2, y2);

線を描画するための関数。(x1, y1)を始点、(x2, y2)を終点とする線を描画する。

rect(x, y, width, height);

四角形を描画するための関数。(x, y)の点を左上とし、幅width、高さheightの四角形を描画する。

triangle(x1, y1, x2, y2, x3, y3);

三角形を描画するための関数。(x1, y1)、(x2, y2)、(x3, y3)の3点を頂点とした三角形を描画する。

ellipse(x, y, width, height);

円を描画するための関数。(x, y)を中心点として、幅width、高さheightの円を描画する。

quad(x1, y1, x2, y2, x3, y3, x4, y4);

四角形を描画するための関数。rect関数とは違い、4つの頂点を指定することで四角形を描画する。

arc(x, y, width, height, radian1, radian2);

円弧を描画するための関数。(x, y)を中心点として、幅width、高さheightの円の円弧をradian1からredian2までの角度で描画する。

図形の重なり

Processingでは2つ以上の図形が描画され、図形同士に重なりがあった場合、後に書かれた図形が上に重なります。

size(800, 600);
ellipse(200, 200, 300, 300);
rect(150, 150, 300, 100);

とすると、

processing2

となり、後に描画された四角形が上に重なっています。

図形の塗りと境界線の色

図形の色に関する関数は、

  • background()
  • fill()
  • stroke()

の3つがあり、値を1つだけ与えるとグレースケール、(R, G, B)の形式で設定するとRGB表示となります。

また、それぞれの値は、0〜255までの値を指定でき、fill()とstroke()については4つめにアルファ値を設定できます。

POINT

アルファ値とは透明度のことで、0が透明、255が不透明となり、アルファ値を省略した場合は、デフォルトで255となります。

size(800, 600);
background(255);
stroke(0);
fill(200, 0, 0);
ellipse(200, 200, 200, 200);
fill(0, 200, 0);
ellipse(350, 200, 200, 200);
fill(0, 0, 200);
ellipse(275, 325, 200, 200);

とすると、

processing3

となり、ここに透明度を加えて、

size(800, 600);
background(255);
stroke(0);
fill(200, 0, 0,100);
ellipse(200, 200, 200, 200);
fill(0, 200, 0,100);
ellipse(350, 200, 200, 200);
fill(0, 0, 200,100);
ellipse(275, 325, 200, 200);

とすると、

processing4

となり、透明度のある図形が描画されました。

塗りをなしにしたい場合、もしくは、境界線をなしにしたい場合は、

noFill(); //塗りなし
noStroke(); //境界線なし

とします。

Processingの変数と演算子、制御構文

この章では、Processingの変数、演算子、制御構文について解説してきます。

POINT

ProcessingはJavaベースの言語なので、Javaの変数、演算子、制御構造とほぼ同じです。

変数とデータ型

変数はデータを入れておく箱のようなイメージです。

変数に名前を付けて値を管理することで、不要な同じ値の繰り返しを避け、コードを読みやすくしたり、コードを改変しやすくする、といった狙いがあります。

2つ以上同じ値のある場合は、変数を使うようにした方が無難です。

Processingでは、

int x;
x = 1;

の形式で変数を宣言および代入をし、また、

int x = 1;

といった形で変数の宣言と代入を同時に行えます。

上の例では、int型の変数を定義したので、変数xに代入できる値は整数のみとなります。

宣言とは違うデータ型の値を代入した場合、例えば、

int x = 1.5;

とした場合はエラーとなります。

また、同じ変数名を2度使ったり、システムで予約されている変数名を使うことはできません。

int x;
int x = 1;

とした場合は、同じ変数を2度作ろうとしたためエラーとなります。

Processingにおける基本のデータ型を次の表にまとめます。

データ型
boolean 真偽値(true or false)
byte 8bitの整数 -128〜127
char 16bitのユニコード文字
color 32bitの値でProcessing独自変数。色を扱うために使う。
double 64bitの浮動小数点。floatより多くの値を扱える。
float 32bitの浮動小数点数。
int 32bitの整数 -2,147,483,648〜2,147,483,647
long 64bitの整数 intより多くの整数を扱える。

全てのデータ型を確認したい場合は、Processing公式リファレンスをチェックしてください。

Processing特有の特殊な変数

Processingは実行中のプログラムの状態を表す特殊な変数を持っています。

widthとheightです。

POINT

図形を描画する関数の一般的な式の幅と高さでできているwidthとheightとは別ものです。

widthとheightは、set()関数を実行した時にセットされ、ウィンドウの幅と高さを記憶しています。

widthとheightを使うことで、ウィンドウからの相対的な位置を用いた描画が可能となります。

size(800, 200);
line(0, 0, width, height);
line(0, height, width, 0);
ellipse(width/2, height/2, 30, 30);

とすると、

processing5

となり、中心や角を簡単に指定できます。

演算子

次はProcessingの演算子についてみていきましょう。

+ 足す(加算)
引く(減算)
* かける(乗算)
/ 割る(除算)
% 余り(剰余)

また、

i++; // i = i + 1; と同じ意味
i--; // i = i - 1; と同じ意味
i += 10; // i = i + 10; と同じ意味
i -= 10; // i = i - 10; と同じ意味

といった演算子もあるので、覚えておきましょう。

比較演算子も次の表にまとめます。

< 最初の値が次の値より小さい場合にtrueを返す
> 最初の値が次の値より大きい場合にtrueを返す
<= 最初の値が次の値以下の場合にtrueを返す
>= 最初の値が次の値以上の場合にtrueを返す
== 最初の値が次の値と等しい場合にtrueを返す
!= 最初の値が次の値と等しくない場合にtrueを返す

制御構文

制御構文とは、プログラムの上から下への流れを制御するための構文で、条件分岐と繰り返しがあります。

POINT

制御構文は、コードを簡略化できたり、より複雑な処理をさせることができるので、プログラミングに当たっての必修事項です。

構文の規則さえ覚えてしまえば難しくはないので、さっそくやっていきましょう。

まずは、for文です。

for文を説明するに当たって、次のような例をみてみましょう。

size(700,150);
strokeWeight(8); // 線の太さを設定するための関数
line(20, 20, 100, 100);
line(80, 20, 160, 100);
line(140, 20, 220, 100);
line(200, 20, 280, 100);
line(260, 20, 340, 100);
line(320, 20, 400, 100);
line(380, 20, 460, 100);
line(440, 20, 520, 100);
line(500, 20, 580, 100);
line(560, 20, 640, 100);

平行な線を10本描画するプログラムですが、実行結果はこんな感じ。

processing6

プログラムをみてみると、xの値が60ずつ増えていますね。

このように特定の決まった値の変化による繰り返し場合、for文で容易に書くことができます。

書式は、

for(初期化; 条件; 値の更新){
    処理
}

です。

実際に上のプログラムを書き換えてみると、

size(700, 150);
strokeWeight(8);
for(int i = 20; i <= 560; i += 60){
    line(i, 20, i + 80, 100);
}

となり、同じ実行結果を得られます。

単純に繰り返しの回数だけを指定する場合は、

for(i = 0; i < 10; i++){
}

のように書き、for文の中の処理が0回目から9回目まで、つまり、10回実行されます。

次に、条件分岐について解説します。

条件分岐のための構文をif文といい、書式は、

if(条件){
    処理
}

となっています。

if文では、条件がtrueの場合に処理が行われ、条件に合わない場合は、処理をスルーします。

if文を使うことで、特定の値はこの処理でとか、別の値はこっちの処理でといったように値によって処理を分けることができます。

またif文は、elseとともに次のように書けます。

if(条件1){
    処理1
}
else if(条件2){
    処理2
}
else{
    処理3
}

elseは、必ずifと同時に使われ、直訳すると「さもなければ」という意味です。

条件1さもなければ条件2といったように、条件1に合わなかった場合には条件2の判定が行われ、条件2に該当すれば処理2が、どの条件にもそぐわない場合には処理3が実行されます。

また、if文の条件には比較演算子の他、論理演算子が使われる場合が多々ありますので、論理演算子についても解説をします。

&& かつ
|| または
! ではない

表の演算子を論理演算子と呼び、例えば

if((a == b) && (c == d)){} // 2つの項がどちらもtrueの場合true
if((a == b) || (c == d)){} // 2つの項のうちどちらかtrueの場合true
if(!(a == b)){} // a == bがtrueの場合false、a == bがfalseの場合true

という使い方をします。

Processing特有の関数:setup()関数とdraw()関数

この章では、Processing特有の関数であるsetup()関数とdraw()関数について解説します。

setup()関数は、プログラムが実行された時に1度だけ呼ばれる関数で、初期設定のための関数など、コード内で1度だけでいい処理を書いておくための関数です。

次に、draw()関数についてですが、draw()関数のブロック内のコードは、プログラムが終了するまで繰り返し実行されます。

POINT

デフォルトでは、1秒間に60回の繰り返しが行われ、この周期をフレームと呼びます。

draw()関数があることによって、自身で繰り返しのための記述をする必要がないので、Processngのコードは、どちらかのブロック内に書きます。

setup()関数とdraw()関数の外で宣言された変数はグローバル変数と呼ばれ、プログラム内の全ての関数で使うことができます。

最後にProcessingがコードを処理する順番は次のようになっているので、頭に入れておくようにしましょう。

  1. setup()とdraw()の外で宣言された変数の作成
  2. setup()内のコードを1度だけ実行
  3. draw()内のコードを繰り返し実行

Processingにおけるデバイスからの入力

この章では、デバイス、つまり、マウスとキーボードの入力のProcessingでの扱いについて解説します。

マウスポインタの座標

Processingでは、プログラムが実行されている間、マウスポインタのx座標とy座標をmouseX変数、mouseY変数に保持しています。

また、pmouseX変数とpmouseY変数において、1つ前のフレームの座標を保持しています。

次のような例をみてみましょう。

void setup(){
    size(700, 150);
    strokeWeight(4);
    stroke(0, 102);
}

void draw(){
    line(mouseX, mouseY, pmouseX, pmouseY);
}

実行結果はこんな感じ。

processing7

1つ前のマウスポインタの位置と現在のマウスポインタの位置を結ぶ線が切れ目なく描画されていることが分かります。

マウスのクリック

次に、マウスのクリックについて解説します。

Processingでは、マウスのクリックを検出するために、mousePressed変数が用意されています。

mousePressed変数はブーリアン型の変数であり、trueかfalseの値を持ちます。

また、ボタンが押されている間はtrue、ボタンを離すとfalseの値を取ります。

void setup(){
    size(120, 120);
    strokeWeight(30);
}

void draw(){
    background(204);
    stroke(102);
    line(40, 0, 70, height);
    if(mousePressed){
        if(mouseButton == LEFT){
            stroke(255);
        }
        else{
            stroke(0);
        }
    line(0, 70, width, 50);
    }
}

このコードの実行結果は次のようになります。

processing8-1

processing8-2

mousePressedの値がtrueの場合に、新たな変数であるmouseButton変数の値を比較しています。

mouseButton変数は、LEFT、CENTER、RIGHTのいずれかの値をとり、それぞれがマウスのボタンに対応しています。

したがって、左クリックの場合は白い線、それ以外のボタンの場合は黒い線が描画されます。

キーボードからの入力

Processingでは、キーボードの入力を常時受け付けており、押されたキーの有無と最後に押されたキーの情報を得ることができます。

mousePressed変数と同じような変数で、キーが押されるとtrueになるkeyPressedという変数があります。

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

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);
}

実行結果です。

processing9-1

processing9-2

processing9-3

最後に押されたキーの情報を取得すためには、key変数を使います。

char型のkey変数は、最後に押されたキーの情報を保持していて、次のキーが押されるまで値は変わりません。

上のコードでは、キーが押された時にそのキーがhもしくはnの時に線を1本描画し、HかNが表示されるようになっています。

Processingプログラミングにおける座標系の変更

Processingでは、座標系を変更することによって、視覚的な動きをつけることができます。

つまり、アニメーションを描画できるようになるので、ここからもっと面白くなってきます。

座標系の移動

まずは、座標系の変更の基礎となるtranslate()関数からみていきましょう。

既に解説した通り、ウィンドウの左上の基準となる点の座標は、(0, 0)です。

この基準点を変更することによって、Processingでは動きをつけることができるようになります。

void setup(){
    size(500, 300);
}

void draw(){
    translate(mouseX, mouseY);
    rect(0, 0, 100, 100);
}

実行結果はこんな感じです。

processing10

マウスポインタを追従するように四角形が描画されました。

translate()関数は座標を指定することによって、基準点を移動させるための関数です。

このコードでは、rect()は(0, 0)を指定していますが、マウスポインタの位置に基準点が変更されているので、このように追従してくる結果となります。

座標系の回転

rotate()関数を使うことで、座標系を回転することができます。

このとき、回転の中心となるのは基準点(0, 0)となり、回転の中心は、translate()関数によって移動させることができます。

void setup(){
    size(500, 500);
}
void draw(){
    translate(100, 100);
    rotate(map(mouseX, 0, 500.0, 0, PI/2));
    rect(0, 0, 160, 20);
}

実行結果です。

processing11

map()関数は、

map(a, b, c, d, e);

と書き、aの値の範囲をb-cからd-eへ変換します。

便利な関数なので、覚えておくようにしましょう。

上のコードは、回転の中心を(100, 100)の点へ移動させ、0からπ/2までの範囲で四角形を回転させるというコードです。

座標系の伸縮

scale()関数は、座標系を伸縮させるための関数で、scale(0.5)とすると半分、scale(2)とすると2倍になります。

void setup(){
size(600, 200);
}
void draw(){
    translate(mouseX, mouseY);
    scale(mouseX / 200.0);
    rect(-15, -15, 30, 30);
}

実行結果です。

processing12

マウスポインタのxの値が大きくなるにつれて、四角形が大きく引き伸ばされています。

PushとPop

座標の変換を一部にのみ適用させ、他のコードに影響を与えないようにするために、pushMatrix()関数とpopMatrix()関数があります。

この2つは必ずセットで使われ、pushMatrix()を使うとその座標系が記録され、popMatrix()が実行されるともとの座標系が復元されます。

void setup(){
size(600, 300);
}
void draw(){
    pushMatrix();
    translate(mouseX, mouseY);
    rect(0, 0, 100, 100);
    popMatrix();
    translate(50, 50);
    rect(60, 0, 50, 50);
}

実行結果です。

processing13

pushMatrix()とpopMatrix()の外にある小さい四角形は常に同じ位置に表示されており、座標移動がキャンセルさています。

まとめ

今回は、プログラミング言語Processingの入門として、

  • Processingとは
  • Processingの開発環境
  • 図形の描画
  • 変数と演算子、制御構造
  • setup()関数とdraw()関数
  • デバイスから入力
  • 座標系の変更

といった基礎的な内容について解説しました。

Processingの基礎的な内容を理解すれば、様々なグラフィックやアニメーションを表現するための足がかりになり、もっと深めれば自由な表現を作品にできます。

冒頭でもお伝えしておりますが、もっと詳しく知りたいという方は「Processingをはじめよう 第2版」がおすすめです。

それではまた。

SNSでもご購読できます。

コメントを残す

*