Skip to content

Instantly share code, notes, and snippets.

@bzdgn
Created December 18, 2016 10:51
Show Gist options
  • Save bzdgn/859de07fedffcd05d7816b27a7b0fb33 to your computer and use it in GitHub Desktop.
Save bzdgn/859de07fedffcd05d7816b27a7b0fb33 to your computer and use it in GitHub Desktop.
2D World Physics : Particles Explosion Demo
<!DOCTYPE html>
<html>
<head>
<title>2D World Physics : Particles Explosion Demo</title>
</head>
<body>
<canvas width="800" height="600" id="mainCanvas" onmousedown="handleMouseClick(event)" >
</canvas>
<script>
<!-- Written by Levent Divilioglu -->
<!-- 18.12.2016 -->
(function () {
// globals
canvas = document.getElementById('mainCanvas');
ctx = canvas.getContext("2d");
WIDTH = canvas.width;
HEIGHT = canvas.height;
GRAVITY = 4;
FRICTION = 0.94;
ctx.fillStyle="black";
ctx.fillRect( 0, 0, WIDTH, HEIGHT);
GRAVITY = 10;
var RADIUS = 30;
clickState = false;
refreshState = false;
var numOfBalls = 1000;
var r = 3;
var v_max = 150;
var creationRadius = 10;
var creationX = WIDTH/2;
var creationY = HEIGHT/3;
var genBalls = generateBalls(numOfBalls, r, v_max, creationRadius, creationX, creationY);
setInterval( function() { animate(genBalls); } , 50 )
})();
// main loop
function animate(balls) {
clearScreen();
if(clickState) {
handleBalls(balls);
}
mainDraw(balls);
}
function handleBalls(balls) {
for(var i = 0; i < balls.length; i++) {
handleBall(balls[i]);
}
}
function handleMouseClick(e) {
if(e.button === 0) {
clickState = true;
}
}
function generateBalls(numOfBalls, radius, v_max, creationRadius, creationX, creationY) {
var balls = [];
for(var i = 0; i < numOfBalls; i++) {
var x_start = creationX - creationRadius + radius;
var x_end = creationX + creationRadius - radius;
var y_start = creationY - creationRadius + radius;
var y_end = creationY + creationRadius - radius;
var x = getRandomInterval(x_start, x_end);
var y = getCircleY(x, getRandomInterval(0, creationRadius), creationX, creationY)
var v_x = getRandomInterval(-v_max, v_max);
var v_y = getRandomInterval(-v_max, v_max);
var ball = { 'r' : radius, 'x': x, 'y': y, 'v_x': v_x, 'v_y': v_y, 'holdState': false, 'onGround': false };
balls.push(ball);
}
return balls;
}
function getCircleY(x, cR, xo, yo) {
return getRandomSign()*Math.ceil( Math.sqrt( cR*cR - (x-xo)*(x-xo)) ) + yo;
}
function handleBall(ball) {
if(ball.holdState) {
ball.x = mouse.mX;
ball.y = mouse.mY;
} else {
ball.v_y += GRAVITY;
if(ball.onGround) {
ball.v_x *= FRICTION;
}
ball.x += ball.v_x;
ball.y += ball.v_y;
if( (ball.v_y > 0 && ball.y + ball.r > HEIGHT) || (ball.v_y < 0 && ball.y - ball.r < 0) ) {
ball.v_y *= -0.8;
if(ball.y + ball.r > HEIGHT) {
ball.y = HEIGHT - ball.r;
ball.onGround = true;
} else {
ball.onGround = false;
}
if(ball.y - ball.r < 0) {
ball.y = 0 + ball.r;
}
}
if( (ball.v_x > 0 && ball.x + ball.r > WIDTH) || (ball.v_x < 0 && ball.x - ball.r < 0) ) {
ball.v_x *= -0.8;
if(ball.x + ball.r > WIDTH) {
ball.x = WIDTH - ball.r;
} else if(ball.x - ball.r < 0) {
ball.x = 0 + ball.r;
}
}
}
}
function mainDraw(balls) {
for(var i = 0; i < balls.length; i++) {
drawBall(balls[i]);
}
}
function drawBall(ball) {
ctx.beginPath();
ctx.fillStyle="red";
ctx.arc(ball.x, ball.y, ball.r, 0, 2 * Math.PI, false);
ctx.fill();
}
function handleMouseMove(event) {
mouse.mX = event.clientX;
mouse.mY = event.clientY;
}
// refresh screen
function clearScreen() {
ctx.clearRect( 0, 0, WIDTH, HEIGHT );
ctx.fillStyle="black";
ctx.fillRect( 0, 0, WIDTH, HEIGHT );
}
function getRandomSign() {
var sign = Math.ceil(Math.random() * 100);
if(sign < 50)
return -1;
return 1;
}
// return set interval : [-limit, limit] - {0}
function getRandom(limit) {
var sign = Math.ceil( Math.random() * 100 );
if(sign < 50)
sign = -1;
else
sign = 1;
var num = sign * Math.ceil( (Math.random() * limit-1) + 1);
return num;
}
// return set interval : [1, limit]
function getRandomPositive(limit) {
return Math.ceil( (Math.random() * limit-1) + 1);
}
// return set interval : [a, b]
function getRandomInterval(a, b) {
return a - 1 + Math.ceil( Math.random()*(b-a+1) );
}
</script>
</body>
</html>
@bzdgn
Copy link
Author

bzdgn commented Dec 18, 2016

Left-click to start demo, here is a sample screenshot;

particlesexplosion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment