Processing(色の切り替え)

processingで色を順番に変えていく方法をまとめておきます。

図形の描画などにも応用ができますが、今回は背景を変えていくことを例に書いていきます。

変数を使って色を変える

クリックするたびに背景色を変えようとしたとき、方法はいくつかありますが、数値の変数を使う場合はこのようなプログラムで変える事ができます。

int colorNumber = 0;

void setup()
{
    size(800, 450);
}

void draw()
{
    //colorNumber変数の内容によって背景色を変える
    if (colorNumber == 0)
    {
        background(100, 150, 250);
    }
    else
    {
        background(100, 250, 150);
    }
}

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算する。
    colorNumber++;
    //colorNumber変数の値が1を超えたら0に戻す
    if (colorNumber > 1)
    {
        colorNumber = 0;
    }
}

マウスをクリックするとcolorNumber変数に値が加算され、drawの中ではその値によりif文で分岐しています。

色を増やす

もし変わる色を増やした場合、このようになります。

int colorNumber = 0;

void setup()
{
    size(800, 450);
}

void draw()
{
    //colorNumber変数の内容によって背景色を変える
    if (colorNumber == 0)
    {
        background(100, 150, 250);
    }
    else if(colorNumber == 1)
    {
        background(100, 250, 150);
    }
    else
    {
        background(250, 150, 100);
    }
}

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算する。
    colorNumber++;
    //colorNumber変数の値が2を超えたら0に戻す
    if (colorNumber > 2)
    {
        colorNumber = 0;
    }
}

drawの中にあるif条件が増え、mouseClikedの中にある条件が1から2に変わっています。

色を増やした場合、変えなければいけないところが複数の場所に散らばっています。特に、いろいろとプログラムを追加していくとプログラムの内容を変えようと思ったときに書き換える場所を探したり、変え忘れて思った通りに動かないということが起きやすくなります。

color型の変数を使う

ここで少し書き方を変えてみます。Processingでは、color型という変数を使うことができるので、はじめにまとめておくことができます。色の指定は、RGBもしくはRGBA、16進数(#FFCC00)で設定できます。

int colorNumber = 0;
color color1 = color(100, 150, 250);
color color2 = color(100, 250, 150);
color color3 = color(250, 150, 100);

void setup()
{
    size(800, 450);
}

void draw()
{
    //colorNumber変数の内容によって背景色を変える
    if (colorNumber == 0)
    {
        background(color1);
    }
    else if(colorNumber == 1)
    {
        background(color2);
    }
    else
    {
        background(color3);
    }
}

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算する。
    colorNumber++;
    //colorNumber変数の値が2を超えたら0に戻す
    if (colorNumber > 2)
    {
        colorNumber = 0;
    }
}

コードが見やすくなりましたが、色が増えたときに変えなければいけない場所は変わりません。

配列を使う

そこで、色を配列に入れて使う方法で書いてみます。配列は、簡単に説明すると変数がまとまった入れ物です。

int colorNumber = 0;
color[] colorPallet = {color(100, 150, 250),
                       color(100, 250, 150),
                       color(250, 150, 100)};

void setup()
{
    size(800, 450);
}

void draw()
{
    //colorPallet配列のcolorNumberの色を設定する
    background(colorPallet[colorNumber]);
    
}

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算する。
    colorNumber++;
    //colorNumberがcolorPalletの配列数を超えたら0に戻す
    if (colorNumber > colorPallet.length - 1)
    {
        colorNumber = 0;
    }
}

注意点として、配列の番号は0から始まりますが、lengthで戻る値は配列の最大番号ではなく配列の数なので1を引く必要があります。 (3個の配列であれば、配列の番号は0~2番ですが、lengthで戻る値は3です)

このプログラムの場合、色を追加するには一番上の配列に設定するだけで済みます。lengthで上限が自動的に変わるので、数値を変える必要がありません。

int colorNumber = 0;
color[] colorPallet = {color(100, 150, 250),
                       color(100, 250, 150),
                       color(250, 150, 100),
                       color(250, 250, 100),
                       color(100, 250, 250),
                       };

void setup()
{
    size(800, 450);
}

void draw()
{
    //colorPallet配列のcolorNumberの色を設定する
    background(colorPallet[colorNumber]);
    
}

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算する。
    colorNumber++;
    //colorNumberがcolorPalletの配列数を超えたら0に戻す
    if (colorNumber > colorPallet.length - 1)
    {
        colorNumber = 0;
    }
}

if文の部分を短くする

クリックしたときの変数加算と0に戻すif文を短くする方法を考えましたが、わかりづらくなっていきました。

前置インクリメントを使う
void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算し、
    //colorNumberがcolorPalletの配列数を超えたら0に戻す
    if (++colorNumber > colorPallet.length - 1)
    {
        colorNumber = 0;
    }
}

前置インクリメント(変数の前に++)を条件式の中に書くと、変数に1が加算された後ifの判定がされます。後置インクリメントも使用できますが、その場合は条件を変える必要があります。 if (colorNumber++ > colorPallet.length - 2)

if文の中括弧省略

さらにif文では、中括弧{ }を省略できます。

void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算し、
    //colorNumberがcolorPalletの配列数を超えたら0に戻す
    if (++colorNumber > colorPallet.length - 1)  colorNumber = 0;
}

中括弧を省略できるのは、実行される処理が1文で終わる場合だけです。改行も可能ですが、if文の中と外の違いがわかりづらくなります。

そのほかの方法でも1行に収めることができます。

条件演算子を使う
void mouseClicked()
{
    //マウスがクリックされたらcolorNumberの値に1を加算し、
    //colorNumberがcolorPalletの配列数を超えたら0に戻す
    colorNumber = colorNumber >= colorPallet.length - 1 ? 0 : colorNumber + 1;
}

変数 = 条件 ? Trueの時の代入値 : Falseの時の代入値
という書き方ですが、さらにわかりづらくなっています。

プログラムは、簡単に短く書くよりも、見やすくわかりやすく、書き換えがしやすくなるように心がけたいと思います。