ウェブバーチャル花火してみた

こんにちは。しゅん(@MxShun) です。

今回は、グラフィックスライブラリを利用し開発した「ウェブバーチャル花火」を紹介します。

まずは自己紹介

記事初投稿なので、まずは自己紹介をさせてください。

今年新卒入社をしました、三浦駿と申します。ASKULウェブサイトの保守・運用を担当しています。

学生時代は、AR技術を用いたギター演奏学習支援システムの開発をしていました。好きな言語はJavaScriptです。これからよろしくお願いします!

github.com

いきさつ

さて、先日同期の友人が「今年は夏祭りが軒並み中止となっていて悲しい」という話をしていました。

イベントリスト (Walkerplusより)

うん。悲しい。なにより、夏祭りといえば! の花火を見ていないことで夏を感じられていない。

「じゃあ、バーチャルな花火を作っちゃえば夏を感じられて、技術も学べて一石二鳥なのでは?

そう考えたのが、今回ウェブバーチャル花火を開発しようと思ったいきさつです。

ウェブバーチャル花火

早速ですが成果物と使っている技術の紹介です。

成果物

デモ

こちら(GitHub Pagesリンク)から実際にご覧いただけます。(音声が流れますのでご注意ください*1 )

夏ですね。夏を感じられます。

ランダムなタイミングで打ち上げられた、ランダムな色・大きさの花火が、ランダムな高さで爆発します。

また、画面をクリックするとその回数だけ花火を打ち上げることもできます。ぜひ試してみてください!

使っている技術

今回のウェブバーチャル花火では「p5.js」というOSSのグラフィックスライブラリを利用しています。

p5js.org

OpenGLやDirectX、Three.jsなど数あるグラフィックスライブラリのなかで、なぜp5.jsか

第1に、ハードウェアに依存せずクロスブラウザなライブラリなのでユーザの導入コストが少ないこと。

第2に、

p5.js is an interpretation of Processing for today’s web.

(p5.js homeより)

とあるように、ProcessingをJavaScriptに移植したもので、私自身コンピュータグラフィックスとしてProcessingを触ってみたかったこと。

以上2点から、p5.jsの採用がウェブバーチャル花火実現のベストプラクティスだと考えました。

p5.js

では、公式のチュートリアルに基づいてp5.jsの導入をやってみます。

"Your First Sketch"

p5.jsでは独自IDEが用意されています。実際に開いてみましょう。

サンプル1

初期状態でサンプルプログラムが記述されています。

構文はProcessingに則る形で、それぞれ以下を定義します。

  • setup 初期フレームに一度だけ実行される処理
  • draw  毎フレーム実行される処理

具体的には400×400pxのキャンバス(ウィンドウ)に、RGBがすべて220(つまり、#DCDCDC)の背景色を指定して描画する処理が記述してあります。

実際に動かすと、Previewに灰色の正方形が描画されていることが確認できますね。

"Skip Ahead to a Sketch That's More Exciting"

続いて元々の処理を削除し、次の処理を記述してみてください。

function setup() {
  createCanvas(400, 400);
}

function draw() {
  if (mouseIsPressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 80, 80);
}

実際に動作させます。

サンプル2

このようにマウスの動きに合わせて円を描きます。具体的にはマウスをクリックする度に白・黒色を切り替え、80×80pxの円をマウスのx,y座標上に描画する処理が記述してあります。

よりインタラクティブで自由度が高い動作になりましたね。

実際の処理

最後に、バーチャル花火の実際の処理を簡単に説明します。

function setup() {
  // ブラウザのウィンドウサイズに合わせてキャンバスサイズを調整
  createCanvas(document.documentElement.clientWidth, document.documentElement.clientHeight).position(0, 0);
  // BGMのループ再生
  bgm.loop();
  // 星の描画準備
  preStars();
}

function draw() {
  // 背景の描画処理
  drawBackground();
  // 星の描画処理
  drawStars();

  // 1/3秒ごとに1/2の確立で花火を打ち上げる
  if (frameCount % 20 == 0 && random() * 2 > 1) {
    // 花火クラス要素追加(第1引数:x座標, 第2引数:y座標, 第3引数:横方向速度, 第4引数:縦方向速度, 第5引数:重力加速度)
    fireworks.push(new Firework(random(width), height, 0, random(10, 30), 0.98));
  }

  for (const fw of fireworks) {
    // 爆発した花火を処理対象から外す
    if (fw.getType === 2 || fw.getFrame > 30000) {
      fireworks = fireworks.filter((n) => n !== fw);
      continue;
    }
    // 花火の描画処理
    fw.fire();
  }
}

フレーム毎に背景・星・花火の描画処理をするほか、20フレーム(つまり、1/3秒)ごとに1/2の確立で新規花火打ち上げを判定する処理を動かしています。

各花火の状態を要素typeで管理し、その値によってフレームごとに処理fireで打ち上げ・爆発の描画を出しわけています。

詳細な処理の中身はバーチャル花火のGitHubリポジトリを参照してください。

github.com

補足

p5.js本体、それから今回のウェブバーチャル花火でも利用したサウンドライブラリp5.sound.jsの導入はCDNが楽ちんです。

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>

なお、

To run this example locally, you will need the p5.sound library a sound file, and a running local server.

(p5.js sample - Load and Play Soundより)

とあるように、p5.sound.js動作にはサーバが必要である点に留意してください。

おわりに

グラフィックスライブラリp5.jsを利用し開発した「ウェブバーチャル花火」を紹介しました。

改めて技術ドリブンではなく課題ドリブンな開発の意義を再確認できました。

告知

最後に告知です。

現在、新卒エンジニアメンバーで新人研修の活動報告と学び共有の記事を絶賛執筆中です。近いうちに公開される(はず)なので、ぜひ次回も読んでいただけると嬉しいです。

また、ヤフーさん主催イベント「Yahoo! JAPAN Internal Hack Day 17」参加記事と同期みわすけの前記事はすでにご覧いただけたましたでしょうか? まだの方は合わせて読んでいただけると嬉しいです。

最後までご覧いただきありがとうございました!

techblog.yahoo.co.jp

*1:花火の音声として、無料効果音で遊ぼう!さんのフリー音源を使用させていただいています。

ASKUL Engineering BLOG

2020 © ASKUL Corporation. All rights reserved.