0

I have a HTML5 canvas that generates a bouncing box every time you click on it. The box array stores the x-value, y-value, x-velocity, and y-velocity of each box created. The box will travel in a random direction at first and will bounce of the sides of the canvas but if it hits a corner the box dissappears instead of bouncing back. EDIT: I answered my own question noticing that the soundY and soundX functions were causing the problem.

var box = new Array();
var width  = window.innerWidth;
var height = window.innerHeight;
var field = document.getElementById('canvas');

field.width  = width;
field.height = height; 
field.ctx = field.getContext('2d');
field.ctx.strokeStyle = 'rgba(255,255,255,1)'; 
setInterval('redraw()', 200);
addEventListener('click', createBox, false);

function createBox(e) { // this box will always fail collision detection at the upper-left corner
  box.push(100); // x-value is normally mouse position
  box.push(100); // y-value is normally mouse position
  box.push(-5); // x-speed is normally random
  box.push(-5); // y-speed is normally random
}

function redraw() {
  field.ctx.clearRect(0,0,width,height); 

  for(var i = 0; i < box.length; i+=4) {
         if(box[i] < 0)        { box[i+2] *= -1; soundY(box[i+1]); } // parameter of soundY is less than 0 
    else if(box[i] > width)    { box[i+2] *= -1; soundY(box[i+1]); } // which is invalid and causes this to break

         if(box[i+1] < 0)      { box[i+3] *= -1; soundX(box[i]); }
    else if(box[i+1] > height) { box[i+3] *= -1; soundX(box[i]); }

    box[i] += box[i+2];
    box[i+1] += box[i+3];
    field.ctx.strokeRect(box[i], box[i+1], 4, 4);
  }
}

function soundX(num) {
  // play a sound file based on a number between 0 and width
}

function soundY(num) {
  // play a sound file based on a number between 0 and height
}
4

2 に答える 2

1

問題を再現できる唯一の方法は、コーナーの1つにボックスを生成して、正しいx速度とy速度で、ボックスが最初にキャンバスの境界の外側に作成されるようにすることでした。それが起こったとき、速度の反転はアイテムを範囲内に戻すのに十分ではなく、次のフレームで速度が再び反転されます(以下同様)。

私はこれがあなたの問題を解決するかもしれないと思います:

        var boxes = [];
        var boxSize = 4;
        var width = window.innerWidth;
        var height = window.innerHeight;
        var field = document.getElementById('canvas');

        function redraw() {
            field.ctx.clearRect(0, 0, width, height);
            var box;
            for (var i = 0; i < boxes.length; i++) {

                box = boxes[i];
                field.ctx.strokeRect(box.x, box.y, boxSize, boxSize);

                if (box.x < 0) {
                    box.x = 0;
                    box.dx *= -1;
                } else if (box.x > width - boxSize) {
                    box.x = width - boxSize;
                    box.dx *= -1;
                }

                if (box.y < 0) {
                    box.y = 0;
                    box.dy *= -1;
                } else if (box.y > height - boxSize) {
                    box.y = height - boxSize;
                    box.dy *= -1;
                }

                box.x += box.dx;
                box.y += box.dy;
            }
        }

        field.width = width;
        field.height = height;
        field.ctx = field.getContext('2d');
        field.ctx.strokeStyle = 'rgba(0,0,0,1)';

        setInterval(redraw, 200);
        addEventListener('click', createBox, false);

        function createBox(e) {
            boxes.push({
                x: e.clientX - 10,
                y: e.clientY - 10, // arbitrary offset to place the new box under the mouse
                dx: Math.floor(Math.random() * 8 - boxSize),
                dy: Math.floor(Math.random() * 8 - boxSize)
            });
        }

私はあなたのコードのいくつかのエラーを修正し、それをもう少し読みやすくするためにいくつかの変更を加えました(私は願っています)。最も重要なのは、衝突検出を拡張して、速度が外に出た場合にボックスの座標をキャンバスの境界にリセットするようにしたことです。

さらに議論が必要な場合に便利なjsfiddleを作成しました。

于 2012-04-05T00:10:32.160 に答える
0

It was additional code (see edit) that I left out assuming it was unrelated to the issue, but removing the code solved the problem as it appears this use-case would cause an invalid input in this part of the code.

于 2012-04-05T18:56:12.020 に答える