Processingで独自の関数(ユーザー定義関数)を作る



Processingでデザインやアートを生成していく中でellpseやrect、lineといった関数はProcessingが用意したのもなので、関数にパラメータを入れるだけで図形や線が描けましたが、これとは別に独自の関数(ユーザー定義関数)を作ることができます。

独自の関数(ユーザー定義関数)は関数として処理をまとめておいて、あとで必要な時に関数を使ってその処理を利用するといった感じです。いままで使ってきたProcessingの関数もそうだったでしょう。
複雑なプログラムや何行かにわたり作成したキャラクターやアート、デザインをプログラムコードの中で何度も描くことがある場合は、関数として処理をまとめておいたほうが便利です。

まずは、関数を作成する際の基本の構文はこちら。

戻り値の型 関数名(引数の型 引数名, 引数の型 引数名, ...) {
  処理の内容
  return 返す値; //戻り値がある場合
}


戻り値がない場合は「void」、戻り値がある場合は戻り値のデータ型(intfloatなど)を記述します。
引数は関数に渡す値です。値のデータ型とその名前を記述します。
複数ある場合はカンマ区切りで記述します。
戻り値がある場合は「return」で値を返すようにします。


プログラムは上から読んでいきますが、draw()内で関数が呼び出されたらその関数が記述されている所までいき、関数の処理を実行してまた戻ります。

実際にサンプルコードで見ていきましょう。

戻り値がある関数


ただただ掛け算をする関数を作ってみました。

void setup() {
  size(300, 300);
  background(255);
  noLoop();
}
 
void draw() {
  int product = multiplication(5, 8);
  println(product);
}
 
int multiplication(int a, int b) {
  return a * b;
}



multiplication(掛け算)という関数を作成。
扱うデータ型はintで引数もintとして、2つの引数(int型でa, b)を渡して掛け算の関数でaとbを掛けて、その答えをreturnで返します。
multiplication(5, 8)で掛け算した答えをproduct(積)の変数に格納。プログラムが正しいか確認するためprintlnでエディタ下のコンソールに変数productの値を表示させて確認します。
5×8なので40とコンソールに表示されます。

続いては戻り値がなく、関数の処理だけ実行する関数を作ってみます。

戻り値がない関数


ちょっと遊びで皆さんご存知のドラクエの定番モンスターを描いてみました。

Processingで描くスライム

void setup() {
  size(800, 600);
  background(#ffffff);
  smooth();
  noLoop();
}
 
void draw() {
  slime(150, 110);
  slime(180, 300);
}
 
void slime(int x, int y) {
   
  pushMatrix(); //座標を保存
  translate(x, y); //渡された数値で座標を移動
  noStroke();
  fill(#3c8af7);
   
  beginShape();
  vertex(0, 0);
  bezierVertex(-10, 45, -50, 48, -50, 48);
  bezierVertex(-50, 48, -100, 55, -100, 110);
  bezierVertex(-100, 110, -100, 165, 0, 165);
  bezierVertex(0, 165, 100, 165, 100, 110);
  bezierVertex(100, 110, 100, 50, 50, 48);
  bezierVertex(50, 48, 10, 48, 0, 0);
  endShape();
   
  //左目
  fill(255);
  ellipse(-30, 90, 36, 36);
  fill(0);
  ellipse(-30, 90, 20, 20);
   
  //右目
  fill(255);
  ellipse(30, 90, 36, 36);
  fill(0);
  ellipse(30, 90, 20, 20);
   
  //口
  strokeWeight(10);
  stroke(#ff0000);
  noFill();
  bezier(-40, 125, -30, 140, 30, 140, 40, 125);
   
  popMatrix(); //元の座標に戻す
   
}



slime関数の引数の値はスライムを描き始める座標とします。
わかりやすくint型でx,yの2つの引数を設定しておき外部からx座標とy座標の値を渡すようにします。
slime関数の中のtranslate(x, y)の部分で渡された値が入り、座標を移動させてスライムを描いていきます。
pushMatrix()を使い、translateで移動させる前の座標(デフォルトなので 0, 0 の座標)を保存しておき、最後にpopMatrix()で元の座標に戻せば次に描くスライムが 0, 0 の座標からわかりやすく指定できるようになります。
スライム自体はbezier()bezierVertex()でベジェ曲線を描いて表現しています。

スライムを描く関数は作成しましたので、あとはdraw()の部分でslime関数を使い引数にx座標とy座標を入れてどんどん描いていくことができます。

複数行で描かなくても、たった1行で関数を呼び出してあげるだけとなります。

実行結果がこちら。

Processingで描くスライム



複雑なプログラムや複数行あるコードを何度も書かないといけないことがある場合は関数を作って処理をまとめておけば、後に描きたいことが少しのコードですんだり値を変えて編集などをする際も手間がかかることがなくなります。

皆さんも遊びで独自の関数(ユーザー定義関数)を作ってみてください。