Skip to content

ローカルエンティティを使う

ローカルエンティティは、プレイヤーごとに異なる動作・異なる表示を行うことができるエンティティ (g.E) です。

凡例

javascript
const localSprite = new g.Sprite({
  ... // その他プロパティ

  // ローカルであることを指定
  local: true,

  // touchable: true を指定してクリック可能にしてもよい。
  // ただし受け取るイベントはローカルイベントになる(後述)
  touchable: true
});
const localSprite = new g.Sprite({
  ... // その他プロパティ

  // ローカルであることを指定
  local: true,

  // touchable: true を指定してクリック可能にしてもよい。
  // ただし受け取るイベントはローカルイベントになる(後述)
  touchable: true
});

詳細

Akashic Engine のマルチプレイは、全プレイヤーの操作情報 (イベント) を全プレイヤーに共有し、それを全員が処理をすることで実現されます。 そのため原則的に全プレイヤーが同じフレームでは同じゲーム画面を表示します。

しかしプレイヤーごとに異なる画面を表示したいことがあります。 例えば多人数の対戦ゲームで、各プレイヤーが装備を切り替える UI は、いちいち他プレイヤーの分まで表示すべきでないかもしれません。 このような時にローカルエンティティが利用できます。

ローカルエンティティ は、マルチプレイでプレイヤーごとに異なる動作・異なる表示を行うことができるエンティティです。

ローカルエンティティは、エンティティのコンストラクタ引数の local プロパティに true を与えることで生成できます。

touchable なローカルエンティティ

通常のエンティティ同様、ローカルエンティティは touchable: true を指定してクリック・タッチ可能にすることができます。

ただし ローカルエンティティに対するイベントは、「そのエンティティをクリック・タッチしたプレイヤー自身」にしか通知されません

javascript
// 通常の (ローカルでない) エンティティ
const sprite = new g.Sprite({
  ... // その他プロパティ
  touchable: true
});

sprite.onPointDown.add(ev => {
  // 誰かが `sprite` をクリック・タッチした時、
  // 全プレイヤーの手元でここに書かれたコードが実行される
});

// ローカルエンティティ
const localSprite = new g.Sprite({
  ... // その他プロパティ
  local: true, // ローカルエンティティにする
  touchable: true
});

localSprite.onPointDown.add(ev => {
  // 誰かが `localSprite` をクリック・タッチした時、
  // クリックした本人のデバイスでのみ、ここに書かれたコードが実行される
});
// 通常の (ローカルでない) エンティティ
const sprite = new g.Sprite({
  ... // その他プロパティ
  touchable: true
});

sprite.onPointDown.add(ev => {
  // 誰かが `sprite` をクリック・タッチした時、
  // 全プレイヤーの手元でここに書かれたコードが実行される
});

// ローカルエンティティ
const localSprite = new g.Sprite({
  ... // その他プロパティ
  local: true, // ローカルエンティティにする
  touchable: true
});

localSprite.onPointDown.add(ev => {
  // 誰かが `localSprite` をクリック・タッチした時、
  // クリックした本人のデバイスでのみ、ここに書かれたコードが実行される
});

このような「発生させた本人にしか通知されないイベント」を、 ローカルイベント と呼びます。

ローカルイベントに起因する処理においては、ゲームのグローバルな実行状態を変更してはいけません。(後述)

ローカルイベントは操作した本人にのみ通知されますが、そこから改めて全プレイヤーに通知したいことがあります。 例えば「多人数の対戦ゲームの装備を切り替える UI で、実際に装備を変更した」時には、選んだ装備を全プレイヤーに通知しなければなりません。 この場合には g.game.raiseEvent() を使います。詳細は 逆引きリファレンス » ローカルイベントからグローバルに通知する を参照してください。

ローカル処理とその制限

ローカルイベントに起因して実行される処理など、特定のプレイヤーのデバイス上でしか行われない処理を ローカル処理 と呼びます。

これは、主に touchable なローカルエンティティをクリック・タッチして、 g.E#pointDown などにイベントが通知された時の処理を指します。 ローカル処理中に呼び出された g.Scene#setTimeout() などが引き起こす処理もローカル処理に含みます。

ローカル処理には、そこでのみ許される処理や、逆に禁止される処理が存在します。

  • ローカル処理で禁止される処理
    • ローカルでないエンティティの生成・操作
    • シーン遷移
    • (ローカル処理以外で利用している)乱数生成器(g.Game#random など)の利用
  • ローカル処理で許される処理
    • ローカルエンティティの生成・操作
    • g.Game#focusingCamera の変更 (次節で説明します)
    • Math.random() の利用 (ローカル処理でのみ可能)
    • 全体への通知 (g.Game#raiseEvent() の呼び出し) (ローカル処理でのみ可能)

ローカルイベントはそれを発生させたプレイヤーにとってしか存在しないので、ローカル処理では「プレイヤー間で間接的に共有されている実行状態」を破壊してはいけません。すなわち、同じ操作によって同じ実行状態が再現できなくなるような変更をしてはいけません。

例として、幅・高さが 100 で、 touchable が真である、ローカルでない矩形のエンティティを考えます。ローカル処理の中でこのエンティティの位置を原点から (200, 0) の位置に移動させたとします。するとそれ以降、たとえば (50, 50) の位置に対するポイント押下イベントの結果は、プレイヤー間によって異なるものになってしまいます。このようなエンティティ操作に限らず、ローカル処理では「非ローカルエンティティの生成」や「シーン遷移」「(ゲーム開発者が作った)ゲーム状態の変更」など、破壊的操作のほとんどを行ってはいけません。

通常の場合と異なり、Akashic Engine の乱数生成器 (g.Game#random) の利用も避けてください。ローカル処理によって特定のプレイヤーでのみ乱数生成が行われると、乱数生成器の内部状態が変わります。その結果、それ以降で各プレイヤーが乱数を生成した時に得られる数の系列が、一人だけ異なるものになってしまいます。ローカル処理で乱数を利用したい時は、 g.game.localRandom を利用してください。