カテゴリー
Processing

Processing(Step3)

図形を並べる

for文の活用

Step2で図形を描画しましたが、例えば、100個の円を描画したいとなった時に1つずつ作っていたら、面倒くさいですよね。そのためには、Step1で学んだ繰り返し処理を用います。まずは、次のコードを実行してみましょう。

int n = 7; //並べる円の数

void setup()
{
    size(1000, 1000); 
    background(255); //背景色を白にする
    noStroke(); //図形の枠線を描かない
    fill(255,0,0); //図形の塗りつぶしを赤色にする
}

void draw()
{
  for(int i = 1; i <= n; i = i+1){//円の数が7になるまで繰り返し処理をする
  ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
  }
}

実行すると、以下のような画面になると思います。

重要な処理はここのコードになります。

 for(int i = 1; i <= n; i = i+1){//円の数が7になるまで繰り返し処理をする
  ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する

for文を用いることで、連続して同じ円を表示しています。nの値をいじることで、円の数を好きに増やすことができるので、複数の図形など描きたいときに非常に楽になります。また、円の引数に繰り返し処理で使っているiを使うことで描画位置をずらしたり、大きさを変えていけるので値を色々といじってみると面白いです。

while文の活用

上記のプログラムはwhile文を用いても、同じように表示させることができます。書き換えた場合のコードは以下になります。

int i = 1; //繰り返し処理の基準値
int n = 7; //並べる円の数

void setup()
{
    size(1000, 1000); 
    background(255); //背景色を白にする
    noStroke(); //図形の枠線を描かない
    fill(255,0,0); //図形の塗りつぶしを赤色にする
}

void draw()
{
  while(i <= 7){//円の数が7になるまで繰り返し処理をする
  ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
  i += 1;
  }
}

図形を動かす

まずは、以下のコードを実行してみましょう。

int x = 0; //円のx座標を保存する変数

void setup()
{
    size(1000,1000); //画面サイズを1000x1000にする
    background(255); //背景色を白色にする
    rectMode(CENTER); //四角形の描画モードを変更
}

void draw()
{
    noStroke(); //枠線なし
    fill(255,0,0); //塗りつぶし色を赤に設定
    rect(x, height/2, 200, 200);
    x = x + 1; //x座標を1増やす
}

これを実行すると、このような画面になると思います。

四角形が右にずっと描画されてしまうと思います。さらに、四角形の軌跡が残ってしまいます。なぜかというと、draw関数に書かれた処理は毎フレーム(一定の秒数毎)実行されてしまうので、上書きされてしまうのです。なので、描画するごとに背景を再度描画すれば、軌跡が残りません。以下のコードをdraw関数内に加えてみましょう。

background(255); //背景色を白色にする

そうすると、このようになります。

しかし、プログラムは実行し続けているので、四角形は永遠に右に描画し続けてしまいます。そこで、条件処理を付け加えることで、より四角形の動きをコントロールしましょう。

if文の活用

先ほどのコードに付け加え、以下のようにしてみましょう。

int x = 0; //円のx座標を保存する変数

void setup()
{
    size(1000,1000); //画面サイズを1000x1000にする
    background(255); //背景色を白色にする
    rectMode(CENTER); //四角形の描画モードを変更
}

void draw()
{
    background(255); //背景色を白色にする
    noStroke(); //枠線なし
    fill(255,0,0); //塗りつぶし色を赤に設定
    rect(x, height/2, 200, 200);
    x = x + 1; //x座標を1増やす
    if(x-100 > width)//四角形のx座標が画面サイズより大きくなったら
    { 
        x = 0; //x座標を0にする(四角形は左端に戻る)
    }
}

このif文が重要になります。

  if(x-100 > width)//四角形のx座標が画面サイズより大きくなったら
    { 
        x = 0; //x座標を0にする(四角形は左端に戻る)
    }

四角形左辺のx座標を画面のサイズと比較して、その値を超えたら、四角形のx座標を0に戻すことで、画面左端に再度描画されるということになります。

マウスに追従する

今までは、キャンバス上に描くだけでしたが、マウスの動きに合わせて動く円を作成したいと思います。プロセシングでは、マウスのクリックや位置を検出してくれる機能があるので、それを使います。まずはコードをコピーしてみましょう。

void setup() {
  size(1000, 1000);
  background(255); //背景色を白色にする
}

void draw() {
  background(255); //背景色を白色にする
  noStroke(); //枠線なし
  fill(255,0,0); //塗りつぶし色を赤に設定
  ellipse(mouseX, mouseY, 200, 200);
}

円の引数にmouseX、mouseYを設定することで描画される位置が、マウスに追従するようになります。

また、マウスが押されているときのみ表示するなら、こう書き換えます。

if (mousePressed == true){
  ellipse(mouseX, mouseY, 200, 200);
  }

if文を使い、条件を変え描画しています。mousePressedというマウスボタンを押しているときは検出します。それ以外にも使える関数があるので、以下にまとめて記載しておきます。

  • mousePressed…マウスボタンが押されたとき
  • mouseReleased…マウスボタンを離したとき
  • keyPressed…キーを押したとき(キーを指定することができる)

キーの処理をするときは以下のようにコードを書きます。

if ((keyPressed == true) && (key == 'a')){
}

ランダムを利用する

プロセシングでは、random関数を利用することで無作為に図形を描いたり、サイコロのように数字を出したりすることができます。以下のように記述するだけで利用できます。

random(最小値、最大値)

この引数のなかに例えば、最小値に0、最大値に100と入れれば、0~100未満の中から数字が無作為に選ばれます。(最大値のみの記述でもOK)これを利用するとこのようにコードが書けます。

int n = 7; //並べる円の数

void setup()
{
    size(1000, 1000); 
    background(255); //背景色を白にする
    noStroke(); //図形の枠線を描かない
}

void draw()
{
  for(int i = 1; i <= n; i = i+1){//円の数が7になるまで繰り返し処理をする
    fill(random(255),random(255),random(255)); //図形の塗りつぶしをランダムにする
    ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
    
    if(i==7){
    noLoop(); //円を7つ書き終えたときにdraw()の繰り返し処理を止める
    }
  }
}

図形の塗りつぶしをランダム関数にすることで、描画する図形の色を変えています。

引数として値が取得できるものには、何でも使用できるので、図形の大きさ、位置、色等、様々なことに応用できます。自分で変数を設定し、ランダムな値を代入するには、以下のようにfloat型で指定する必要があります。

float color = random(100); 

実践的な条件分岐

図形を動かす時にも使ったようにif文を使えば、random関数で得た値でも、より細かく処理できるようになります。例えば以下のコードです。

int n = 7; //並べる図形の数
int m = 0; //図形を決める番号

void setup()
{
    size(1000, 1000); 
    background(255); //背景色を白にする
    noStroke(); //図形の枠線を描かない
    rectMode(CENTER);//四角形の描画モード変更
}

void drawTriangle(int x, int y, int r) {  //三角形を作る関数
  pushMatrix();
  translate(x, y);  // 中心となる座標
  rotate(radians(-90));

  // 円を均等に3分割する点を結び、三角形をつくる
  beginShape();
  for (int i = 0; i < 3; i++) {
    vertex(r*cos(radians(360*i/3)), r*sin(radians(360*i/3)));
  }
  endShape(CLOSE);

  popMatrix();
}

void draw()
{
  for(int i = 1; i <= n; i = i+1){//図形の数が7になるまで繰り返し処理をする
    fill(random(255),random(255),random(255)); //図形の塗りつぶしをランダムにする
    
    m = int(random(1,4));
    if(m == 1){
    ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
    }
    if(m == 2){
    rect(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
    }
    if(m == 3){
    drawTriangle(100+i*100,height/2,50);//x軸を100ずつ増加させながら描画する
    }
    
    if(i==7){
    noLoop(); //図形を7つ書き終えたときにdraw()の繰り返し処理を止める
    }
  }
}

プログラム内では、ランダムに選ばれた数によって描画する図形を分けています。1が出たら円、2が出たら四角、3が出たら、三角と定めています。実行すると、以下のようになります。

case文の活用

上のコードはcase文を用いても記述することができます。今回は3種類を場合分けしていますが、沢山条件を分けたいときには、こちらの方が使いやすい時もあります。以下がそのコードです。

int n = 7; //並べる図形の数
int m = 0; //図形を決める番号

void setup()
{
    size(1000, 1000); 
    background(255); //背景色を白にする
    noStroke(); //図形の枠線を描かない
    rectMode(CENTER);//四角形の描画モード変更
}

void drawTriangle(int x, int y, int r) {
  pushMatrix();
  translate(x, y);  // 中心となる座標
  rotate(radians(-90));

  // 円を均等に3分割する点を結び、三角形をつくる
  beginShape();
  for (int i = 0; i < 3; i++) {
    vertex(r*cos(radians(360*i/3)), r*sin(radians(360*i/3)));
  }
  endShape(CLOSE);

  popMatrix();
}

void draw()
{
  for(int i = 1; i <= n; i = i+1){//図形の数が7になるまで繰り返し処理をする
    fill(random(255),random(255),random(255)); //図形の塗りつぶしをランダムにする
    
    m = int(random(1,4));
    switch(m){
      case 1:
        ellipse(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
        break;
      case 2:
        rect(100+i*100,height/2,100,100);//x軸を100ずつ増加させながら描画する
        break;
      case 3:
        drawTriangle(100+i*100,height/2,50);//x軸を100ずつ増加させながら描画する
        break;
      default:
      break;
    }
    if(i==7){
    noLoop(); //図形を7つ書き終えたときにdraw()の繰り返し処理を止める
    }
  }
}