akashic-games/akashic-engine

Apple端末でnew Sprite時に生成されたエンティティの表示がブラウザ実装により異なる

Closed this issue · 6 comments

Spriteを生成するときにsrcの範囲外を参照したときのエンティティの見た目がOSにより異なります。
例えばサイズが100x100の画像をsrcに指定し、srcWdithに1000を指定してSpriteを生成すると、
webkitでは、透明になります。
Chromium,Geckoでは、元画像幅が10分の1に圧縮され、残りの部分は透明になります。

各ブラウザ実装によって動作が変わるのは開発段階で気が付きにくいバグの原因になるので、対処して欲しいです。
WebGLはエラーを返すと思われるので、それを開発者に伝えるなにか手段がほしいです。

xnv commented

ありがとうございます。確認します。

xnv commented

次のようなコードで srcWidth を変えて確認しました。

          var player = new g.Sprite({
            scene: scene,
            src: playerImageAsset,  // 幅・高さ 32 px の画像
            srcWidth: /* 適当な値 */,
          }); 

いくつかのバージョンの Mac Safari を確認しましたが、他ブラウザ (Chrome, Firefoxx など) と同じく「元画像幅が圧縮され、残りの部分は透明に」なるようです (以下スクショのとおり)。width, height を明示的に指定するなど、他の条件も少し試しましたが、やはり現象は再現できていません。

スクリーンショット 2022-02-21 13 37 19

何か詳細な再現手順や、OS, ブラウザのバージョン情報などあれば伺いたいです。

返信ありがとうございます。
もう一度調べてみた所、報告した不具合の原因が少し違いました。
原因は、
g.SpriteFactory.createSpriteFromEを利用して生成したスプライトを元に、新しいスプライトを生成するときに、そのスプライトの外側を参照しようとしたため
でした。
以下に再現するコードを書きます。

const pane = new g.Pane({
  scene,
  width: 30,
  height: 30,
});
pane.append(new g.Sprite({
  scene: scene,
  src: scene.asset.getImageById("player"),  // 幅・高さ 32 px の画像
}));
// pane は30x30なので、生成されるスプライトは30x30
const createdSprite = g.SpriteFactory.createSpriteFromE(scene, pane);
new g.Sprite({
  parent: scene,
  scene: scene,
  src: createdSprite.src,
  // srcに指定したスプライトよりも縦横2px大きい
  width: 32,
  height: 32,
});
xnv commented

詳細ありがとうございます。Mac Safari で現象を再現できました。原因と対応を検討します。

xnv commented

本件の対応を行いました。akashic-cli@2.15.55 と akashic-sandbox@0.17.40 以降、 問題の描画が行われた時にエラーとする ようになります。

ブラウザの挙動に依存せず、serve/sandbox 自身が引数をチェックしてエラーにします。これによって、Safari を利用していないゲーム開発者であっても開発途中に必ず問題に気づけるかと思います。(副作用として、「Safari では動かなくていい」という人にまで Safari 互換を強制することになりますが、ゲーム開発者の環境依存のデバッグ負担 (「ユーザさんから不具合報告が来たが、Mac がないから直せない……」など) を下げる方が重要と判断します)

エラーメッセージを確認できました。
対応ありがとうございます。