🦞

Rust & Wasm でミニゲームを作る時のサンプル(Rust2024)

2025/03/02に公開

はじめに

前回、WebAssemblyミニゲーム用のシンプルなサンプルを作成しましたが、Rust 2024 Editionでは、グローバル変数に、"static mut"の使用が禁止されたため、サンプルが動作しませんでした。そこで、Rust 2024 Editionでも動作するように、グローバル変数でゲームオブジェクトを持ちまわるやり方をやめて、別途用意したループ関数に、Trait + 'static で動的ディスパッチにしたゲームオブジェクトを渡す方法にすることで、Rust 2024 Editionでもビルドが成功するように更新しました。

対象のバージョン

  • Rust 2024 Edition
  • rustc 1.83.0
  • cargo 1.80.1
  • rustup 1.27.1
  • pnpm 9.12.3

環境構築例:Rust & WebAssembly 構築メモ

Rust&Wasm サンプル

Play in browser
https://github.com/myurioka/demo02

サンプルを通して理解した内容

  1. Gameオブジェクト、Trait + 'static でラッピングして、準備したループ用の関数に渡しています。。理由は、Closure::wrap()に渡たすオブジェクトは全て'static'でないといけないためです。👍
  2. animation_frameと、mouse_event_listnerのコールバック用のクロージャ―で共有する、クリップポイントは、新たにRefCellを用意して、借用ルールを回避しています。
  3. 再描画時に呼び出す関数(Closure)を用意します。
    • unsafe{}は、static mute のオブジェクトの値を変えるため必要になります。
    • 引数として呼び出しを開始した時点の時刻が返されますが、サンプルでは参照していません。
    • RC<T>を使って実装する理由は、callbackの処理中に、再帰用のrequestAnimatinoFrameを呼び出す必要があるためです。👍

      Rc<T> enables multiple owners of the same data; Box<T> and RefCell<T> have single owners.
      参照:RefCell<T> and the Interior Mutability Pattern

  4. 再描画時に呼び出される関数(Closure)を指定してrequetsAnimationFrameを呼び出します。
  5. ブラウザーが、再描画のタイミングで 3.で指定した関数(Closure)を呼び出します。
  6. 自前の内部カウントをインクリメントし、各内部変数を更新します。
  7. 各内部変数を参照し、再描画します。
  8. "requestAnimationFrame()"を呼び出し、次の再描画に備えます
  9. クリック時にに呼び出される関数(Closure)を用意します。
  10. "canvas"に、click時に呼び出されるイベント・リスナーをセットします。
  11. forget()を呼び出し、関数のスコープを抜けた後でも、イベントを受け取れるように、Function(closure)のポインタ用情報を維持します。👍
  12. ブラウザーが、クリックを検知し、 9.で指定した関数(Closure)を呼び出します。
  13. 受け取ったクリック座標を、内部変数に反映します。

Discussion