RPG Maker MZ Next:モダンな RPG Maker MZ フレームワーク

更新情報!

Bitmap.drawText();

が機能するようになり、現在は PixiJS の Text レンダリングを使用しています。ただし、キャンバスレンダリングと非常に似ています。BitmapText を使用することを計画していましたが、残念ながら、RM のユーザーが慣れ親しんでいる操作性に対して十分な制御を提供していません。

通常の RM システムとの大きな違いは、テキストスタイルを使用するようになったことです!これにより、テキストの多くの側面に対して非常に多くの制御が可能になります。この機能に簡単にアクセスできるようにします。
おそらく、シンプルな関数経由で:

bitmap.changeTextStyle({});

さて、私は休むことにします。なぜなら、奇妙なバグのデバッグは本当に骨が折れる作業だったからです!

「いいね!」 1

新しいAPIの変更点は以下の通りです:

Windowsにアンカー機能が追加され、位置決めがより容易になりました!

また、ライブラリにはスプライトやウィンドウのアンカー用の既存のプリセットも用意されています!

const rect = new Rectangle(10,10,100,100);
const window = new WindowDummy(rect);
window.anchor.copyFrom(AnchorPresets.Center);
// または
window.anchor.x = 0.5;
window.anchor.y = 0.5;

これで、ウィンドウの配置をより良い方法で行えるようになるはずです!

アンカーの実装に関する技術的な詳細は非常にシンプルです:

  get anchor(): Point {
    return this._anchor;
  }

  set anchor(value: PointData | number) {
    if (typeof value === 'number') {
      this._anchor.set(clamp(value, 0, 1), clamp(value, 0, 1));
    } else {
      this._anchor.set(clamp(value.x, 0, 1), clamp(value.y, 0, 1));
    }
    this.updatePivot();
  }

  private updatePivot() {
    this.pivot.set(
      this._anchor.x * this._width,
      this._anchor.y * this._height
    );
  }
// 一部のコードは省略していますが、幅と高さのリサイズ時にも更新されます。

これは basically、コンテナのローカルトランスフォームに基づくピボットに対するエイリアス/セッターです。

さらに更新!

SceneLayer

これは実験的な機能ですが、スプライトを完全に機能するシーンレイヤーにグループ化することができます。つまり、カスタムレイヤー(例えばフォグや照明まで!)をScene_Mapに追加するために、事実上無限のレイヤーを持つことができるということです。

技術的な実装は以下の通りで、事実上あらゆるものに適用可能です。

/**
 * 複数のシーンレイヤーを管理するクラス。
 * 
 * これは ```RenderLayer``` のコレクションであり、
 * 任意の containerChild を*レイヤー*に効率的にグループ化することを可能にします。
 * @experimental これにはまだ多くの実装が必要です。
 */
export class SceneLayerContainer extends Container<ContainerChild> {
  
  private readonly _layers: Map<string, RenderLayer>;

  // どの物理的な子要素がどのレイヤー名に属しているかを追跡
  private _layerTracking: Map<string, Set<ContainerChild>>;

  get layers(): Map<string, RenderLayer> {
    return this._layers;
  }

  getLayer(name: string): RenderLayer {
    const layer = this._layers.get(name);
    if (!layer) throw new Error(`Layer "${name}" not found`);
    return layer;
  }

  constructor() {
    super();
    this._layers = new Map();
    this._layerTracking = new Map();
    this.sortableChildren = true;
  }

  addLayer(name: string, layer: RenderLayer, zIndex: number | null = null) {
    if (this._layers.has(name)) {
      throw new Error(`Layer name "${name}" already exists`);
    }

    this._layers.set(name, layer);
    this._layerTracking.set(name, new Set());

    if (zIndex !== null) {
      layer.zIndex = zIndex;
    }

    this.addChild(layer);
  }

  addToLayer(layerName: string, ...children: ContainerChild[]) {
    const layer = this.getLayer(layerName);
    const trackedSet = this._layerTracking.get(layerName)!;

    this.addChild(...children);
    layer.attach(...children);

    for (const child of children) {
      trackedSet.add(child);
    }
  }

  removeFromLayer(layerName: string, ...children: ContainerChild[]) {
    const layer = this.getLayer(layerName);
    const trackedSet = this._layerTracking.get(layerName)!;

    layer.detach(...children);
    this.removeChild(...children);

    for (const child of children) {
      trackedSet.delete(child);
    }
  }

  removeLayer(name: string, destroyChildren: boolean = false) {
    const layer = this._layers.get(name);
    if (!layer) throw new Error(`Layer "${name}" not found`);

    const trackedChildren = this._layerTracking.get(name);

    if (trackedChildren) {
      // この特定のレイジャーレジストリに関連付けられたすべてのコンポーネントを安全に処理
      for (const child of trackedChildren) {
        this.removeChild(child);
        if (destroyChildren) {
          child.destroy({ children: true });
        }
      }
    }
    layer.detachAll();
    this.removeChild(layer);
    this._layers.delete(name);
    this._layerTracking.delete(name);
  }
}

SceneLayerContainer は単なるファニーなコンテナだと言えるかもしれませんが、新しい

RenderLayer

API により、これらすべてがより簡単になります。

ただし、これはまだかなり実験的な段階であり、私もまだ試行錯誤中です。しかし、この機能が皆さんが SceneMap や任意のシーンに新しいコンテンツをより簡単に追加できるようになることを強く願っています!

「いいね!」 1

このプロジェクトがどこへ向かうのか楽しみです。特にESModulesサポートは!

これはバニラエディタとも互換性があり、NW.JSへのエクスポートも可能でしょうか?
私はメカニクス作成にはエディタをそれほど使いませんが、タイルやイベント作成にはとても便利です。
また、デスクトップ向けのJS/TS市場はElectronに移行しているようですが、私はまだNWに愛着を持っています。

オーバーライドやエイリアスなどのデコレーターは気に入っていますが、こうしたパターンをまだ推奨すべきかどうかは疑問です。実際のコードベースでは、エイリアスは有用な部分と肥大化しやすい部分の両方があります。また、ClassName.prototype.funcName という10年前の構文から離れられる可能性もあります。

互換性については、コアスクリプトを書き直す価値があるかどうかで悩んでいます。RPGPaperMakerやGodotRpgFrameworkのような他のオープンソース「メーカー」に貢献する方がよいかもしれません。特に最終目標が「エディタを除いた新しいRPGメーカーエンジン」を持つことである場合です。

コアの一部を書き直しつつ、旧MZのコアスクリプトのプロトタイプをすべて実装し(ただし、新しいシステムで動作するように動作を再設定する)という世界も存在します。ただし、それがどれほど実現可能で有益なのかは不明です。

「いいね!」 1

これは従来のエディタと互換性があり、NW.JSへのエクスポートも可能ですか?

私はメカニクス作成にはエディタをあまり使いませんが、タイルやイベントの作成にはとても便利です。
また、デスクトップ向けのJS/TS市場はElectronへと移行しているように見えますが、私は依然としてNWに愛着を持っています。

これは旧エディタとNw.jsと100%互換性があります。

現在、私は簡便さのためにViteを使用しています(TSをネイティブにサポートしており、バンドルが速いためです)。

デコレータを使用したオーバーライドエイリアスなどは好きですが、これらのパターンをまだ推奨すべきかどうかは疑問です。実際のコードベースでは、エイリアシングは有用な面と冗長になりやすい面の両方があります。また、ClassName.prototype.funcName という10年前の構文から離れることも可能かもしれません。

これについては、RPG Maker MZの現在の制約を考慮しつつ、ゆっくりと考えているところです(Unityのようにクラスを拡張してゲームオブジェクトにアタッチできるわけではありませんが)。ネイティブフックのようなものを考えていましたが、まだどのようにアプローチすべきか確信が持てません。もしC#であれば、イベントリスナーを使用するだけで済む単純な話ですが、RPG Makerプラグインのワークフローはモンキーパッチングを非常に重視しているため、ユーザーにこれを避けるよう強制するのは少し複雑になります。

互換性については、コアスクリプトを書き換える価値があるかどうかで葛藤しています。RPGPaperMakerやGodotRpgFrameworkのような他のオープンソースの「メーカー」に貢献する方がよいでしょうか?特に最終目標が「エディタを除いた全く新しいRPG Makerエンジン」を持つことである場合です。

コアの一部を書き換える世界も存在しますが、旧MZのコアスクリプトのプロトタイプをすべて実装し(ただし、新しいシステムで動作するように動作を再配線する)、互換性を保つという方法もあります。それがどれほど実現可能で有益かはわかりませんが。

互換性についてはお気持ちわかります。当初の私の計画は単純で、「RPG MakerがモダンなPixiJSエコシステムを持っていたらいいな」と思い、純粋な楽しみと興味からポートし始めました(はい、私は変態です)。正直なところ、このプロジェクトは純粋な好奇心から生まれました。

多くの破壊的変更は、PixiJSのV5からV8への移行に伴うもので、多くのものが壊れました。私は、古いテクノロジー(非常に古いライブラリ)の上に構築されているRPG Makerを、より更新された状態に持ち込みたいと思っています。RubyやC#とは異なり、Webは非常に急速に進化しており、そのペースは驚くほどです。MZにもう少し寿命を与えたいのです。

しかし、時にはこれが私の時間をかける価値があるかどうか自問することもあります。これは大きな取り組みですが、努力を積み重ね、削り出すにつれて、ゆっくりと形になり、問題を解決していく様子を見るのは面白くなってきます。でも、また言いますが、私はただの変態なだけです、ハハ。

RPG Paper Makerについては、実はWanoと一緒にV2のコアスクリプトのランタイムデザイナーを担当していました(ハハ)。しかし、前回以来多くのことを学び、V3のコアスクリプトをよりモジュール化和柔軟性を持たせるためにリフレッシュする必要があります!残念ながら、最近では時間が取れませんでした。

「いいね!」 1