Node.jsでエンジンを実行する
Node.jsは、Windows、Linux、macOSなどで動作するクロスプラットフォームのオープンソースJavaScriptランタイム環境です。これはV8 JavaScriptエンジン上で動作し、ウェブブラウザの外部でJavaScriptコードを実行します。Node.jsを使用すると、開発者はJavaScriptでコマンドラインツールやサーバーサイドスクリプティングを作成できます。
PlayCanvas EngineはNode.jsでの実行を完全にサポートしています。これは次のような場合に役立ちます。
- マルチプレイヤーサーバーの作成
- アセットデータ処理ツールの作成
- アプリケーションの単体テストの記述
PlayCanvas EngineはNode.jsを使用して独自の単体テストを実行しています。
インストール
開始する前に、Node.js 18以降がインストールされていることを確認してください。その後、npmを使用してPlayCanvas Engineをインストールできます。
npm install playcanvas
ヘッドレスアプリケーションの作成
Node.jsでPlayCanvasアプリケーションを実行する場合、レンダリングは必要ない可能性が高いです。この場合、何もレンダリングしないNullGraphicsDeviceを作成できます。表示するものがないため、キャンバスの代わりにプレーンなオブジェクトを使用できます。
import { AppBase, AppOptions, NullGraphicsDevice, ScriptComponentSystem } from 'playcanvas';
// 何もレンダリングしないため、プレーンなオブジェクトをキャンバスの代わりに使用する
const canvas = { width: 1, height: 1 };
const options = new AppOptions();
options.graphicsDevice = new NullGraphicsDevice(canvas);
options.componentSystems = [ScriptComponentSystem];
const app = new AppBase(canvas);
app.init(options);
app.start();
AppBaseは、登録したコンポーネントシステムだけを実行します。このアプリケーションは、スクリプトの追加で使用するスクリプトコンポーネントシステムを登録しています。他の種類のコンポーネントを追加する場合は、アプリケーションの構成で説明しているように、それぞれのシステムを登録してください。
アプリケーションの更新
ブラウザでは、app.start()はrequestAnimationFrameで駆動されるメインループを開始します。Node.jsにはrequestAnimationFrameがないため、メインループは実行されません。代わりに、必要なレートでapp.update(dt)を呼び出してください。これにより、スクリプト、アニメーション、物理など、登録したコンポーネントシステムが更新され、レンダリングは一切行われません。
const TICK_RATE = 20; // 1秒あたりの更新回数
setInterval(() => {
app.update(1 / TICK_RATE);
}, 1000 / TICK_RATE);
固定のdtを渡すと、タイマーにずれが生じても、すべての更新が同じ長さになります。
スクリプトの追加
ESMスクリプトは標準的なJavaScriptモジュールであるため、Node.jsで直接インポートできます。たとえば、エンティティを回転させるスクリプトは次のとおりです。
import { Script } from 'playcanvas';
export class Rotate extends Script {
static scriptName = 'rotate';
update(dt) {
this.entity.rotate(0, 90 * dt, 0);
}
}
スクリプトクラスをインポートし、スクリプトコンポーネントに渡します。
import { Entity } from 'playcanvas';
import { Rotate } from './rotate.mjs';
const entity = new Entity('Box');
entity.addComponent('script');
entity.script.create(Rotate);
app.root.addChild(entity);
これで、app.update(dt)を呼び出すたびにスクリプトのupdateメソッドが実行されます。
jsdomの使用
エンジンの一部は、Node.jsが提供していないDOM APIに依存しています。
<script>要素でロードされるクラシックスクリプトXMLHttpRequestでファイルをリクエストする、アセットレジストリを通じたアセットのロード
これらのいずれかが必要な場合は、jsdomパッケージを使用してDOM環境をシミュレートできます。
npm install jsdom
次の関数は、jsdomを使用してDOM環境を設定し、PlayCanvas Engineが正常に実行できるようにします。
import { JSDOM } from 'jsdom';
import * as pc from 'playcanvas';
let jsdom;
export function jsdomSetup() {
const html = '<!DOCTYPE html><html><head></head><body></body></html>';
jsdom = new JSDOM(html, {
resources: 'usable', // エンジンがアセットをロードできるようにする
runScripts: 'dangerously', // エンジンがスクリプトを実行できるようにする
url: 'http://localhost:3000' // ドキュメントのURLを設定する
});
// windowとdocumentをグローバルスコープにコピーする
global.window = jsdom.window;
global.document = jsdom.window.document;
// エンジンで使用されるDOM APIをグローバルスコープにコピーする
global.ArrayBuffer = jsdom.window.ArrayBuffer;
global.Audio = jsdom.window.Audio;
global.DataView = jsdom.window.DataView;
global.Image = jsdom.window.Image;
global.KeyboardEvent = jsdom.window.KeyboardEvent;
global.MouseEvent = jsdom.window.MouseEvent;
global.XMLHttpRequest = jsdom.window.XMLHttpRequest;
// PlayCanvas APIをグローバルスコープにコピーする(「classic」スクリプトにのみ必要)
jsdom.window.pc = pc;
}
アプリケーションを作成する前にjsdomSetup()を呼び出してください。アセットをロードするには、クラシックスクリプト用のScriptHandlerなど、アセットの種類ごとのリソースハンドラーもAppOptionsに登録してください。jsdomもメインループを提供しないため、上記のようにapp.update(dt)を呼び出し続けてください。