[8日目]自分で”関数”を作ってみよう!
はじめに
私たちStudy-Gazerは、あくまでも「processing」というツールを通して
読者の皆様が「プログラミングのイメージをつかむこと」や「楽しみながらプログラミングの基礎を学んでいくこと」を目的としています.
「size関数」や「draw関数」,「ellipse関数」など、
これまで様々な関数を使ってきました.
ですが、今回はそんな「関数を作る」ということについて
やっていこうと思います!
1.「関数を作る」ってどういうこと?
ここでいっている「関数を作る」とは、自分で「関数を定義する」ということです.では、関数を定義するとはどんなことなのかやっていきましょう!
例えば、次のような「3羽のペンギン」をコードで描くとします.
今までであれば、このような以下のようなコードを入力していたでしょう.
int x;
int y;
void setup(){
size(900,600);
}
void draw(){
background(0,150,250);
x=width/2; //Penguin No.1
y=150;
//body
stroke(0);
strokeWeight(150); //stroke(線)の太さを変更.
line(x,y-40, x,y+40);
noStroke(); //stroke(線)をない状態に.
fill(255);
ellipse(x,y+50, 110,125);
//eyes
ellipse(x+40,y-55, 20,25);
ellipse(x-40,y-55,20,25);
//mouth
fill(#F9FA14);
triangle(x,y-50, x+15,y-35, x-15,y-35);
//arm
fill(0);
triangle(x-100,y+50, x-70,y-20, x-70,y+30);
triangle(x+100,y+50, x+70,y-20, x+70,y+30);
//leg
fill(#F9FA14);
triangle(x-30,y+110,x-20,y+125,x-50,y+125);
triangle(x+30,y+110, x+20,y+125, x+50,y+125);
x=width/2-225; //Penguin No.2
y=height-150;
//body
stroke(0);
strokeWeight(150);
line(x,y-40, x,y+40);
noStroke();
fill(255);
ellipse(x,y+50, 110,125);
//eyes
ellipse(x+40,y-55, 20,25);
ellipse(x-40,y-55,20,25);
//mouth
fill(#F9FA14);
triangle(x,y-50, x+15,y-35, x-15,y-35);
//arm
fill(0);
triangle(x-100,y+50, x-70,y-20, x-70,y+30);
triangle(x+100,y+50, x+70,y-20, x+70,y+30);
//leg
fill(#F9FA14);
triangle(x-30,y+110,x-20,y+125,x-50,y+125);
triangle(x+30,y+110, x+20,y+125, x+50,y+125);
x=width/2+225; //Penguin No.3
//body
stroke(0);
strokeWeight(150); //stroke(線)の太さを変更.
line(x,y-40, x,y+40);
noStroke(); //stroke(線)をない状態に.
fill(255);
ellipse(x,y+50, 110,125);
//eyes
ellipse(x+40,y-55, 20,25);
ellipse(x-40,y-55,20,25);
//mouth
fill(#F9FA14);
triangle(x,y-50, x+15,y-35, x-15,y-35);
//arm
fill(0);
triangle(x-100,y+50, x-70,y-20, x-70,y+30);
triangle(x+100,y+50, x+70,y-20, x+70,y+30);
//leg
fill(#F9FA14);
triangle(x-30,y+110,x-20,y+125,x-50,y+125);
triangle(x+30,y+110, x+20,y+125, x+50,y+125);
}
正直、とても長くて入力するのが面倒ですよね...
ですが、「関数を定義する」と
このようにコードを短縮化することができるのです!
void setup(){
size(900,600);
}
void draw(){
background(0,150,250);
penguin(width/2, 150); //penguin No.1
penguin(width/2-225, height-150); //penguin No.2
penguin(width/2+255, height-150); //penguin No.3
}
void penguin(int x, int y){
//body
stroke(0);
strokeWeight(150); //stroke(線)の太さを変更.
line(x,y-40, x,y+40);
noStroke(); //stroke(線)をない状態に.
fill(255);
ellipse(x,y+50, 110,125);
//eyes
ellipse(x+40,y-55, 20,25);
ellipse(x-40,y-55,20,25);
//mouth
fill(#F9FA14);
triangle(x,y-50, x+15,y-35, x-15,y-35);
//arm
fill(0);
triangle(x-100,y+50, x-70,y-20, x-70,y+30);
triangle(x+100,y+50, x+70,y-20, x+70,y+30);
//leg
fill(#F9FA14);
triangle(x-30,y+110,x-20,y+125,x-50,y+125);
triangle(x+30,y+110, x+20,y+125, x+50,y+125);
}
draw関数のカッコ内にある「penguin( )」が まさに「作った関数」です.
また、作った関数のカッコ内にどの情報を入力するのかを
指定することが可能で、宣言時(例 : void penguin)の( )内で
データ型を用いることで指定できます.(例 : int x, int y )
2.「関数の定義」の仕組み
さて、「関数の定義のやり方」についてやりましたが、それはいったいどのような仕組みで実行されているのでしょうか?
[1日目] ”Processing”をやり始めよう!で記述した通り
通常、コードは上から下へ 順に実行されていきます.
ですが、「関数を定義」した場合はこのように実行されるのです.
「定義した関数」をdraw関数の中で見つけると、その関数の
詳細な情報を得るためにdraw関数の下にある
「その関数が定義されている部分」へジャンプします.
そして「定義されている部分」のコードを実行したのちに
元の場所であるdraw関数内に戻るのです!
3.”戻り値”と「関数の定義」について
実は「関数を定義」する際、”戻り値”があるかないかで「void」を使うか使わないかが決まります.そんな”戻り値”についてやっていきましょう!
「戻り値」について
「戻り値」は「返り値」とも言われるもので、関数から戻ってくる
(出力される)値のことをいいます.簡単に言うと、計算結果のことです.
例えば、ハンバーガーショップで「お金」を「店員」に渡すことで
「ハンバーガー」を入手したとします.
その場合、”「お金」が引数”で ”「店員」が関数”
”「ハンバーガー」が戻り値”となります.
そんな「戻り値」がない場合は、「関数を定義」するときに「void」を使います!そして戻り値がある場合はデータ型( int や float など)を使います.
POINT!!
「関数を定義」するとき、戻り値があるかないかで形が変わる.
・”戻り値がある”場合:「int」や「float」といったデータ型を使う.
・”戻り値がない”場合:「void」を使う.
4.戻り値がある場合の「関数の定義」
戻り値がない場合は、上記の「3羽のペンギン」を描いたように「void」を使いますが、戻り値がある場合はどのような形になるのでしょうか?
次の例では、月面での体重を計算して表示するコードを書いてみました.
※「kgf」は重量キログラムを表す単位です.
void setup() {
size(300, 300);
background(255);
int BodyWeight = 60; //自分の体重を入力してみよう!
int MoonBodyWeight = result(BodyWeight);
fill(0);
textSize(51); //テキストの大きさを変える.
textAlign(CENTER); //テキストを中央揃えにする.
text(MoonBodyWeight, 110, 170); //テキストを表示させる関数.
text("kgf",185,170);
}
int result(int weight) {
int calculate = weight/6;
return calculate; //returnで戻り値を指定.
}
ここで注目してほしいのは
定義した関数である 「 int result 」 の中にある「return文」です!
「return文」について
戻り値があるときに「関数を作る」場合は「return文」を必ず使います.
「作った関数」の 戻り値 を指定する役割を持っており、これがないと
うまくプログラミングが動かなくなるので注意が必要です!
+α(プラスアルファ)
・「text」: 実行ウィンドウ上で文字を描く関数です.
text (data ,x,y) ; で使い、data には表示したい文字を
指定したり、入力したりできます!文字を入力したい場合は、
text ("data",x,y) ; のように「 "(ダブルクオーテーション) 」
で入力する文字を囲む必要があります!
・「textSize」:「text」の文字サイズを指定するものです.
カッコ内で値を入力し、サイズを指定します.
・「textAlign」:「text」の文字揃えを指定するものです.
中央揃え (CENTER)、左揃え (LEFT)、右揃え (RIGHT)を
カッコ内に入力することで指定します.
5.コードを書いて復習しよう!
では最後に、今日やったことを自分で好きなコードを書くことで復習しましょう!
[練習]次のルールに従って、好きなコードを書こう!
ルール
・「作った関数」を使ってコードを書くこと.
・可能なのであれば、「text関数」を使ったコードを書くこと.
よろしければ、この記事のコメントに
そのコードを見せていただけると嬉しいです!
素晴らしい作品は後ほど紹介させていただきます!
ーーーーー
私はこのようなコードを書きました!
void setup(){
size(500,600);
}
void draw(){
background(255);
fill(0);
textAlign(CENTER);
textSize(51);
text("- Roll the Dice !-",width/2,100);
text("- FINISH ! -",width/2,520);
Dice(6,200); //第1パラメーターにサイコロの面数を入力.
Dice(6,height/2); //第1パラメーターにサイコロの面数を入力.
Dice(6,400); //第1パラメーターにサイコロの面数を入力.
noLoop(); //draw()の繰り返し処理を停止する.
}
void Dice(int num, int y){
int n= 1+ int(random(num));
textSize(30);
text("RESULT…"+n, width/2,y);
}
void mousePressed(){
loop(); //draw()の処理を再開する.
}
これは、3つのサイコロを振った結果の値を生成してくれるものです!
マウスをクリックすることで、振り直すことができます.
また、Dice関数 (作った関数) の第1パラメーターの値を変えることで
サイコロの面数を変えることが可能になってます!
+α(プラスアルファ)
・「noLoop」: draw( )の繰り返しの処理を止めてくれるものです.
・「loop」: noLoop( )で止めたdraw( )の処理を再開されるものです.
おわりに
今回は、自分で「関数を作る」ことについて学びました!
関数を作るときの” 流れ ”や「戻り値」との関係性などは少し複雑ですが
今回やった内容もとても重要なので ぜひ覚えといてください!
今回も見ていただき、ありがとうございました!
これからも一緒に楽しくプログラミングの基礎を学んでいきましょう!