LogoMark.png

Processing/Sample の変更点


#author("2020-06-15T20:15:53+09:00","default:inoue.ko","inoue.ko")
*Processing
Sample Program
~

Processing には大きく2つのプログラミングスタイルがあります。
-1)順に処理を実行し、最後でストップする(静止画用)
-2)メインループを持ち、停止されるまで処理を繰り返す(動画用)
それぞれ、簡単な例を紹介しましょう。
もし、すでに Processing の環境が準備されている場合は、
このページのソースをコピー&ペーストしてお試し下さい。
~

***静止画 プログラム例
 size(512, 512);
 colorMode(HSB, 100);
 background(0, 0, 99);
 noStroke();
 rectMode(CENTER);
 
 for( int y = 16 ; y < 512 ; y += 32 ){
     for( int x = 16 ; x < 512 ; x += 32 ){
         fill( random(40,70), 50, 90);
         rect(x, y, 24, 24);
     }
 } 
~

#ref(processing_01.jpg,right,around)
たったこれだけです。
これにコメントを付けて説明すると、
以下のようになります。

size(512,512);    // 画面サイズの指定
colorMode(HSB,100);    // カラーモードの指定 
background(0,0,99);    // 背景色 赤・彩度0・明度99
noStroke();    // 線なし(図形描画時)
rectMode(CENTER);    //  中心座標基準(長方形描画時)

for( int y = 16 ; y < 512 ; y += 32 ){    // 縦方向の繰り返し
 for( int x = 16 ; x < 512 ; x += 32 ){    // 横方向の繰り返し
  fill(random(40,70),50,90);    // 色指定(ランダム,彩度50,明度90)
  rect(x,y,24,24);    // 矩形描画(中心 x,y  , サイズ24*24)
 }
}
~


***動画 プログラム例
 float x,y;  // ボールの位置
 float vx,vy;  // 速度(1フレームごとの移動量)
 int radius = 10;  // ボールの半径
 
 void setup(){
     size(512,512);
     frameRate(60);
     x = width / 2;
     y = height / 4;
     vx = 3;
     vy = 5;
 }
 
 void draw(){   //  メインループ
     fill(255);
     rect(0,0,width,height);
     x = x+vx;
     y = y+vy;
     if( x<radius || width - radius<x ) vx = -vx;
     if( y<radius || height - radius<y ) vy = -vy;
     fill(0);
     ellipse(x,y,radius*2,radius*2);  
 }
~

#ref(processing_02.jpg,right,around)
とりあえずこれで、丸い図形が画面上を動きます。

void setup() は、初期設定
void draw() は、メインループ

このプログラムの以下の部分は、
アニメーションの基本的なテクニックです。

 rect(0,0,width,height); ← 画面全体の塗りつぶし(消去)
 ellipse(x,y,radius*2,radius*2); ← 円の描画

この「全部消す」と「(少し位置を変えて)描く」をセットにして、
繰り返すことで、アニメーションが実現する・・という仕組みです。

 x = x+vx;   (  y = y+vy; も同じ役割 )

これは、座標(位置)の移動を意味しています。
= 記号は、等しいという意味ではなく、
「右辺の計算結果を左辺の変数に代入しなさい」という意味です。
つまり、現在の x 座標に vx だけ加えて、それを新たな x 座標とする・・
ということを意味していて、
これを繰り返すことで、アニメーションが実現します。

 if( x<radius || width - radius<x ) vx = -vx;
 
この行は、壁面での跳ね返りを実現します。
xの値、すなわち画面内でのx座標が、左端よりも左、
あるいは右端よりも右にはみ出すようであれば、移動方向を逆転する・・
という動作を書いたものです。
たとえば 今 vx が+の値で、x= x+vx で右(+向き)に移動しているとき、
右の壁を越えようとした時点で、 vx を-の値にすれば、それ以後は、
x=x+vxでx の値は減り続ける・・つまり左へ動くことを意味します。

この壁への当たり・反転処理は、上下方向についても必要ですので、
y について同様の1行が必要です。

~

***Interactive   
マウスを用いたインタラクティブなプログラムの例

 int cnt=0;
 
 void setup(){
     size(512,512);
     colorMode(HSB,100);
     noStroke();
     frameRate(30);
 }
 
 void draw(){
     fill(99,10);
     // 白10%
     rect(0,0,width,height);
     // 全画面塗りつぶし
     fill((cnt++)%100,50,99);
     // 順次変化する色相で
     ellipse(mouseX,mouseY,64,64);
     // マウスの位置に円を描く
 } 
~

#ref(processing_03.jpg,right,around)
これだけで、マウスに追随して
円が描かれるものができます。

void setup() は、初期設定
void draw() は、メインループ

塗りつぶしの色指定の部分について補足します。
cnt++  :  これは cnt(カウント)を1つ進める・・意味します。
A %100 : これは A の値を100で割った余り・・を意味します
つまり、ループの都度、1,2,3,4・・・・と値が変化して、
99まで進むと、次は0に戻ってまた繰り返すことになります。
~

***キーボード入力を用いたインタラクティブなプログラムの例
 PFont font;
 
 void setup(){
     size(512,512);
     colorMode(HSB,100);
     frameRate(30);
     font = createFont("Arial",50);
     textFont(font);
     textAlign(CENTER);
 }
 
 void draw(){
     fill(99,10);
     rect(0,0,width,height);
 }
 
 void keyPressed(){
     fill(random(100),99,99);
     text(key,random(width),random(height));
 }
~

#ref(processing_04.jpg,right,around)
キーボードから入力した文字が
ランダムな位置に表示されます。
英数入力モードで操作してください。

ここで重要なのは、
void keyPressed() です。
ここには、「キーが押されたときにやるべきこと」 が書かれています。
この場合は、色相をランダムに決めて、
押されたキーの文字をランダムな位置に出力します。

//''loadFont()の使い方''
//Processing で使うフォントを作成するには・・
//-ツールメニューで Create Font... を選択
//-使いたいフォントを選択(あなたのPC内にあるものが候補)
//-以上で、Processing で要求される vlw形式のデータが作成され、
//sketch の data ディレクトリに追加されます。 
//-あとは、上のサンプルのように書けば表示されます。
~

***応用サンプル
マウスクリックと、キーボードの[r],[g],[b],[0]に反応するプログラムの例です。
[r],[g],[b]は、ボール色のRGB各値を増加、[0]は黒に戻します。
以下のソースをProcessingの編集画面にコピー&ペーストしてお試し下さい。

 // 変数の宣言 ////////////////////////////////
 float[] x = new float[10] , y = new float[10];
 float[] vx= new float[10] , vy= new float[10];
 int[] radius = new int[10];
 int[] R = new int[10], G = new int[10], B = new int[10];
 int i;
 
 // 初期設定 ////////////////////////////////
 void setup(){
     size(512,512);
     colorMode(RGB,256);
     noStroke();
     frameRate(60);
     // 配列変数の初期化
     for(i=0;i<10;i++){
          x[i] = width / random(2,5);
          y[i] = height / random(2,5);
          vx[i] = random(-5,5);
          vy[i] = random(-5,5);
          radius[i]= (int)random(10,50);
          R[i] = 0;
          G[i] = 0;
          B[i] = 0;
     }
 }
 
 // メイン ////////////////////////////////
 void draw(){
     fill(255,255,255);
     rect(0,0,width,height);
     for(i=0;i<10;i++) {
          x[i] = x[i]+vx[i];
          y[i] = y[i]+vy[i];
          if( x[i]<radius[i] || width - radius[i]<x[i] ) vx[i] = -vx[i];
          if( y[i]<radius[i] || height - radius[i]<y[i] ) vy[i] = -vy[i];
          fill(R[i],G[i],B[i]);
          ellipse(x[i],y[i],radius[i]*2,radius[i]*2);
     }
 }
 
 // マウスコールバック ////////////////////////////////
 void mousePressed() {
     for(i=0;i<10;i++) {
          x[i] = mouseX;
          y[i] = mouseY;
     }
 }
 
 // キーボードコールバック ////////////////////////////////
 void keyPressed(){
     for(i=0;i<10;i++) {
          switch(key){
               case 'r':
                    R[i] += 32; if(R[i]>255) R[i] = 255;
                    break;
               case 'g':
                    G[i] += 32; if(G[i]>255) G[i] = 255;
                    break;  
               case 'b':
                    B[i] += 32; if(B[i]>255) B[i] = 255;
                    break;
               case '0':
                    R[i] = 0; G[i] = 0; B[i] = 0;
                    break;
               default:
                    break;  
          }
     }
 }
~
~



**付記:
3つの図形に、それぞれ異なる動きを与えるサンプル
&color(red){作り変えて試すためのサンプルなので、使っていない変数もあります。};
#image(test.jpg,right,30%)
-円は斜めに動いて、エリア内を反射します。
-矩形は左右に反射します。
-三角形は上下に反射します。

 int x1, y1, r, vx1, vy1;  // ellipse
 int x2, y2, s, vx2, vy2;  // rect
 int x3, y3, l, vx3, vy3;  // triangle
 
 void setup(){
    size(400,400);
    x1=50; y1=100; r=25; vx1=2; vy1=2; 
    x2=0; y2=175; s=60; vx2=2; vy2=0;
    x3=200; y3=0; l=20; vx3=0; vy3=2;
    colorMode( RGB, 256 );
    noStroke();
    smooth();
 }
 
 void draw(){
   
    // Erase
    fill(255);
    rect(0,0,width,height);
     
    // ellipse Bouncing
    x1 = x1 + vx1;
    y1 = y1 + vy1;
    if( x1 < r || width-r < x1 ) vx1 = -vx1;
    if( y1 < r || height-r < y1 ) vy1 = -vy1;
    fill(255,0,0);
    ellipse(x1, y1, r*2, r*2); 
      
    // rectangle Bouncing horizontal
    x2 = x2 + vx2;
    if( x2 < 0 || width-s < x2 ) vx2 = -vx2;
    fill(0,255,0);
    rect(x2,y2,s,s); 
     
    // triangle Bouncing vertical
    y3 = y3 + vy3;
    if( y3 < 0|| height-l*2 < y3 ) vy3 = -vy3;
    fill(0,0,255);
    triangle(x3, y3, x3+l, y3+l*2, x3-l, y3+l*2); 
     
 }

~
~