Kevin's Data Analytics Blog

データサイエンティスト、AIエンジニアを目指す方に向けて情報発信していきます。

Processingで元気玉風のデジタル動画を作成

今回は、Processingというプログラミング言語を初めて使用してみました。Processingは、Javaを単純化してグラフィック機能に特化した言語と言われています。複雑なセットアップ作業も不要であるため、プログラミング初心者でも比較的に簡単に始められます。

作成した動画

元気玉風の球体が徐々に大きくなっていくイメージの動画を作成しました。
youtu.be

Processingの準備

実行ファイルのダウンロード

「processing programming」と検索し、公式サイトへアクセスします。

ダウンロードページから、自身の環境に合った実行ファイルをダウンロードします。※2022.07時点でversion 4.0はまだベータ版(試用版)なので、私は正式版の3.54を取得しました。

Processingの起動

Windows版の実行ファイルはzipファイルになっていますので、適当なフォルダーに展開します。※例:「C:\Program Files\processing-3.5.4-windows64\processing-3.5.4」

processing.exeが実行ファイルなので、これをクリックして起動します。processing.exeのショートカットをデスクトップ等に作成すると便利です。

エディタが表示されます。Processingの起動が出来ました。

エディタのフォント設定

「ファイル」→「設定」をクリックします。

日本語対応フォントへの変更

「エディタとコンソールのフォント」から、「MSゴシック」など日本語入力が可能なフォントに変更します。

フォントサイズ

エディタのフォントサイズはデフォルトだと「12」で小さいため、「18」くらいに変更することをお勧めします。

これで、Processingを使う準備が出来ました。他のプログラミング言語と比べて、とても簡単です。

サンプルコードの実行

エディタ部分にコードを書いて、実行ボタンを押します。

別ウィンドウが起動され、プログラムの実行結果が表示されます。

元気玉風アニメーションのコード

では、元気玉風のアニメーションを作成してみましょう。以下のコードをコピー&ペーストして実行すれば、冒頭で紹介したアニメーションが起動されると思います。

// 元気が溜まる動画

// 変数宣言
int t = 1;  // 時間管理
int cnt = 0;  //ループカウンタ
int org_ball_num = 60;  // 小エネルギー玉の個数(初期値)
int cur_ball_num = org_ball_num;  // 小エネルギー玉の個数(最新値)
int param1 = 50;  // 大エネルギー玉の外側オーラの幅
int param2 = 700;  // 小エネルギー玉の生成が止まるタイミング
int param3 = 750;  // 各パラーメータのリセットタイミング
float power_size = 5;  // 小エネルギー玉のサイズ
float range = 10;  // 小エネルギー玉が消える範囲
float[] x = new float[cur_ball_num];  // 小エネルギー玉のx座標のリスト
float[] y = new float[cur_ball_num];  // 小エネルギー玉のy座標のリスト
float[] dist_x = new float[cur_ball_num];  // 画面中心からのx方向の距離
float[] dist_y = new float[cur_ball_num];  // 画面中心からのy方向の距離
// 画面タイプを指定 Default:正方形、SP:縦長、PC:横長
String mode = "PC"; // "Default" or "SP" or "PC"

// 初期化 最初に1回だけ実行される
void setup(){
  // フレームレート(1秒ごとに表示されるフレーム数)を指定
  frameRate(30);
  
  // 画面サイズを指定
  // ※size関数には変数は使えないため、画面タイプに合わせて手動修正
  //size(1000, 1000, P3D); // Default
  //size(540, 980, P3D); // SP
  size(1920, 1080, P3D); // PC

  // 小エネルギー玉の位置を初期化
  for(int i = 0; i < cur_ball_num; i++){
    x[i] = random(width);
    y[i] = random(height);
  }

  // 画像タイプごとにパラメータを調整
  if (mode == "SP"){
    param1 = 40;
    param2 = 680;
    param3 = 740;
  }
  else if (mode == "PC"){
    param1 = 50;
    param2 = 750;
    param3 = 800;
  }
  
  // tを各パラーメータのリセットタイミングの直前に設定
  t = param3 - 1;
}

// 図形を描画 ループして実行されるためアニメーションになる
void draw(){
  
  // 小エネルギー玉を描画
  for(int i = 0; i < cur_ball_num; i++){
    if (cnt == 0) {break;}
    // 枠線なし
    noStroke();
    
    // 色を指定
    fill(190, 248, 253, 255);
    
    // 位置とサイズを指定
    ellipse(x[i], y[i], power_size, power_size);
    
    // 画面の中心からの距離を取得(x軸、y軸)
    dist_x[i] = max(x[i] - width/2, width/2 - x[i]);
    dist_y[i] = max(y[i] - height/2, height/2 - y[i]);

    // 中央付近に入ったら、位置を初期化する
    if (dist_x[i] + dist_y[i] <= range*5){
      x[i] = random(width);
      y[i] = random(height);
    }

    // x軸方向の移動
    if (x[i] > width/2 + range){
      // 真ん中+rangeよりも右側にいる場合は、x座標の値を減らす(左に移動)
      x[i] -= (x[i] - width/2 + range)/50;
    }
    else if (x[i] < width/2 - range){
      // 真ん中-rangeよりも左側にいる場合は、x座標の値を増やす(右に移動)
      x[i] += (width/2 - range - x[i])/50;
    }
    else {
      // それ以外(真ん中付近)にいる場合は、真ん中に移動
      x[i] = width/2;
    }
    
    // y軸方向の移動
    if (y[i] > height/2+range){
      // 真ん中+rangeよりも下側にいる場合は、y座標の値を減らす(上に移動)
      y[i] -= (y[i]-height/2+range)/50;
    }
    else if (y[i] < height/2-range){
      // 真ん中-rangeよりも上側にいる場合は、y座標の値を増やす(下に移動)
      y[i] += (height/2-range-y[i])/50;
    }
    else {
      // それ以外(真ん中付近)にいる場合は、真ん中に移動
      y[i]=height/2;
    }
  }
  
  // 時間の経過とともに、小エネルギー玉の表示を変えていく
  power_size += 0.04;  // サイズを大きくする
  range += 0.015;  // リセットするレンジを広くする
  cur_ball_num = org_ball_num - floor(org_ball_num * t/param2);  //表示数を減らす
  
  // 以下、大エネルギー玉を描画
  
  // 原点を中心に移動
  translate(width/2, height/2, 50);
  
  // 1層目 外側のエネルギー
  // 色埋めしない
  noFill();
  // 枠を表示 色を時間経過とともに、変化させていく
  stroke((t + 600)/2 - 450,(t + 600)/2,((t + 600)/2)*9,20);
  // 半径t+param1の球体を表示
  sphere(t + param1);
  
  // 2層目 内側のエネルギー
  // エネルギーの色を指定
  fill(141,242,253,100);
  // 半径tの球体を表示
  noStroke();
  sphere(t);

  // 3層目 この動画の背景色になる
  fill(0, 0, 0);  // 黒で埋める
  // 2層目よりも一回り小さい半径(t-10)の球体を表示する
  if (t > param2){
    noStroke();
    sphere(t - 10);
  }
    
  // 一定時間を超えたら、パラメータをリセットする
  if (t > param3){
    t = 0;
    range = 10;
    power_size = 5;
    cur_ball_num = org_ball_num;
    cnt+=1;
  }
  
  // 動画作成用にpngファイルを保存 ※保存時にコメントインする
  //saveFrame("frames/######.png");

  // tをインクリメント
  t+=1;
}

動画ファイルの保存

プログラムの中でsaveFrame関数を実行すると、プログラムを停止するまでの間、コマ送りで画像ファイルが生成されていきます。

saveFrame("frames/######.png");

画像ファイルが出来たら、「ツール」→「ムービーメーカー」から、画像ファイルの格納フォルダを指定し、「動画を作成」をクリックします。

作成された動画は「.mov」という拡張子のファイルで、基本的にWindowsでは再生できない形式となります。
MOVで保存した後で、mp4などWindowsで再生可能な形式に変換します。(変換ソフトウェアはたくさん公開されており、難しくありませんのでここでは割愛します。)

これで、アニメーション動画の完成です。

まとめ

Processingを使ってアニメーション動画を作成する方法を紹介しました。
Processingは、実行ファイルを起動するだけで使用でき(インストール・セットアップ作業が不要)、また、図形を描画するための関数が用意されており、短い行数でプログラムが書けます。そのため、プログラミング初心者でも簡単に始められると感じました。
また、Processingのダウンロードからサンプルコードの実行まで、実際に操作している様子を動画にまとめました。もし記事の中で不明点があれば、こちらもご確認ください。
youtu.be


本記事が皆様のお役に立てば幸いです。
最後まで読んでいただきありがとうございました!