フローチャートのススメ(変数のスコープを少し)
宿題
前回の宿題、『ループのループ』のフローチャート。
理解できた!これだっ!
size(400, 300);
for( int d =50 ; d > 0 ; d = d-10){
for(int x = 40; x < width; x = x+50){
ellipse(x,height/4, d, d);}
}
これを分解して考えると、以下のような順序で作図されていることがわかります。
まず最初に実行されるのは中に入っているループの部分。直径が外のループで50になり固定されます。それからd>0でテストを経てループに入ります。
このループでは直径50の円はそのままに、Xの値だけが50ずつ増える=横にずれていくので上記のように丸が描かれます。丸が幅 x < width のテストでfalse(xは画面幅より小さいか、いいえ)の場合にdの部分が更新されます。
①でdの値が40になるのでこのループで描かれる円の直径は40です。d > 0のテスト結果はtrue(直径dは0より大きいか、はい)なので、再度中のループに入ります。中のループで③初期化 (int x =40) が実行されるのでxの値がもどり円の位置はまた一番左端に戻ります。そこから先は最初のループと同じです。
結果は同じになりますが、違う方法で描くことも可能です。
このループでは
同じ大きさの丸を右端まで描く
次に小さい円を左端から右端まで描く
さらに小さい円を。。。。
という順序ですが、
左端の円を小さい円まで描く
その隣に同じものを描く
といった順序で描くことも可能です。
その場合はこのループの外と中がひっくり返るだけです。
わかると単純ですが、いままで『なんとなぁーく』やってしまっていたので、フローチャートは目からウロコです。
フローチャートのルール
前回の投稿の際にフローチャートの描き方には一定のルールがあるらしい。と書きました。
このサイトを見たのですが、まだまだ初心者の私には縁のないものが多すぎて『どこで使うのこれ?』みたいなものばかりでした。
今回のコードで使ったのは主に3つだけ(ページ内 4.フローチャートの基本ルール(記号)参照)
①開始・終了 プログラムのスタートと終了 丸っこい四角で囲む
②処理 角ばった四角 中には処理する内容が書かれています
③条件分岐 菱形 trueとfalseのようにわかれるところに使います
あとは、ま、追々ってことで。。。
あと、フローチャート作りに使ったのはこのサイトです
前回のフローチャートはイラレで作ったのですが、今回のは上記サイトで作りました。
こっちの方が倍ぐらい作りやすいです。矢印もついてくるし、さすがチャート作りに特化したアプリなだけあります。ぜひ使ってみてください。
変数のスコープ
setup()とdraw()の関数のところでこの変数のスコープが出てきます。setup()は文字通りセットアップに使われるもので、これは一度しか実行されません。対してdraw()は繰り返し実行されます。
int x = 0;
void setup(){
size(200 , 150);
}
void draw(){
delay(500);
ellipse(x, height/2, 20, 20);
x += 20;
}
動きの速度を調整するためdelay();という関数を足しています。
delay(milliseconds)
数値の単位はミリ秒(1/1000)です。その時間の分だけプログラムを一時停止します。この場合0.5秒の停止時間になります。(しかしgifアニメを作るアプリの方でも調整しているので上記のgifはこの数値にはなっていません)
saveFrame();でpngファイルを出力してそれを放り込めばgifアニメーションにしてくれます。すごい簡単で重宝しそう。
saveFrame(filename);
filename 任意の文字+ #### + 拡張子(.tif, .tea, .jpg, .png)
少しそれましたが、上記の変数は int x = 0;
この宣言はsetup()とdraw()の{}の外側にいます。
この時の変数をグローバル変数と呼びます。
ここで宣言されたものは、以後すべての箇所で使用することが可能です。
対してsetup()内、draw()内で宣言されたものはその中でしか使えません。
例えばこの宣言をdraw()内に入れてしまうとどうなるか。
これだけです。繰り返しの中に入ってしまったので、宣言も繰り返されることになり最後の x += 20; が打ち消されてしまいアニメーションになりません。
本題
で、今日は実はここが本題です。
本に書いてある例題でマウスの位置を判定するものがあります。
中心に書いてある小さな白い円にカーソルを合わせると、黒くなってどんどん大きくなります。円の外にカーソルを外すと、大きさがその場で止まり、白い円にもどります。
int x = 400;
int y = 300;
int radius = 12;
void setup(){
size(800, 600);
ellipseMode(RADIUS);
}
void draw(){
background(204);
float d = dist(mouseX, mouseY, x, y);
if(d < radius){
radius ++;
fill(0);
}else{
fill(255);
}
ellipse(x, y, radius, radius);
}
キャンバスサイズだけ変更してあります。(大きくて見やすいのが好みなので)
この例題ではxとyの値が最初に宣言されており、それが画面の中心になっています。
画面の中心なら、いままでのもののようにwidth/2、height/2が使いたい!
なぜなら数字をできるだけみたくないから!!(数字アレルギー)
ということで、こう変換しました。
int x = width/2;
int y = height/2;
int radius = 12;
void setup(){
size(800, 600);
ellipseMode(RADIUS);
}
void draw(){
background(204);
float d = dist(mouseX, mouseY, x, y);
if(d < radius){
radius ++;
fill(0);
}else{
fill(255);
}
ellipse(x, y, radius, radius);
}
すると
?????
なんで?????
いままで中心にあったものが、左上に移動してしまいました。
スコープの話があったので、同じものをdraw()の中に入れてみました。
int radius = 12;
void setup(){
size(800, 600);
ellipseMode(RADIUS);
}
void draw(){
int x = width/2;
int y = height/2;
background(204);
float d = dist(mouseX, mouseY, x, y);
if(d < radius){
radius ++;
fill(0);
}else{
fill(255);
}
ellipse(x, y, radius, radius);
}
あ、戻ってきた。
解せぬ。
数値は同じはずなのに、グローバル変数にしたとたん、数値がずれてしまう。
何故。何故だー!!!
このモヤモヤを書きたいが為に変数のスコープに触れました。
長い時間考えましたが、よくわからないので、ちょっと無視して進もうと思います。また、わかった時にこれは解決しようと思います。
無期限の宿題!
この記事が気に入ったらサポートをしてみませんか?