2010-11-29 21 views
1

こんにちは私は、次のキャンバスアプリケーションを持っています。私が抱えている問題は、アプリが最初に起動したときに、ボールがキャンバスの端でカットされているということです。彼らはそれをするべきではありません彼らはそれに触れる場合は、キャンバスの端から跳ね返る必要があります!HTML5キャンバス物理

物理を分類するのが難しいですが、マウスを動かすと跳ね返りますが、起動時には動きません。

THANKS

答えて

0

あなたは物理学のためのBox2Dを使用することができます。

1

あなたはとなります。 Mozilla Developer Networkの記事:Basic Animations

私が知る限り、キャンバスはcanvas.restore()関数で変更されるたびに更新する必要があります。

+0

私は古いバージョンのアプリケーションで作業していましたが、その機能を使用しませんでした:http://dev.driz.co.uk/app/ – Cameron

+0

ああ、私は ''要素を使ったことが一度もなかったので、もう一度やります。私は今あなたのデモで遊んでいます... – Blender

+0

唯一の違いは、2番目のデモで 'setInterval()'メソッドを使用しなかったことです。 MDNの記事では、 '.restore()'メソッドと 'setInterval()'メソッドの2つのアニメーション方法について説明しました。私はどちらも見ていないので、一緒に作業デモをハックさせてください... – Blender

2

ボールが切断されている(壁を越えている)場合は、それを壁に再配置するか、壁から離れたボールを移動する方向に移動します。

ボールが壁から3ピクセル先にある場合、壁から新しい方向に3ピクセル離れた位置に置くことができます。

これは、期間が短すぎるとボールが速すぎて修正できない場合に役立ちます。

UPDATE:

私はそれがChromeで動いても、それはFirefoxの4B7に描くんが、あなたのコードを見て、この行が問題になることがあり見ることができない何らかの理由で、あなたのコードを見た後、 :

Balls[i].x += Balls[i].vx; 

x + vx < 0場合、それはまだ壁の左になります。

オフにできる理由は、このコードがあります。Balls[i].vx *= 0.99;です。これは、チェックを行う前にvxに減少し続けます。調整した後、これを最後に置くことができます。

また、同じif文ブロックに左右の壁のコードがありますが、別々に処理する必要があります。

この問題を解決するには、FirebugをFirefoxで1つのボールで使用し、壁を過ぎたときにbreakステートメントを入れて、各ステップで値が何であるかを確認することです。

また、調整するときにボールが一直線上を移動すると仮定していますが、どちらの方向に修正するかは、ifが失敗した場合に応じて行いますが、コーナーの場合には可能ですどちらも失敗する。それはあなたの物理モデルの失敗です.45度の角度で壁に当たった場合、壁が理想的であれば、45度の角度で跳ね返ります。

Chrome、IE、Firefoxのデバッガの使い方を学ぶのは良いことですが、私はFirebugを使用した方がいいかもしれません。

2

はここではない、VX

のvXあなたの構文を使用してあなたが問題を抱えていた修正

if (ball[i].x - ball[i].r <= 0 || ball[i].x + ball[i].r >= cwidth) { 
    ball[i].vx = -ball[i].vx; 
    ball[i].x += ball[i].vx; 
} 

if (ball[i].y - ball[i].r <= 0 || ball[i].y + ball[i].r >= cheight) { 
    ball[i].vy = -ball[i].vy; 
    ball[i].y += ball[i].vy; 
} 
+0

ボールはまだキャンバスの縁で切り取られているようだが、起動時にそれを跳ね返らない。私は最初のループを変更して、ボールをランダムに配置するようにしました。 'x = Math.random()* cwidth >> 0; y = Math.random()* cheight >> 0; 'しかし、それらのいくつかは、マウスで移動しない限り、オフセットされて表示されます。例えばhttp://dev.driz.co.uk/pool – Cameron

+0

基本的な数学を学ぶことをお勧めします。真実のおい、私はあなたに子供を育てようとはしていません..大丈夫です、ちょうどmin && maxの値を追加して、範囲を設定し、範囲の間にランダムな点を設定してください... –

+0

'x = min + Math.random )*((幅 - 分) - 分) –

0

です。 vyではありません。

さらに、レンダリングのために関数を呼び出す必要がありました。 最終結果をjsdo.itに投稿します(物理を終了した時点)。本当にクールだ。

 
window.onload=App 
function App() { 
    var pool = document.getElementById('pool'); 
    var canvas = pool.getContext('2d'); 
    var cwidth = pool.width = window.innerWidth; 
    var cheight = pool.height = window.innerHeight; 
    var ctop = pool.offsetTop; 
    var cleft = pool.offsetLeft; 
    var size = [5, 10, 15, 20, 25, 30]; 
    var numBalls = 100; 
    // CREATES THE BALL 
    function Ball(x, y, vx, vy, r, s) { 
     this.color = rgb(); 
     this.x = x; 
     this.y = y; 
     this.vX = vx; 
     this.vY = vy; 
     this.r = r; 
     this.size = s; 
    } 
    // GIVES EACH BALL A RANDOM COLOR 
    function rgb() { 
     var color = 'rgb('; 
     for (var i = 0; i < 3; i++) { 
      color += Math.floor(Math.random() * 255) + ','; 
     } 
     return color.replace(/\,$/, ')'); 
    } 
    var Balls = [], 
     x, y, vx, vy, r, s;

for (var i = 0; i < numBalls; i++) { 
    x = Math.random() * cwidth >> 0; 
    y = Math.random() * cheight >> 0; 
    vx = Math.random() * 20 - 6; 
    vy = Math.random() * 20 - 6; 
    r = Math.random() * 15 + 30; 
    s = size[~~(Math.random() * size.length >> 0)]; 

    // CREATES THE BALLS 
    Balls.push(new Ball(x, y, vx, vy, r, s)); 
} 
function render(){ 
// DRAWS THE CANVAS AND BALLS 

// PHYSICS Balls.map(関数(アイテム){// ボールが跳ね返るSHOULDキャンバスEDGE
item.vX * = 150; item.vY * = 150;

item.x += item.vX; 
    item.y += item.vY; 

    if (item.x < item.r){ 
     item.vX *= -.99; 
     item.x += item.vX; 
    } 
    if(item.x > pool.width - item.r) { 
     item.vX *= -.99; 
     item.x += item.vX; 
    } 
    if (item.y < item.r){ 
     item.vY *= -.99; 
     item.y += item.vY; 
    } 
    if(item.y > pool.height - item.r) { 
     item.vY *= -1; 
     item.y += item.vY; 
    } 

} // END PHYSICS canvas.clearRect(0、0、canvas.canvas.width、canvas.canvas.height);

for (var i in Balls) { 
    var b = Balls[i]; 

     var grad = canvas.createRadialGradient(b.x + b.r/4 , b.y - b.r/4 , b.r/5 , b.x, b.y, b.r); 
     grad.addColorStop(0, '#fff'); 
     grad.addColorStop(.85, b.color); 
     grad.addColorStop(1, '#222'); 
     canvas.beginPath(); 
     canvas.fillStyle = grad; 
     canvas.arc(b.x, b.y, b.r, 0, Math.PI * 2, 0); 
     canvas.fill(); 
} 

}

// END FOR 
// MOUSE MOVEMENT - BALLS SHOULD MOVE AWAY FROM MOUSE CURSOR 
pool.onmousemove = function(e) { 
    x = e.pageX - this.offsetLeft; 
    y = e.pageY - this.offsetTop; 

    for (i = 0; i < numBalls; i++) { 
     if (Math.abs(x - Balls[i].x) < 20 && Math.abs(y - Balls[i].y) < 20) { 
      Balls[i].vX = (x - Balls[i].x) ; 
      Balls[i].vY = (y - Balls[i].y) ; 

     } 
    } 
}; 

たsetInterval(レンダリング、50)。

// END APP

}

関連する問題