Processing入門再び/LOSの起動画面

みなさん、おはようございます。bashプログラマの @ma2saka です。

[Livesense Advent Calendar 2016 その３](http://qiita.com/advent-calendar/2016/livesense_3)の8日目を担当します。8日目とはつまり9日目の朝10時までということです。若い頃、会社で教わりました。うすうすおかしいとは思っているんですが、どこが間違っているのかどうも確信が持てません。

## はじめに

子供の頃、プログラマは黒い画面に向かってばーっと緑色の文字を打ち込んでいたんですよね。そういうイメージだったんです。ハッカーは初めて乗るモビルスーツのOSが遅いからと言って書き換えたりします。エリートはPHPを書きます。

そして、「本物の」ソフトウェアは、以下のようなビジュアルで[^1]動作するものだと思っていました。



![Untitled2.gif](https://qiita-image-store.s3.amazonaws.com/0/17911/4cf51b23-862e-f065-49de-2599c0b294f6.gif "Untitled2.gif")

むしろUIにプログラミングが必要と思っていなかったというのが正解でしょうか。プログラムの動作は何か自動的に可視化されるものだと。プログラマが目的のプログラムを書き上げると、それがコンピュータの上で実行される過程でこのような可視化が自然と成されるのだと。おっと、AWS X-Ray?　そんな流行でクラウドな話はいたしませんよ。

ここでは、子供の頃の自分の問いかけに答えて見ることにしましょう。

そう、プログラマは、こんな感じの「さいばあ」な画面を作れるんだろうか? ということです。
## 道具たち

### Processing 

プロセッシングでスケッチすることに。

- [Processing 3.2.3](https://processing.org)
- iMac (27-inch, Late 2012)

今となってはクラシックな風情のあるスペックの iMac さんです。 


### 色の取得

Macの標準ユーティリティに Digital Color Meter というものがあって、これを利用して動画から色を拾います。

![スクリーンショット 2016-12-08 22.34.56.png](https://qiita-image-store.s3.amazonaws.com/0/17911/fad5e9f0-c125-8c6a-9c9a-1c1f7df8e247.png "スクリーンショット 2016-12-08 22.34.56.png")

### サイズ測定

フリーの PixelWindow を利用しました。

- [PixelWindow](https://itunes.apple.com/jp/app/pixelwindow/id503739894?mt=12)

### Gif化

フリーの LICEcapを利用しました。

- [LICEcap](http://www.cockos.com/licecap/)


## 中心のロゴから作っていく

```java
size(640, 480);

noStroke();

//背景は黒
background(0);

color blue = color(30, 50, 100);

int w = 640;
int h = 480;

fill(blue);
ellipse(w/2, h/2, 150, 150);
stroke(255);
fill(255);

textSize(50);
textAlign(CENTER, CENTER);
text("L.O.S", w/2, h/2 - 14);

pushMatrix();
{
  translate(w/2, h/2);
  textSize(18);
  textAlign(CENTER, CENTER);
  scale(1, 0.5);
  text("SYSTEM VIEW", 0, 0 + 50);
}
popMatrix();
```

こうなる。フォントはちょっと後にしよう。調整し出すとキリがなさそう。

![スクリーンショット 2016-12-08 22.59.42.png](https://qiita-image-store.s3.amazonaws.com/0/17911/b03b68c0-1c8b-3602-6d91-fda791296135.png "スクリーンショット 2016-12-08 22.59.42.png")

この時点で、なんかすごく地味な仕事な気がしてきたが、粛々と作る。

## 最初に「それっぽい」画面効果を作る

動きがあるとテンションがあがるので、上から下まで動くモアレの縞を最初に作っておこう。

```java
  // サイバーノイズ
  fill(0,0,3,100);
  noStroke();
  rect(0, cyber_noise_position, width, 200);

  cyber_noise_position += 2;
  if(cyber_noise_position > height){
    cyber_noise_position = -200; 
  }
```

特に理由はないが、わかりやすくサイバーノイズとした。

走査線っぽいのも重ねよう。

```
  // 走査線らしきもの
  stroke(0, 150);
  strokeWeight(1);
  for (int i = 1; i< height; i+=3) {
    line(0, i, width, i);
  }
```

## 円形のプログレスバー

最初 `ellipse` を書いてマスクして・・・って考えていたんだけど、なんのことはない、`arc`で円弧を描き、`strokeCap`で線の端をまっすぐにして、あとはストロークの色をちゃんと指定してあげるだけでいいですね。

パーリンノイズを用いてランダムにそれらしくグラフを動かすことにしました。

```
  pushMatrix();
  {
    translate(w/2, h/2);
    rotate(PI/2);
    noFill();
    strokeCap(1);

    //バー1
    {
      strokeWeight(40);
      int bar1_size = 210;
      stroke(mos);
      arc(0, 0, bar1_size, bar1_size, 0, TWO_PI );

      stroke(sky);
      arc(0, 0, bar1_size, bar1_size, 0, TWO_PI * noise(tick + 1000));

      stroke(green);
      arc(0, 0, bar1_size, bar1_size, 0, TWO_PI * noise(tick));
    }
  }
  popMatrix();
```

ここまででこうなった。

![スクリーンショット 2016-12-08 23.38.39.png](https://qiita-image-store.s3.amazonaws.com/0/17911/fd28953a-bc18-f071-a1a5-84e69b2b6877.png "スクリーンショット 2016-12-08 23.38.39.png")

地味ですが、何も考えることなく進めます。

## 三分割

その外側には三分割されたバーがあります。
これらも同様に増やしていく。

```
  pushMatrix();
  {
    translate(w/2, h/2);
    noFill();
    strokeCap(1);
    strokeWeight(18);

    //バー
    rotate(PI/2);
    for (int i = 1; i< 4; i++) {
      rotate(TWO_PI/3);
      {
        int bar3_size = 310;
        stroke(mos);
        arc(0, 0, bar3_size, bar3_size, 0, TWO_PI/3 - 0.2);

        stroke(green);
        arc(0, 0, bar3_size, bar3_size, 0, TWO_PI/3 * noise(tick + 25*i) - 0.2);
      }
    }
  }
  popMatrix();
```

`noise` は呼び出しごとにランダムになるわけではなく、与えた値に対して一意に決まる値なので利用箇所が違う場合には適当なオフセットを与えることになります。ちなみにマジックナンバー祭りです。なぜ25なのかはわかりません。(パーリンノイズは渡す数字が大きいほど非連続的に動くようになります)


## メッセージボックス

いわゆる吹き出し。普通に矩形を書いて三角の吹き出し口をつければ良い。`rect` 関数は角丸をちゃんと描くことができる。すごい。

```
  // ウインドウ1
  pushMatrix();
  {   
    stroke(window);

    translate(240, 330);

    strokeJoin(ROUND);
    fill(window);
    rect(0, 0, 160, 40);

    fill(yellow);
    textSize(14);
    textAlign(LEFT, CENTER);
    scale(0.8, 1);
    text("* STARTING UP THE SYSTEM", 0, 5);

    fill(window);
    noStroke();
    triangle(100, -25, 80, 0, 120, 0);
  }
  popMatrix();

```

ここにはメッセージボックスからはみ出してデザインされている円弧型のプログレスバーがあるんです。

メッセージボックスには最初STARTING UP THE SYSTEMと表示されていて、円弧型のプログレスバーが100%に到達すると文字列が切り替わるのだが切り替わった後の内容がうまく読めない。とりあえず「WELCOME TO THE L.O.S.」あたりに変えておくことにする。

## いったんここまで

ここまででこんな感じである。まあまあ、それっぽい感じになったのではないだろうか。

![Untitled3.gif](https://qiita-image-store.s3.amazonaws.com/0/17911/043ccc2a-b465-fadc-deea-8b1055fd60ce.gif)


特別な技術とか計算式とかいらないので、根気強くスクラッチアンドビルドを繰り返せば「あんな感じ」のものは作れそうです。

普通に1時過ぎちゃったので、いったんここで投稿しておくことにしましょう。

# おまけ

ここまでのコードを一行も改変せずに Processing.js に食わせたもののキャプチャが以下です。

<img width="374" alt="スクリーンショット 2016-12-09 9.23.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/17911/b3218632-10d8-6834-23d5-dfd44ff9a162.png">

`strokeCap`と`strokeJoin`が効いてないことを除けば悪くない再現度です。驚いたことに、Safariでまずまずの、というかJava版とほとんど遜色ない速度でアニメーションします。

processing.min.js は 220kbくらいのサイズなので、おっと意外に使えるかも...?

# おわりに

さて、この手のものごとは

- 実用性を気にしては負け

ということで、実用性は横に置いてひとつ楽しくいきましょう。

さて、次の9日目は @nbat さんです。よろしくお願いいたします。

[^1]: 画像は機動警察パトレイバー2の冒頭で描かれるオペレーティングシステムLOSの起動画面です。LOSはレイバー・オペレーティング・システムです。