2

次の JavaScript コードがあります。これを使用して、画像の配列をループして、それぞれを異なる場所の HTML5 キャンバスに描画します。

/*First, create variables for the x & y coordinates of the image that will be drawn.
                the x & y coordinates should hold random numbers, so that the images will be 
                drawn in random locations on the canvas.*/
                var imageX = Math.floor(Math.random()*100);
                var imageY = Math.floor(Math.random()*100);

                /*Create a 'table' of positions that the images will be drawn to */
                var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
                var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];
                var randomPositionX = Math.floor(Math.random()*10);
                var randomPositionY = Math.floor(Math.random()*10);

            /*Draw all images from assetsImageArray */
            /*Use a while loop to loop through the array, get each item and draw it. */
            var arrayIteration = 0;
            console.log('Assets Image Array length: ' + assetsImageArray.length); /*Display the length of the array in the console, to check it's holding the correct number of images. */
            while(arrayIteration < assetsImageArray.length){
                context.drawImage(assetsImageArray[arrayIteration], imageX, imageY, 50, 50);
                console.log(arrayIteration); /*Display the current array position that's being drawn */
                arrayIteration = arrayIteration+1;
                /*Now try changing the values of imageX & imageY so that the next image is drawn to a 
                    different location*/
                imageX = imagePositionsX[randomPositionX];  /* imageX+(Math.floor(Math.random()*100)); */
                imageY = imagePositionsY[randomPositionY];  /* imageY+(Math.floor(Math.random()*100));  */

            }

このコードの背後にあるロジックは次のとおりです。最初に arrayIteration 変数を 0 に設定してから、assetsImageArray の画像数をコンソールに表示します。その後、while ループが開始されます。arrayIteration 変数が assetsImageArray 内のアイテムの数よりも少ない間、assessImageArray の位置 arrayIteration (つまり、この時点での位置 0) の画像は、座標 imageX および imageY でキャンバスに描画される必要があります。

imageX 変数と imageY 変数は両方とも、コードによって割り当てられた乱数を保持しますMath.floor(Math.random()*100); 。キャンバスの指定された場所に最初の画像を描画した後、コンソールは描画されたばかりの配列要素をログに記録する必要があります。

次に、次の行で arrayIteration 変数をインクリメントし、最後に、配列 imagePositionsX および imagePositionsY からそれぞれランダム要素の値を取得して、imageX および imageY の値を更新する必要があります。

while ループはこのコードを繰り返し処理し、配列のすべての画像が描画されるまで、assetsImageArray からキャンバス上の新しい場所に各画像を描画します。

ただし、何らかの理由で、assetsImageArray の最初と最後の画像だけがキャンバスに描画されています。それらはランダムな場所に描画されています-これが私が望んでいることであり、ページをリロードするたびにキャンバス上の新しい位置に描画されますが、配列内の画像が最初の位置の間にない理由がわかりません最後はキャンバスに描かれています。私のロジックのどこかに問題があると思いますが、どこにあるのかわかりません。

誰でもそれを見つけることができますか?

4

1 に答える 1

1

imageXループの各反復で、次の画像はとで指定された座標で描画されますimageYが、2回目以降の反復imageXimageYは常に同じ値を保持するため、2番目以降の画像はすべて同じ場所に重ねて描画されます。そのため、最初と最後の画像だけが描かれているように見えます。

最初の反復では、ループが開始する前にimageX割り当てられた値に従って、最初の画像が0〜99のランダムな座標で描画されます。imageY

            var imageX = Math.floor(Math.random()*100);
            var imageY = Math.floor(Math.random()*100);

次に、ループ内で変更imageXしてimageY

         imageX = imagePositionsX[randomPositionX];  
         imageY = imagePositionsY[randomPositionY];

しかし、どのような価値観がrandomPositionXあり、randomPositionY保持されますか?それらは、ループが開始する前に1回割り当てられる0から9までの乱数を保持します。imagePositionXしたがって、これらの2つの行は、およびimagePositionsY配列から常に同じ位置を選択します。

最も簡単な修正は、ループ内で次の2行を移動することです。

            var randomPositionX = Math.floor(Math.random()*10);
            var randomPositionY = Math.floor(Math.random()*10);

偶然にも複数の画像が同じ場所に表示される可能性はありますが、10 x 10のグリッドでは可能性が低くなります(画像の数によって異なります)。

私はおそらくコードを単純化するでしょう、このようなもの:

 var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
 var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];
 var i, x, y;

 for (i = 0; i < assetsImageArray.length; i++) {
     x = imagePositionsX[ Math.floor(Math.random()*10) ];
     y = imagePositionsY[ Math.floor(Math.random()*10) ];

     context.drawImage(assetsImageArray[i], x, y, 50, 50);
 }

現在のコードが最初の画像の座標が0〜99のランダムな場所で始まるのに対し、他のすべての画像は2つの配列からランダムに選択された座標を使用している理由がわかりません。そのため、この違いを取り除きました。

于 2012-11-23T11:23:09.583 に答える