目次
変数
変数は値の保持に使用されます。次のサンプルでは、変数の値を変更して、その構成に影響を与えています。
function setup() {
createCanvas(720, 400);
background(0);
stroke(153);
strokeWeight(4);
strokeCap(SQUARE);
// このsetup()関数内でのみ利用できるローカル変数
let a = 50;
let b = 120;
let c = 180;
draw4Lines(a, b, c);
ellipse(a + 80, b + 60, 30);
// 変数の値を変更
a = a + c;
b = height - b;
draw4Lines(a, b, c);
// さらに変更
a = a + c;
b = height - b;
draw4Lines(a, b, c);
ellipse(a + 80, b + 60, 30);
}
// aaからaa+ccまでの横線を、y値を変えて4本描く
function draw4Lines(aa, bb, cc) {
line(aa, bb, aa + cc, bb);
line(aa, bb + 10, aa + cc, bb + 10);
line(aa, bb + 20, aa + cc, bb + 20);
line(aa, bb + 30, aa + cc, bb + 30);
}
下図はこの実行結果です。
– 解説 –
このプログラムが起動し、setup()関数が呼び出されると、変数a,b,cにはそれぞれ50,120,180が割り当てられます(初期化)。その後 draw4Lines(a, b, c)が呼び出されるので、これは draw4Lines(50, 120, 180)と同等ということになります。
その後、
a = a + c;
b = height – b;
という2行が来ています。これは、aにcを足した結果をaに割り当て(代入し)、高さからbを引いた結果をbに代入しろという意味です。したがって、
a = 50 + 180 = 230
b = 400 – 120 = 280
ということになり、draw4Lines(a, b, c)はdraw4Lines(230,280,180)になります。前と同じdraw4Lines(a, b, c)を実行しているのですが、変数a,b,cが保持している値が異なるので、その結果も変わる、ということになります。
プログラミングの解説書などではよく、変数は箱にたとえられます。箱には名前がついていて、その中に値が入っている、という考え方です。
TrueとFalse
ブーリアン型の変数は2つの値、trueとfalseのどちらかだけを持つことができ、ブーリアン型はプログラムの流れ(フロー)を決める制御ステートメントでよく使用されます。次のサンプルでは、ブール値bがtrueであれば垂直の線が描かれ、ブール値bがfalseであれば、水平の線が描かれます。なお、変数iが参照している値をtext()関数で線の端に描画しています。
function setup() {
createCanvas(720, 400);
background(0);
stroke(255);
fill(255, 0, 0);
textSize(10);
let b = false;
let d = 20;
let middle = width / 2;
// iは20からスタートし、20刻みで720まで大きくなる
// 20,40,60,80,...,720
for (let i = d; i <= width; i += d) {
// iが360未満かどうか
// 未満ならbはtrue
b = i < middle;
// bがtrueなら => iが360未満なら => 繰り返しの前半分
if (b === true) {
// 垂直線を描く
line(i, d, i, height - d);
text(i, i - 10, d);
}
// iがmiddle(360)以上ならbはfalse
if (b === false) {
// 水平線を描く
line(middle, i - middle + d, width - d, i - middle + d);
text(i, middle, i - middle + d)
}
}
}
変数のスコープ
変数は、グローバルスコープ(プログラムのどこからでも見ることのができる範囲)か、または関数スコープ(その関数内でのみ見ることのができる範囲)を持ちます。たとえば、setup()かdraw()関数の中で宣言された変数はその関数でのみ利用できます。グローバル変数はsetup()やdraw()の外で宣言された変数で、プログラムのどこでも利用することができます。関数変数がグローバル変数と同じ名前で宣言された場合でも、プログラムは、その時点のスコープ(カレントスコープ)での計算にその関数変数を使用します。
// このaはグローバルな変数 => このJSファイルのどこからでも見ることができる。
let a = 80;
function setup() {
createCanvas(720, 400);
background(0);
stroke(255);
noLoop();
}
function draw() {
// グローバル変数のaを使って線を描く
// (80, 0)から(80, 400)まで線を引くので、線は垂直の線になる
line(a, 0, a, height);
print('draw()内 :' + a);
// forループの中でローカル変数のaを使用する
// ローカル変数aは、このforループの中でのみ見ることができる
// ローカル変数aは120からスタートし、3刻みで200未満まで大きくなる
// 120,123,126,129,...198
for (let a = 120; a < 200; a += 3) {
// 最初の線は(120,0)から(120,400)まで、2本めの線は(123,0)から(123,400)まで描かれ、
// 最後の線は(198,0)から(198,400)まで描かれるので、結果として縦縞のように見える
line(a, 0, a, height);
print('forループ内 :' + a);
}
// ここでカスタム関数のdrawAnotherLine()を呼び出す
drawAnotherLine();
// ここでカスタム関数のdrawYetAnotherLine()
drawYetAnotherLine();
}
function drawAnotherLine() {
// ローカル変数のaを作成する。
// このローカル変数aはこの関数内でのみ見ることができる。
let a = 320;
// ローカル変数のaを使って線を描く
// (320,0)から(320, 400)までの線を引くので、線は垂直の線になる
line(a, 0, a, height);
print('drawAnotherLine()関数内 :' + a);
}
function drawYetAnotherLine() {
// この関数内では、ローカル変数aを設定していないので、
// この線はグローバル変数のaを使って描かれる。
// aの値は80
// (83, 0)から(83, 400)までの線を引くので、線は垂直の線になる => 最初に描いた線のすぐ右
line(a + 3, 0, a + 3, height);
print('drawYetAnotherLine()関数内 :' + a);
}
下図はこの実行結果です。
– 解説 –
変数のスコープの理解はプログラミングにとって重要です。今その変数が何の値を保持している(参照している)のか、を調べるには、print()関数やconsole.log()メソッドが役立ちます。
下図は、上記サンプルで使われている変数aの見える範囲(スコープ)を示した図です。ブラウザのコンソール画面には、print()関数によって、変数aが参照している値が出力されるので、確認してみてください。
ここではあくまでも例として、グローバル変数とローカル変数に同じ名前が使われていますが、間違いの元になるので、通常は別の変数名を使用します。
数値
数値は小数点を付けても付けなくても記述できます。整数(integer、通常はintと呼ばれます)は小数点のつかない数値です(例:123)。浮動小数点数(float)は、小数を持つ数値を言います(例:3.14)。
// 数値型のグローバル変数aを作成
let a = 0;
// 数値型のグローバル変数bを作成
let b = 0;
function setup() {
createCanvas(720, 400);
stroke(255);
print('変数aの型:' + typeof a); // number
print('変数bの型:' + typeof b); // number
}
function draw() {
background(0);
// aを整数でインクリメント => aはdraw()が呼び出されるたびに1だけ大きくなる
a = a + 1;
// bを浮動小数点数でインクリメント => bはdraw()が呼び出されるたびに0.2だけ大きくなる
b = b + 0.2;
// (a, 0)から(a, 200)まで線を描画
line(a, 0, a, height / 2);
// (b, 200)から(b, 400)まで線を描画
line(b, height / 2, b, height);
// キャンバスの右端を超えたらリセット
if (a > width) {
a = 0;
}
if (b > width) {
b = 0;
}
}
これを実行すると、上の線の方が速く右に移動するのが分かります。