Akashic Engine プログラミングでの注意点2020/04/04

「今日からはじめるニコ生ゲーム制作」
なんて放送もあって、新たに Akashic Engineを使ってみようという方も出てきそうなこの頃。

しかし放送でやっていたように画像を差し替えるくらいなら良いのですが、プログラムを組んでゲームを作るとなるといろいろ注意しなければいけない点も出てきます。
一応 Akashic Engineで何本かゲームを作ってきた身として、そのあたりをいくつか挙げてみたいと思います。

なお、サンプルコードは TypeScriptで書かれています。
JavaScriptの方は型宣言等、読み飛ばしちゃってください。


1.マルチタッチ

PCで開発してマウスでテストプレイしていると気づきにくいのですが、Akashic Engineはマルチタッチに対応しています。画面の2点以上を同時にタッチすると、それぞれのポイントのイベントが発生します。

pointDownでタッチを見るだけなら、気にする必要はありません。
pointMovepointUpで移動したとき・離したときのイベントを使うときは、引数のメンバpointerIdでそれぞれ区別・対応するようにしましょう。
一緒にすると、スマホだけの裏技なんてものができてしまうかもしれません。


2.シーンオブジェクトのポイントイベント

エンティティ毎のポイントイベントとは別に、シーンオブジェクトのpointDownCaptureでシーン全体のポイントイベントを取得することができます。
タッチした座標は引数のメンバpointで得られるのですが、touchableなエンティティの上をクリックした場合、その値が画面上の座標ではなくエンティティ上での相対座標になってしまいます。

例えば (100, 100) - (200, 200)の座標・大きさでtouchableなエンティティがあったときに画面上の座標(120, 120)をクリックすると、取得される値は(20, 20)になってしまいます。

画面上の座標を得るには、メンバtargetを見てエンティティの行列で変換する必要があります。
scene.pointDownCapture.add((ev: g.PointDownEvent) =>
{
    let pos: g.CommonOffset;
    if ( ev.target ) {
        pos = ev.target.getMatrix().multiplyPoint(ev.point);
    }
    else {
        pos = ev.point;
    }



3.アンカーポイント

エンティティはアンカーポイントによって表示する座標の原点や拡大・縮小・回転の位置を指定することができます。
原点を指定するようなものなのですが、appendで追加した子エンティティの相対座標に親のアンカーポイントは影響しません。

例えば次のように、
const   parent: g.FilledRect = new g.FilledRect(
{
    scene: scene,
    cssColor: "#ff0000",
    x: 100,
    y: 100,
    width:  64,
    height: 64,
    anchorX: 0.5,
    anchorY: 0.5,
});
scene.append(parent);

const   child: g.FilledRect = new g.FilledRect(
{
    scene: scene,
    cssColor: "#0000ff",
    x: 100,
    y: 100,
    width:  32,
    height: 32,
    anchorX: 0.5,
    anchorY: 0.5,
});
scene.append(child);

中心をアンカーポイントとした2つのエンティティを、それぞれ同じ座標(100, 100)に表示すると

Akashic Engine アンカーポイントの例

2つは同じ座標を中心として表示されます。当然ながら。

const   child = new g.FilledRect(
{
    scene: scene,
    cssColor: "#0000ff",
    x: 0,
    y: 0,
    width:  32,
    height: 32,
    anchorX: 0.5,
    anchorY: 0.5,
});
parent.append(child);

そこで座標が同じなんだから相対位置は(0, 0)だろうと、青い方の位置を x: 0, y: 0にして 赤い方に appendしてみると

Akashic Engine アンカーポイントの例

左上にずれます。
アンカーポイントに依らず、相対座標は親エンティティの左上を原点としているようです。

中心を合わせるには、
    x: 64/2 + 0,
    y: 64/2 + 0,
親エンティティのサイズを考慮する必要があります。

    x: parent.width*parent.anchorX + 0,
    y: parent.height*parent.anchorY + 0,
汎用的に書くと、こんな感じです。



というわけで、自分が Akashic Engineを使う上で実際にぶつかった点を3つ程挙げてみました。

あとはラベルやフォントなんかで気になる点もあるのですが、よくわからないままその場しのぎで対応してたりするので、ここでは割愛致します。