1

キャンバスの周りでボールをバウンドさせることになっている HTML が少しありますが、座標を格納する配列をランダムな位置に設定して でテストすると、「NaN」のように見えますalert("Co-ordinates " + (cirX[i]) + " x " + (cirY[i]));。これは、「座標 NaN x NaN」を返します。私はアレイなしで1つのボールでそれをやろうとしましたが、うまくいきました。配列のコーディングが悪いのか、それとも別のものなのかはわかりません。ここに私のHTMLがあります:

<!Doctype HTML>
<head>
<script>
var cirX = [];
var cirY = [];
var chX = [];
var chY = [];
var width;
var height;

function initCircle(nBalls) {
  alert(nBalls)
  for(var i = 0; i<nBalls;i++) {
    alert("loop  " + i)
    chX[i] = (Math.floor(Math.random()*200)/10);
    chY[i] = (Math.floor(Math.random()*200)/10);
    cirX[i] = Math.floor(Math.random()*width);
    cirY[i] = Math.floor(Math.random()*height);
    alert("Co-ordinates " + (cirX[i]) + " x " + (cirY[i]));

    circle(cirX[i],cirY[i],3);
    setInterval('moveBall(i)',10);
  }
}

function moveBall(ballNum) {
    if(cirX[ballNum] > width||cirX[ballNum] < 0) {
      chX[ballNum] = 0-chX[ballNum];
    }
    if(cirY[ballNum] > height|| cirY[ballNum] < 0) {
      chY[ballNum] = 0-chY[ballNum];
    }
    cirX[ballNum] = cirX[ballNum] + chX[ballNum];
    cirY[ballNum] = cirY[ballNum] + chY[ballNum];
    circle(cirX[ballNum],cirY[ballNum],3);

}

function circle(x,y,r) {
  var c=document.getElementById("canvas");
  var ctx=c.getContext("2d");
  canvas.width = canvas.width;
  ctx.fillStyle="#FF0000";
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI*2, true);
  ctx.fill();
  width = canvas.width;
  height = canvas.height;
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300">
</canvas>
<script>
initCircle(3); //this sets the number of circles
</script>
</body>

配列などを初期化する方法を調べましたが、正しくやっているようですか? よろしくお願いします。

編集:
上記の問題を修正したにもかかわらず、変数ballNummoveBall()予想どおり 0 から 2 まで変化するにもかかわらず、1 つのボールだけがさまざまな速度で移動します ( を追加してテストalert(ballNum))。誰かが理由を知っていますか?

4

3 に答える 3

1

あなたはこの行を呼び出します

cirX[i] = Math.floor(Math.random()*width);

whenwidthはまだ定義されていません。NaNしたがって、結果としてのみ得ることができます。

moveBallsetInterval から関数を適切に呼び出すには、次を使用できます。

(function(i) { // embedds i to protect its value (so that it isn't the one of end of loop
   setInterval(function(){moveBall(i)}, 10);
})(i);
于 2013-03-05T19:54:27.410 に答える
1

これはwidth、ステートメントが初めて実行されるときに定義されていないためです。最初にキャンバスとその寸法を取得し、それをグローバルに保つことができます。

http://jsbin.com/agavoq/9/edit

setInterval を呼び出すには、値を保持する自己呼び出し関数を使用できます。i

(function(x){
  setInterval(moveBall,10, x);
})(i);

または単に

setInterval(moveBall,10, i);

または

setInterval('moveBall(' + i+ ')',10);
于 2013-03-05T20:00:26.317 に答える
0

この行を見ると、別の問題が発生します

setInterval('moveBall(i)',10);

それiはあなたが思っているものではありません。では文字列を使用しないでくださいsetTimeout

于 2013-03-05T19:53:04.707 に答える