Processingでオブジェクト指向-1(クラス、メソッド)

Filed in processing , インタラクティブメディア演習III(3年ゼミ) 1 comments

さて、次のステップはクラス、メソッドです。
これは、「オブジェクト指向言語」の中で使われる概念です。オブジェクト指向は何??という人も多いかもしれませんが、これは、「オブジェクト単位によって設計された」と考えて下さい。

オブジェクト単位ということをもう少し説明しましょう。
オブジェクト指向言語でのクラスとは「型」のことを指します。例えば紅葉まんじゅうの型ですね(人形焼きでもいいんですけど)。

manju.jpg
「もみまんの歴史」より参照

http://www.aa.alpha-net.ne.jp/usaco3/momiman/rekisi.htm

重要なのは、紅葉まんじゅうの型(クラス)は同じなのですが、出来たまんじゅう(オブジェクト)はちょっとずつ違うということです。当然焼き色も違うし、中に入っている餡の量も違うでしょう。
このように、オブジェクトは一つの型(クラス)を元にしていますが、それぞれに個体差を付加することができます。
概念的には以下のような図になります。

object1.png
このように、オブジェクト指向とは、現実の世界でのものの捉え方(車、人間、犬など)に近い考え方でプログラミングを行なうもだと考えていいと思います。

ここで注目して欲しいのは、オブジェクトはそれぞれメソッドを持っていることです。メソッドとは、既に習った関数(function)と機能的には同じだと考えていいでしょう。つまり、手続き型言語における関数がオブジェクト指向言語におけるメソッドなのです。
また、オブジェクトはインスタンス(実体)とも呼ばれます。

例題

screen1.PNG

それでは、実際のプログラムはどのようにすればいいのでしょう。
まずはクラスを作ってみましょう。
以下は、横方向に設定されたスピードで移動する円を生成するクラスです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Circleクラスの宣言
class Circle {
  float xPos, yPos, speed; 
  int eSize;
 
  Circle (float y, int es, float sp) {    //初期化用のメソッド(コンストラクタ)
    xPos = 0.0;    //x座標の初期値は0.0
    yPos = y;     //y座標の初期値はオブジェクトを宣言した際の引数になる
    eSize = es;
    speed = sp;     //speedの初期値もオブジェクト宣言の際の引数
  }
 
  //円の位置を更新するメソッド
  void update() {
    xPos += speed;    //speed分のx座標を移動
    if (xPos > width) {    //円のx座標がウィンドウの幅を超えたら、
      xPos = 0;    //位置を0に戻す
    }
    ellipse(xPos, yPos, eSize, eSize);    //円を描く
  }
}

上の式で分かりづらいのは、初期化用のメソッド(コンストラクタ)でしょう。これは、そのクラスを初期化するために同じ名前のメソッドは必ず入れなければならないという規則があるのだと考えて下さい。
updateメソッドを実行するたびに、円のx座標であるxPosの値にspeedが足されていきます。完全なコードは以下の通りです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Circle c1, c2;    //moveCircleクラスのオブジェクト(インスタンス)を宣言
 
void setup()
{
  size(200, 200);
  smooth();    //図形の輪郭をきれいに描画
  fill(0);    //黒で描画
 
  c1 = new Circle(20.0, 10, 1.0);    //オブジェクトを作成
  c2 = new Circle(150.0, 40, 3.5);
}
 
void draw() {
  background(255);    //背景は白
  c1.update();    //c1, c2オブジェクトのupdateメソッドを実行
  c2.update();
} 
 
//Circleクラスの宣言
class Circle {
  float xPos, yPos, speed; 
  int eSize;
 
  Circle (float y, int es, float sp) {    //初期化用のメソッド(コンストラクタ)
    xPos = 0.0;    //x座標の初期値は0.0
    yPos = y;     //y座標の初期値はオブジェクトを宣言した際の引数になる
    eSize = es;
    speed = sp;     //speedの初期値もオブジェクト宣言の際の引数
  }
 
  //円の位置を更新するメソッド
  void update() {
    xPos += speed;    //speed分のx座標を移動
    if (xPos > width) {    //円のx座標がウィンドウの幅を超えたら、
      xPos = 0;    //位置を0に戻す
    }
    ellipse(xPos, yPos, eSize, eSize);    //円を描く
  }
}

どうでしょうか?c3、c4と、いくつもオブジェクトを増やしてみて下さい。

オブジェクトの配列化

さて、このように性格の違うオブジェクトを作成することに成功したら、もっと数を増やしたくなるというのが次の段階でしょう。
この場合には、配列を使います。
手順は今までのコードと殆ど変わらないのですが、配列のそれぞれの箱にオブジェクトを入れるのだと理解してください。
次の練習問題をやってみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Circle[] circles = new Circle[20];   //20個のオブジェクトを作成 
 
void setup()
{
  size(200, 200);
  smooth();    //図形の輪郭をきれいに描画
  fill(0);    //黒で描画
 
  //オブジェクトを作成
  for(int i = 0; i < circles.length; i ++) circles[i] = new Circle(i*10, 5, i/10.0);
}
 
void draw() {
  background(255);    //背景は白
   //オブジェクトのupdateメソッドを実行
   for(int i = 0; i < circles.length; i ++) circles[i].update();
} 
 
//Circleクラスの宣言
class Circle {
  float xPos, yPos, eSize, speed; 
 
  Circle (float y, int es, float sp) {    //初期化用のメソッド(コンストラクタ)
    xPos = 0.0;    //x座標の初期値は0.0
    yPos = y;     //y座標の初期値はオブジェクトを宣言した際の引数になる
    eSize = es;
    speed = sp;     //speedの初期値もオブジェクト宣言の際の引数
  }
 
  //円の位置を更新するメソッド
  void update() {
    xPos += speed;    //speed分のx座標を移動
    if (xPos > width) {    //円のx座標がウィンドウの幅を超えたら、
      xPos = 0;    //位置を0に戻す
    }
    ellipse(xPos, yPos, eSize, eSize);    //円を描く
  }
}

練習問題1

上のサンプルをもとにして、Y座標も変化する円の集合を作ってください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Circle[] circles = new Circle[20];   //20個のオブジェクトを作成 
 
void setup()
{
  size(200, 200);
  smooth();    //図形の輪郭をきれいに描画
  fill(0);    //黒で描画
 
  //オブジェクトを作成
  for(int i = 0; i < circles.length; i ++){
    circles[i] = new Circle(random(width), random(height), 5,
                            random(1.0, 10.0), random(1.0, 10.0));
  }
}
 
void draw() {
  background(255);    //背景は白
  //オブジェクトのupdateメソッドを実行
  for(int i = 0; i < circles.length; i ++) circles[i].update();
} 
 
//Circleクラスの宣言
class Circle {
  float xPos, yPos, xSpeed, ySpeed; 
  int eSize;
 
  Circle (float x, float y, int es, float xSp, float ySp) {    //初期化用のメソッド(コンストラクタ)
    xPos = x;    //x, y座標の初期値はオブジェクトを宣言した際の引数になる
    yPos = y;
    eSize = es;
    xSpeed = xSp;     //xSpeed, ySpeedの初期値もオブジェクト宣言の際の引数
    ySpeed = ySp;
  }
 
  //円の位置を更新するメソッド
  void update() {
    xPos += xSpeed;    //xSpeed分のx座標を移動
    yPos += ySpeed;    //ySpeed分のy座標を移動
 
    if (xPos > width) {    //円のx座標がウィンドウの幅を超えたら、
      xPos = 0;    //位置を0に戻す
    }else if (yPos > height) {    //円のy座標がウィンドウの幅を超えたら、
      yPos = 0;    //位置を0に戻す
    }
    ellipse(xPos, yPos, eSize, eSize);    //円を描く
  }
}

練習問題2

screen2.PNG

次はもう少し複雑になります。ドラッグして投げると、円が投げた方向とスピードを記憶していて、そのまま画面内をバウンスし続けます。

上のクラスは、それぞれ生成された円が、マウスの投げるスピードによってその円自体のスピードを決定できるというものです。
練習問題としてはかなり難しいかもしれませんが、Circleクラスの中を記述して、プログラムが動くように変更して下さい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// 円の生成のサンプル
 
int count = 0;  //マウスクリックによって生まれる円の番号
 
//Circleクラスのcirclesオブジェクトを宣言
Circle[] circles = new Circle[20];   //20個のオブジェクトを作成 
 
void setup()
{
  size(400,400);  
  background(255);
  smooth();
 
  // circlesオブジェクトの生成と配列の初期化
  for (int i = 0; i < circles.length; i++) circles[i] = new Circle();
}
 
void draw()
{
  background(255);
 
  //常にcircles[]を更新
  for (int i = 0; i < circles.length; i++) circles[i].update();
}
 
void mouseDragged () {
  circles[count].x = mouseX; 
  circles[count].y = mouseY;
}
 
//マウスドラッグによるイベント
void mouseReleased () {
  circles[count].xSpeed = mouseX - pmouseX;
  circles[count].ySpeed = mouseY - pmouseY;
 
  count ++;   //順番に更新
  if(count >= circles.length) count = 0; 
}
 
// Circle クラスを作成
//////////////////////////////////////////////////////////
class Circle {
 
  float x;  //円のx座標
  float y;  //円のy座標
  float radius;  //円の直径
  float xSpeed;  //x軸方向のスピード
  float ySpeed;  //y軸方向のスピード
 
  //初期化用のメソッド(コンストラクタ)
  Circle()
  {
    xSpeed = 0.0;  //スピードの初期値は0.0
    ySpeed = 0.0;
    x = width/2;  //x,yは画面の中心に設定
    y = height/2;
    radius = 5.0;  //円のサイズを設定
  }
 
  //円の描画更新用メソッド
  void  update()
  {
    // speedで設定された値を足す
    x += xSpeed;
    y += ySpeed;
    if(x > width || x < 0 ) xSpeed = -xSpeed;
    if(y > width || y < 0 ) ySpeed = -ySpeed;
    //noStroke();
    fill(0);
    ellipse(x,y,radius,radius);  //円を描画
  }
}
Posted by noguchi   @   26 6月 2007 1 comments

1 Comments

Comments
Trackbacks to this post.

Sorry, comments are closed.

Previous Post
«
Next Post
»
Stroom designed by Credit Cards In conjunction with Web Hosting Reseller , Dream Interpretation Guide , Best Website Hosting.