var ctx = canvas.getContext('2d'); canvas.width = 500; canvas.height = 500; function Ball(_x, _y, _w, _h){ var x = _x, y = _y, w = _w, h = _h, color = [ Math.floor(Math.random() * 0xFF), Math.floor(Math.random() * 0xFF), Math.floor(Math.random() * 0xFF), ], vx = Math.floor(Math.random() * 40) + 1, // v for velocity vy = Math.floor(Math.random() * 2), gx = 0, // g for gravity gy = 9.8 * (w / 400), // 9.8 is the value of Earth's gravitational constant, but let's factor mass in too. bounceXMultiplier = -0.4, // when bouncing on a wall, the energy loss should probably be a lot harsher bounceYMultiplier = -(1 - 0.20 - 0.05); // let's have fun with this. // we'll assume there is a 20% energy loss from contact, and add 5% for air resistance. // This gives the amount of energy lost from a bounce. // You don't HAVE to do this. It could easily be something like -0.8 // Just enough to visibly reduce the absolute value function draw(){ ctx.fillStyle = "rgb(" + color[0] + "," + color[1] + "," + color[2] + ")"; ctx.fillRect(x, y, w, h); } function collisionFloor(){ return y + h >= canvas.height && vy > 0; } function collisionCeil(){ return y <= 0 && vy < 0; } function collisionLWall(){ return x <= 0 && vx < 0; } function collisionRWall(){ return x + w >= canvas.width && vx > 0; } function checkCollisions(){ if(collisionFloor()){ y = canvas.width - h; vy *= bounceYMultiplier; } if(collisionCeil()){ y = 0; vy *= bounceYMultiplier; } if(collisionLWall() || collisionRWall()){ vx *= bounceXMultiplier; } } function pub_jump(height){ vy -= height; } function pub_run(){// over here vx += gx; vy += gy; x += vx; y += vy; checkCollisions(); draw(); } this.run = pub_run; this.jump = pub_jump; } var GravityDemo = (function(){ var balls, interval, fps = 60; function drawBG(){ ctx.fillStyle = "#eee"; ctx.fillRect(0, 0, canvas.width, canvas.height); } function loop(){ var i; drawBG(); for(i = 0; i < balls.length; i++){ balls[i].run(); } } function gimmeSomeBalls(){ var i, numBalls = 10, out = [], tempX, tempY, tempS; for(i = 0; i < numBalls; i++){ tempX = i * 50; tempY = i * 10; tempS = 15 + (i * 5); // S for Size out.push(new Ball(tempX, tempY, tempS, tempS)); } return out; } function pub_jump(){ var i; for(i = 0; i < balls.length; i++){ balls[i].jump(20); } } function pub_main(){ balls = gimmeSomeBalls(); interval = setInterval(loop, 1000 / fps); } return { main: pub_main, jump: pub_jump, }; })(); GravityDemo.main(); canvas.onclick = GravityDemo.jump;
<canvas id=canvas></canvas>