関数
p5.jsでは、関数が基本的な構成要素になっています。
すべてのプログラムを一から作成することは、ほとんど不可能なことであり、無駄なことです。プログラムを作成するときには、今までに作られたモノを再利用して、生産性を高めています。具体的には、p5.jsのような図形を描くプログラムを一からすべて作ることを考えて見てください。誰もやる気はしないでしょうし、できる人は本当に限られています。つまり、再利用することにより、我々も有意義なプログラムを作成可能となるのです。その再利用のための一つの重要な要素が「関数」とかその集合である「ライブラリ」です。
関数は、あるまとまった命令をまとめて記述することにより、再利用を可能にします。どこまでをまとめるかということは、なかなか難しい問題もありますが、ここでは関数の作成方法を簡単に説明します。
関数の定義
以下のコードは、関数の定義です。中身は何も無いので、何もせずに終了して、関数を呼び出したところに戻って来ます。関数の定義は、function 関数名(/引数名, ... /) { 文 ... } となります。引数は0個でも、複数個でも良いですが、関数の役割と引数の意味は、必ず文書化して、誰でも使えるようにすることが大切です。
引数は、関数の定義では、変数のように扱えます。値は関数を呼び出す側で具体的な値を設定します。設定されない場合はエラーとなります。
code:setup
function setup(){
}
function draw(){
}
関数のブロックの中には、複数の文を書きことができ、通常それらは上から順に実行されます。
setup()やdraw()は、値を返しませんが、関数は値を返すこともできます。値を返すには、return文を使います。
code:isEven.js
let rs = isEven(98);
/*
偶数かどうかを判定する関数
引数 num : 整数
戻り値:numが偶数であるときは、true、そうでなければfalse
*/
function isEven(num){
if ( num % 2 == 0 ) return true;
else return false;
}
関数の呼び出しには、isEven(3)のように、必ず値を持った引数を渡します。もし、 a = isEven()のように呼び出すと、エラーが起きたり、正しく動きませんので注意しましょう。
関数のありがたみがわかる例を挙げましょう。次のコードは、キャンバスの中心に次の図ようにモグラを描くコードです。
https://scrapbox.io/files/61f4ef1e84c32e001f501d97.jpg
code:mogura0.js
translate(width/2,height/2); // キャンバスの中心に原点を移動
/*
モグラを大きさ 60x60、 原点に描く
*/
noStroke();
fill(160,140,70);
bezier(-25,30, -25,-25, 25,-25,25,30);
// 目
fill('black');
circle(-10,10,5);
circle(10,10,5);
stroke(100)
strokeWeight(1);
line(-17,15,17,25)
line(-17,20,17,20)
line(-17,25,17,15)
fill(200,200,100);
noStroke();
circle(0,18,14);
fill(90);
circle(0,16,6);
このモグラを何個も描くために、同じコードをコピーするのは大変ですよね。それはもとより、何個作るかも決まっていなければ、どう書いていいかもわかりません。ここで、これを再利用して何度もモグラを描くには、関数にしてしまうと便利です。
code:mogura.js
function draw(){
// 3個書いてみる
mogura(50,100);
mogura(200,100);
mogura(150,200);
}
/*
(x,y) を中心として、大きさ 60x60のモグラを描く
*/
function mogura(x,y){
push();// 追加:今までの環境を変更しないため、今までの環境を保存
translate(x,y);
/*
モグラを大きさ 60x60、 原点に描く
*/
noStroke();
fill(160,140,70);
bezier(-25,30, -25,-25, 25,-25,25,30);
// 目
fill('black');
circle(-10,10,5);
circle(10,10,5);
stroke(100)
strokeWeight(1);
line(-17,15,17,25)
line(-17,20,17,20)
line(-17,25,17,15)
fill(200,200,100);
noStroke();
circle(0,18,14);
fill(90);
circle(0,16,6);
pop(); //元の環境に戻す
}
push(), pop()は、今までの描画していた環境(色、線色、線の太さなど)を一旦保存します。その後、色や線の太さなどを変更して描画し、pop()で元あった環境に戻します。その結果、今関数から呼び出し元の次に戻ったときは元と同じ環境になっていることが保証されています。