見出し画像

モンスト5周年サイトで制作したブラウザゲームの高速化について

モンスターストライクの5周年の際にキャンペーンサイトを制作しました。今回はその中の1コンテンツであるアーサー獣神化のブラウザゲーム技術的な視点からご紹介いたします。

【目次】
・自己紹介
・作成したブラウザゲーム
・ブラウザゲーム(またはSPA)のこれから
・高速化について
・今回使用した技術(ライブラリなど)
・最後に

■自己紹介

ミクシィでフロントエンドエンジニアをしている吉田守と申します。
ブラウザ上で動作するSPA(シングルページアプリケーション)や3Dプログラミングが得意(好き)です。
今年やった仕事では、ルシファー獣神化スペシャルサイトのメインビジュアル部分の演出制作など、WebGL(three.js)+GLSL+Live2Dで作りました。

プライベートでも個人開発でWebサービスなどを制作(サーバーサイドもやります)しており、現在iOSのARアプリを開発中でございます。

■作成したブラウザゲーム

アーサーといえば聖剣エクスカリバー。エクスカリバーといえば誰にも引き抜けない聖剣。アーサーはその聖剣をたやすく引き抜いたことで有名です。
その"引き抜く"という動作に着目し「アーサーに大根を引き抜かせる音ゲー」の制作が始まりました。(制作期間は3.5週間ほど)

▼以下のURLからプレイできます。

※ページ下部の『「5周年感謝キャンペーン」特設サイトはこちら』をクリックすると閲覧できます。

■ブラウザゲーム(またはSPA)のこれから

HTML5は登場した当初(2010年ごろ)は当時流行っていたFlashと比べても動作が重く、リッチコンテンツを動作させるには実用性に欠けるものでした。

それから10年近くが経ち、WebGLが動作する端末が普及しブラウザや端末の高性能化により、モバイルのブラウザでもネイティブアプリと同じような表現を行うことができるようになりました。
かつて「ブラウザ → スマホネイティブアプリ」とプラットフォームの変換がありましたが、これから「スマホネイティブアプリ → ブラウザ」の変換がおきるかもしれません。(ハイエンドな3Dゲームは除く)

■高速化について

軽い動作でないと幅広いユーザーに楽しんでもらうことができません。高速化で気をつけた点をご紹介いたします。

▼CSSアニメーションを使わず、Canvas内で完結させる。
近年ではCSSアニメーションでもハードウェア・アクセラレーションがオンになり、GPUの恩恵を受けることができます。
しかし、CSS側でGPUのリソースを使ってしまうと、CanvasのWebGL側もGPUのリソースを使うので、リソースを奪い合うことになってしまいます。
ここでCSS側のアニメーションが優先された場合、CanvasのWebGL側の描画がカクつく原因になってしまうので、Canvas側に描画を一本化します。

▼画像アセットをスプライトシート にまとめる。
WebGLのドローコールの回数をできるだけ下げるためにもスプライトシート 化します。ただ、何でもかんでも一枚の画像にまとめれば良いという訳でもなく、1枚の画像にまとめたことでかえってデータ容量が重くなってしまうこともあるので、バランスを考えて調整します。
今回はAdobeAnimateを使ってスプライトシートを作成しました。

▼毎フレーム処理のフレームレートを下げる
コンシューマーゲームでは60fpsが美徳とされていますが、ブラウザではリソースが限られているので、フレームレートは30fpsぐらいにして高速化とアニメーションのなめらかさの落とし所とします。

▼レガシーな環境ではCanvasの解像度を下げる
レガシーなブラウザ環境ではよりリソースがシビアになりますので、解像度を下げて高速化します。pixi.jsではRendererの初期化時にresolutionの指定が可能なので、ここで対応します。

this.renderer = PIXI.autoDetectRenderer( 500, 500, {  transparent: false, antialias : false, resolution:0.7, backgroundColor:0x000000 } );

▼画像を圧縮する
画像を圧縮するだけで、読み込み速度と描画パフォーマンスの改善に繋がります。Mac環境ではImageOptimという画像圧縮ソフトでpng画像を軽くすることができます。

▼ソースコードのmin化(圧縮)
gulp-uglifyを使ってソースコードを圧縮してダウンロードサイズを小さくすると共に実行速度を上げることができます。

▼gzipを利用してソースコードをさらに圧縮する
今回は利用しませんでしたが、jsのコードなどをgzipで圧縮することでさらにダウンロードサイズを小さくすることができます。

■今回使用した技術(ライブラリなど)

適切なライブラリを使用することで、開発をスムーズに行うことができました。今回Spineを導入したのは初めてでしたが、動作も軽快でバグもなく末長くお世話になりそうです。

・pixi.js(canvsライブラリ)
・gulp.js
・HOWLER.js(音ライブラリ)
・sass
・BABEL
・pug
・Spine(キャラクターのボーンアニメーション作成)
・Adobe Animate cc(スプライトシート作成)

▼HOWLER.js
音ゲーなので音が出ないと色々とマズいので音ライブラリである「HOWLER.js」を使用しました。Android、iOSどちらのブラウザも問題なく複数の音を同時にならずことができます。(Android4系の一部の標準ブラウザは除く)

▼pixi.js
次に、もっとも大切なのが背景やキャラクターの描画です。
pixi.jsを使用することで開発者が意識せずともWebGL描画を簡単に行うことができ、ブラウザ上でも高速な2D描画が可能です。

▼Adobe Animate cc
pixi.jsで使用する画像群をAnimateでスプライトシートにまとめることで描画の高速化とファイルの軽量化を行なっております。

▼Spine
キャラクターのアニメーションの制作はデザイナーの方がSpineで行いました。
pixi.jsとの親和性が高く、Spine->pixi.jsへのアセットの変換は大変スムーズでした。

■最後に

PWAやWebGLやWebAssemblyなどのブラウザの高機能化、Vue.jsなどのSPAに使えるフレームワークの普及などにより、今までネイティブアプリで制作されていたものが、今後はブラウザアプリでリリースされることも増えそうです。個人的にはRustからのWebAssembly出力に注目しております。

時代の波にのり軟体動物のように変化していくことがWebのフロントエンド エンジニアには求められることだと思っているので、時代の変化を恐れるのではなく、変化を楽しんでいけたらと思っております。

この記事が気に入ったらサポートをしてみませんか?