👾

TypeScriptとAssemblyScriptを比べるためミニシューティングゲームを作る

に公開

はじめに

昔と比べ、Canvasに向かってプログラミングを描くことに興味を持っている人がどれくらいいるのかな?と思いながら、Canvas上で動作するミニシューティングゲームをTypeScript(TSC)版と、AssemblyScript(ASC)版を作りました。ご察しの通り、流行のWASMを使うとどれくらい早くなるのか、まったく同じ動作をするゲームを作ることで、体験して比較することが目的です。速くなるというベンチマーク記事はよく見かけますが、昔を懐かしながら趣味で作るミニゲームという限定された環境ではどうでしょうか。興味を持って頂いた方は、記事中のTypeScript版と、AssemblyScript版を両方を試してみてください🙂。

ミニシューティングゲーム

ミニシューティングゲーム

お試しURL

[TypeScript版] https://myurioka.github.io/barrage/
[AssemblyScript版] https://myurioka.github.io/barragewasm/

操作

マウス移動: 自機左右移動
クリック/タップ(プレー中): シューティング ON⇔OFF
☆シューティングが一定期間OFFの場合、数秒間、攻撃力UP
クリック/タップ: ゲーム開始/再開

ソースコード

https://github.com/myurioka/barrage/
https://github.com/myurioka/barragewasm/

試した結果

実際に触れてみた感覚も、簡単な計測値においても、ほぼ変わらない結果でした😢。

1 2 3 4 5 6 7 8 9 10 平均(ms)
ASC update 3 3 2 2 2 2 2 3 2 3 2.4
draw 4 5 6 5 5 5 7 5 5 5 5.2
TSC update 5 2 5 3 2 4 2 2 2 2 3.3
draw 2 2 2 2 2 2 2 2 2 2 2.1

考察

コーディングしてみて思ったことを記載します。WASMで処理されるのは、下記のシーケンス図の中の赤枠の部分です。

シーケンス図

「このゲームでは、画面上の赤い四角の中で行われるのは、主に弾と敵がぶつかったかどうかのチェック(当たり判定)だけのため、たとえ画面に弾をものすごくたくさん(例えば999個)出しても、この当たり判定の処理自体がとても軽いため、WebAssembly (Wasm) 版と通常のTypeScript版の間に、速さの違いはほとんど感じられませんでした。

[当たり判定処理]

function overap(t: Character, s: Character): boolean {
    if (max(t.x, s.x) < min(t.x + t.w, s.x + s.w) && (max(t.y, s.y) < min(t.y + t.h, s.y + s.h))) {
        return true;
    } else {
        return false;
    }
}

最後に

今回は、TypeScriptコードをTypeScriptコンパイラ(tsc)とAssemblyScriptコンパイラ(asc)でそれぞれビルドし、Canvas上で同じ描画処理を行い、その性能差を比較する実験を行いました。弾幕のような負荷の高い描画で差が出ると期待しましたが、そこまで明確な違いは確認できませんでした。

しかし、この挑戦を通してTypeScriptとWASMの連携方法は十分に理解できました。次回は、ブラウザ上で動作するAIプレイヤーや敵キャラクターの実装に挑戦し、より高度なゲーム体験の実現を目指したいと思います😄。

Discussion