[scratch-vm] pickメソッドで高度なスプライトの操作を制御する


※ 当ページには【広告/PR】を含む場合があります。
2021/03/02



今回の内容もかなりディープな
scratch-render(以降ではrenderと略記) で使うための注意点を解説します。


合同会社タコスキングダム|蛸壺の技術ブログ【Pschool厳選】Scratchを学べるオンライン・駅前プログラミングスクール5選

vm内でrenderを使うときの問題点



あらためて
renderのpickメソッド は、ステージ上の座標からスプライトを検出してそのDrawableIDを返してくれるスクラッチゲーム開発には無くてはならないメソッドです。
このrenderはvmの標準ライブラリとして組み込まれているので、当然vmからもpickメソッドが使えるようになっているのですが、vmから呼び出して使う際にまず何が問題となるのか説明していきます。

vmでpickメソッドを使うときの問題点



まず理解しないといけないはvmのステージの座標はデフォルトでステージの左端:-240、右端:+240の右方向を正、かつ下端:-180、上端:+180とする上方向を正とする座標系をとります。
そこは
setStageSizeメソッド の実装をじっくりみるとなんなく分かると思います。

            /**
* Set logical size of the stage in Scratch units.
* @param {int} xLeft The left edge's x-coordinate. Scratch 2 uses -240.
* @param {int} xRight The right edge's x-coordinate. Scratch 2 uses 240.
* @param {int} yBottom The bottom edge's y-coordinate. Scratch 2 uses -180.
* @param {int} yTop The top edge's y-coordinate. Scratch 2 uses 180.
*/
setStageSize (xLeft, xRight, yBottom, yTop) {
    this._xLeft = xLeft;
    this._xRight = xRight;
    this._yBottom = yBottom;
    this._yTop = yTop;

    // swap yBottom & yTop to fit Scratch convention of +y=up
    this._projection = twgl.m4.ortho(xLeft, xRight, yBottom, yTop, -1, 1);

    this._setNativeSize(Math.abs(xRight - xLeft), Math.abs(yBottom - yTop));
}

        

そして何も考えずにvmでpickメソッドを呼び出したとして、下の図のようにとある四角の枠(高さH)で表したスプライトを検出したいとしましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


おそらく画像の位置によっては、クリックしてステージ上のスプライト画像を触っているにもかかわらず画像は検出されないかもしれません。
かと思えば、画像から離れた上の何もなさそうな位置をクリックしたらスプライトを検出してしまうような良くわからない挙動もあるかもしれません。
このvmの謎の挙動の原因は、vmが内々に定義しているステージの座標が、renderのそれは別々になっているからです。

vmとrenderのステージサイズの違いを捉える



renderとvmとのステージの構成を以下の図で説明しましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


この図で左側がrender内部で制御しているステージ座標、右側がvm内部で制御しているステージ座標を表しています。
まずもっとも大きな違いとして、左から右方向を正とするのはスクラッチステージと同じですが、