0

ユーザーが画面をスワイプしてクリアできるモバイル webapp ゲームを作成しています。キャンバスのほぼ全体が透明になったことを検出するスマート関数を作成しようとしています。

チェックを行うために、毎秒以下の関数を呼び出す間隔があります。動作するはずの方法は、幅が 20 ピクセルで、キャンバスと同じ高さのキャンバスのセクターを取得することです。

この関数は非常にスムーズに実行されるはずですが、何らかの理由で getImageData 関数が多くのピクセルに戻ります。私のセクターは常に幅が 20px で高さが同じなので、毎回同じ量のピクセルを返す必要があります。もちろん、getImageData はますます大きな数値を返すため、私のループはますます遅くなります。

誰がこれを引き起こすのか知っていますか? getImageData 関数の動作を誤解していませんか?

isCanvasTransparent: function (fromX, toX, currentIteration) {

        if(currentIteration < this.clearedIterations) { // If a sector is already clear, we dont need to check it again
            this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1);
            return;
        } else {
            var data = this.context.getImageData(fromX, 0, toX, parseInt(this.canvas.style.width)).data;
            var counter = 0;
            var i = 0;

            // For some reason, the length increases, but the diff between fromX and toX is always 20
            console.log(data.length); 

            for(i=0;i<(data.length);i+=4) { 
                if(data[i+3]!==0){
                    counter++;
                    // I stop iterating, since there are too many non transparent pixels
                    if(counter > 10) {
                        break;
                    }
                }
            }

            // I accept that 10 pixels in each sector is not transparent
            if((counter < 10) && !this.alerted) {
                this.clearedIterations++; // Here we increase clearedIterations, since this sector is clear

                // There are no more iterations, so we are done
                if(currentIteration === this.maxIterations) {
                     // this is the interval that calls isCanvasTransparent(0, 20, 0)
                     // in the first place. The interval is called each second. But as soon the whole view
                     // is transparent, we clear it, so that isCanvasTransparent is no longer called
                    clearInterval(this.checkCanvasTimeout);
                    this.alerted = true;
                    TouchHelpers.removeTouchEvents();
                    this.levelCompleted();
                    return;
                } else {
                    // this sector is clear, but we need to check the next one, since we are not at the end
                    this.isCanvasTransparent(fromX + 20, toX + 20, currentIteration + 1);
                }
            }
        }
    },
4

1 に答える 1

2

fromX/toX の設定方法を見ないとわかりませんが、getImageData に適切なパラメーターを与えていないようです。

context.getImageData次のパラメータがあります。

  • x: 抽出する開始 x 座標、
  • y: 抽出する開始 y 座標、
  • width: このピクセル幅のブロックを抽出し、
  • 高さ: このピクセル数の高さのブロックを抽出します

【追加:追加情報に基づく】

同じサイズのピクセル データのチャンクが必要な場合、最初の呼び出しは次のとおりです。

var data=getImageData(0,0, 20, canvas.height).data;

2 番目の呼び出しは次のようになります。

// Note: the width arguement remains at 20, not increase to 40

var data=getImageData(20,0, 20, canvas.height).data;
于 2013-10-24T15:07:32.950 に答える