back to [[11_YoshidaY]]~
*コンストラクタについて [#r84e308b]

#contents

(このページに対する苦情等受け付けます)~
- 日記みたいに気分で書いたから読みにくさ半端ないねw -- [[11_YoshidaY]] &new{2012-04-20 (金) 03:11:51};
- とりあえずもうちょっとすっきり書きます。 -- [[11_YoshidaY]] &new{2012-04-30 (月) 11:23:28};

#comment

**Processingの初歩解説~コンストラクタ [#e0793fa4]
**コンストラクタについて [#e0793fa4]
Wikipedia「コンストラクタ(構築子、Constructor)は、オブジェクト指向のプログラミング言語で新たなオブジェクトを生成する際に呼び出されて内容の初期化などを行なう関数、メソッドのことである。」。まぁ、わかんないね。~
これはオレが最近よく使うプログラミングの技みたいなもので、まぁ基本なんだろうけど便利なんで解説します。(あ、Processingでのコンストラクタですよ。~
~
***①使用するコード [#rd04909e]

***使用するコード [#rd04909e]
じゃあまず、とりあえず[[このzipファイル(constructor.zip):https://docs.google.com/open?id=0B44PZsb4Cl6cLTctdExTZC1EYkE]]をDLして中のファイルのどれかをProcessingで開いてね。~
constructor,Circle,Line,Quadってゆう4つのタブが開かれると思います。~
これは、constructorってゆうタブが中心のコードです。~
他の3つは、クラスって言うものです。~

***②Processingの始め方 [#q053395f]
Processingでのプログラムは、~
 void setup() {
 }
 void draw() {
 }
っていうコードが書かれてる所を中心に動きます。~
クラスとか関数(void)って言われるものは、くっつけていく部品みたいなもんです。~
-setup()
プログラムを起動してからまず最初に動く部分で、一回だけしか実行されない部分です。~
つまり、ウィンドウのサイズをどうするか(size(300, 300))とか、宣言した変数の初期値をいくらにするか(x = 0)とかをここで指定します。~
-draw()
中に書かれている内容の命令を、上の「{」から順番に下まで実行していき、下の「}」まで行ったらもっかい上の「{」に戻ってループするっていうものです。~
だからアニメーションしたい時とかはここで値が変わる様な命令をします。~

***③Processingで円を描く [#md6888d7]
じゃあ簡単に、[[Processingで円:http://processing.org/reference/ellipse_.html]]を書きたいとします。~
難しくないです。文系も文系なオレが言うから間違いない。~
 void setup() {
   size(400, 400); //横400,縦400の画面に設定
   background(255); //背景は白
 }
 void draw() {
   ellipse(width/2, height/2, 40, 40);
   //ウィンドウの右端の座標(width)の半分のx座標,底の座標(height)の半分のy座標
   //横と縦の直径
 }
これで再生ボタンみたいな実行ボタンを押すと円が画面中央に表示されたはずですね。~
これが第一歩です。~

***④Processingで円を動かす [#m03973f5]
じゃあこれを動かしたい時、~
 ellipse(width/2, height/2,
この部分を変数に変えて、変数の値を徐々に増やすなり減らすなりすれば動きます。~
具体的に言うと、~
 int x, y; //整数の変数を宣言(整数=少数点以下がない)
 void setup() {
   size(400, 400);
   x = 0; y = 0;
 }
 void draw() {
   background(255);
   x++; y++;
   ellipse(x, y, 40, 40);
 }
これが一番簡単なサンプルです。~
動かしてみると、斜めに円が進んで行きますよね。~
この時ちょっと注意しときたいのが、draw()の中に[[background:http://processing.org/reference/background_.html]]が入ってきてる事です。
アニメーションしたい時はdraw()に入れるのが普通です。~
じゃないと背景が更新されなくて軌道が見え見えですね。~

円を使ってアニメーションしたいならここまで来れば後はテキトーにやってれば色々できます。~
じゃあこっから何が言いたいのか。~

**複数の円を表示させたい時。それぞれの円をばらばらに動かしたい時。 [#ja1a93ad]
***①-①悪い例 [#ic7b897e]
こんな時、さっきまでのやり方では段々めんどくさく、円の量が多いほど使用する変数が多くなり、わかりにくくて変数で溢れかえる様なプログラムになります。~
~
実際にオレが昔やってた、効率の悪い例を書きましょう。(多少極端~
***①-②プログラム例 [#i47fcf82]
 int x1, y1;
 int x2, y2;
 int x3, y3;
 void setup() {
   size(400, 400);
   x1 = 0; y1 = 0;
   x2 = 100; y2 = 100;
   x3 = 300; y3 = 300;
 }
 void draw() {
   background(255);
   x1++; y1++;
   x2++; y2++;
   x3++; y3++;
   ellipse(x1, y1, 40, 40);
   ellipse(x2, y2, 40, 40);
   ellipse(x3, y3, 40, 40);
 }
3つの円を動かすために、合計6つの変数を定義して、初期化(最初の値を決めること)して、+1ずつ動いていけって命令して。。あぁ面倒くさい。~
最初はこれでも良いんです。~
でも大量に円を表示したい時に、これじゃあまりにも変数やその他もろもろが溢れて、どの変数がどれで何をするものなのか、一目でわかるもんじゃありません。~

こっからこのページの本題に入ります。~
こんな時に便利なのが今回紹介させて頂きますこのコンストラクタ!~
なんと今まで収納に困っていたこれらのものをまとめちゃうことができちゃうんです!~
え?ピンとこない?テンションがうざい?~
仕方ないよ。そろそろ深夜2時だしね。~

***②-①コンストラクタを使う例 [#c705721e]
具体的にどうすることなのかっていうと、まぁ実際動かしてみた方が早いんだけど、~
さっきと同じものを作るとすると、~
***②-②プログラム例 [#c6d8aead]
 Circle c1, c2, c3;
 void setup() {
   size(400, 400);
   c1 = new Circle(0, 0, 20);
   c2 = new Circle(100, 100, 20);
   c3 = new Circle(300, 300, 20);
 }
 void draw() {
   background(255);
   c1.display(); c1.move();
   c2.display(); c2.move();
   c3.display(); c3.move();
 }
 class Circle{
   int x, y, r;
   Circle(int xpos, int ypos, int radius) {
     x = xpos; y = ypos;
     r = radius;
   }
   void move() {
     x++; y++;
   }
   void display() {
     ellipse(x, y, r*2, r*2);
   }
 }
この段階ではこっちを書く方が実感的にはめんどくさいね。~
けど後でもうちょい楽になるから待ってね。~
まずはこれがどうなってるかっていう解説をします。~
***③プログラム解説 [#xe29b37d]
- class Circle
これが一番大事。~
クラスって言うものを一言で言うなら、他の人が作ったコードを、自分のコードに連結しやすい様に記述されてるものです。なるほどわからん。~
使えるようになればなんとなくわかるんでとりま放置しましょ←~
~
ここでCircleっていうクラスを宣言しています。~
 int x, y, r;
 Circle(int xpos, int ypos, int radius) {
   x = xpos; y = ypos;
   r = radius;
 }
次にここ。~
ここを見る時に一緒に見るのが、setup()の中の~
 c1 = new Circle(0, 0, 20);
っていうコードになります。~
ここでのCircle()の中に入れた数字(0, 0, 20)は、~
上の(int xpos, int ypos, int radius)にそれぞれ突っ込まれます。~
すると、その次の、~
 x = xpos; y = ypos; r = radius;
にある様に、xpos, ypos, radiusに突っ込まれた数字が、x, y, rに移されます。~
ここで、~
c1のxの初期値は0,yは0,rは20と決定されました。~
~
最後にこの数字を使って、円を描画するための「関数」を作ります。~
 void display() {
   ellipse(x, y, r*2, r*2);
 }
この部分です。~
ここのdisplayっていう名前は、テキトーに変更しても大丈夫ですよ。~
でもまだこれだけじゃ描画されるわけじゃないんです。~
だって、まだdraw()の中に何も書いてないから。~
~
では次、~
 c1.display();
について解説します。~
これは、先程のdisplay()を、c1にだけ実行させなさいっていう命令です。~
display()っていうのは、円を描画する機能を持った関数なんで、この場合、~
c1の円だけ描画しなさいってことになります。~
・・・みんな大丈夫?~
説明分かりにくかったらコメント欄に苦情してくださいね。~

どんどん次行くよ。~
 c1.move();
って部分なんだけど~
これは~
 void move() {
   x++; y++;
 }
って所をご覧ください。~
xとyを1ずつ足すっていう処理をするための関数です。~
これを、c1に限ってmoveするってことです(え~
つまりc1のxとyに1ずつ足してくっていう命令を、c1.move();という風に~
draw()の中に書くとmove()の中が実行されるんですよ。~
動かしてみたらなんとなくわかるんじゃないかな。~
~
これが一通りの流れです。~
で、一番最初の~
 Circle c1, c2, c3;
で、この組み合わせを3つ宣言してるんです。~
何個でも宣言できるよ。~
けどこの書き方、ちょっとあんまり効率的じゃない。~
さっきのプログラムを書き換えてみますね。~
 Circle[] c;
 void setup() {
   size(400, 400);
   c = new Circle[3];
   c[0] = new Circle(0, 0, 20);
   c[1] = new Circle(100, 100, 20);
   c[2] = new Circle(300, 300, 20);
 }
 void draw() {
   background(255);
   for(int i = 0; i < 3; i++) {
     c[i].display(); c[i].move();
   }
 }
 class Circle{
   int x, y, r;
   Circle(int xpos, int ypos, int radius) {
     x = xpos; y = ypos;
     r = radius;
   }
   void move() {
     x++; y++;
   }
   void display() {
     ellipse(x, y, r*2, r*2);
   }
 }
だいたいこんな感じかな。~
ちょっとスマートになったはずです。~
っていうのは、クラスって言うのは配列化することができるんです。~
これで宣言の手間がさらに省けたってもんですね。~

配列がわからない人は、んー。~
さすがに配列の説明までするのはめんどくさいんだけど。。~
--平たく言う配列~
入れ物としての箱をイメージしてください。~
変数というのはそれ自体すでに一つの箱です。数字を入れるための。~
それを何個も宣言して色々プログラムを作るんだけど。~
---同じ意味で使うんだけど変化の量を変えたい。(比例でいうと比例定数を変えたい的な~
---何個も宣言して初期化してめんどくさい。~
って時に使うのが配列。~
例えば
 int[] a = new int[10];
って書くと、aっていう名前のついた整数を入れるための箱が、10個用意されます。~
a[0], a[1], a[2], a[3],……,a[9]~
と言う風に。
ここで要注意なのが、0から数えられるってこと。~
これでいちいち
 int a1, a2, a3, a4…a9;
みたいに全部宣言せずに済むし、全部初期値が0で良いなら
 void setup() {
   int[] a = new int[10];
   for(int i = 0; i < 10; i++) {
     a[i] = 0;
   }
 }
ってすれば初期化もすごく楽に済むんだ。~
※[[for:http://processing.org/reference/for.html]]とは~

ここまででだいたいコンストラクタの使い方は終わり。~
後は、コンストラクタの変数の使い方だけです。~

例えば、さっきのプログラムでは、全部同じ方向に同じ速度で進んでたものを、~
一個だけ速くしたいとか、遅くしたいとか、思った時。~
どうすればいいか。~
これもサンプルで説明します。~
 Circle[] c;
 void setup() {
   size(400, 400);
   c = new Circle[3];
   c[0] = new Circle(0, 0, 20);
   c[1] = new Circle(100, 100, 20);
   c[2] = new Circle(300, 300, 20);
 }
 void draw() {
   background(255);
   for(int i = 0; i < 3; i++) {
     c[i].display();
   }
   c[0].move(); c[1].move();
   c[2].x -= 2; c[2].y -= 3;
 }
 class Circle{
   int x, y, r;
   Circle(int xpos, int ypos, int radius) {
     x = xpos; y = ypos;
     r = radius;
   }
   void move() {
     x++; y++;
   }
   void display() {
     ellipse(x, y, r*2, r*2);
   }
 }
このプログラムでは、実行してもらえばわかりますが、一番下にある円が上に向かって逆走しています。~
つまり、c[2]の円だけ逆走させているんです。~
 c[0].move(); c[1].move();
 c[2].x -= 2; c[2].y -= 3;
に注目してもらえたらと思いますが、~
c[0]とc[1]についてはmove()させています。~
つまりx,yが1ずつ増えていく命令です。~
問題はc[2]です。~
c[2].xとあります。~
ここがコンストラクタの一番便利な点だと思うんですが、~
「宣言したクラスの名前.変数名」ってすると、「どのクラスのどの変数」という風に指名できるんです。~
これを使って、
 c[2].x -= 2;
つまり、c[2]のxだけを、-2する命令をしています。~
これを応用すれば、色々なことができる様になりますよ。~

自分が思いつきで書ける範囲は、ここまでですが、~
自分よりもちゃんとプログラミング勉強した人とか、全然違うよとかあったらツッコミ入れてください。~
やれる範囲で修正しま(めんど~
す。←~
~
プログラミング初めての人も、オレも3回生までプログラミングのプもやったことなかったから。~
なんか作りたいモノがあればそのうちある程度出来るようになるんで、大丈夫やよ。~
みんなで協力して頑張ろう。~

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS