Bounce: Bounce.html

<!DOCTYPE html>

<html>
<head>

<title>Comp 86 example Bounce</title>
<!-- Based on: http://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_building_practice -->

<script>
"use strict";

/*
 **************************************************
 * Main class 
 **************************************************
 */
class Main {
	constructor () {
		// Save these, for convenience
		this._ctx = myCanvas.getContext("2d"); //*5 General set up
		myCanvas.width = window.innerWidth; //*5
		myCanvas.height = window.innerHeight; //*5

		// Create list of circles
		this._circles = [] //*5
		for (let i=0; i<100; i++) { //*5
			this._circles.push(new Circle ( //*5
				random (0, myCanvas.width), //*5
				random (0, myCanvas.height),  //*5
				random (-4, 4),  //*5
				random (-4, 4),  //*5
				'rgb(' + random (0,255) + ',' + random(0,255) + ',' + random(0,255) +')',  //*5
				random (10,20)));  //*5
		}

		this.loop()
	}

	// Update everything and redraw for animation loop
	loop() { //*6 Animation
		this._ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; //*6
		this._ctx.fillRect(0, 0, myCanvas.width, myCanvas.height); //*6

		for (let c of this._circles) { //*6
			c.draw(this._ctx); //*6
			c.update(this._circles); //*6
		}

		// Set up for next frame, use arrow function to override "this"
		requestAnimationFrame(() => this.loop()); //*6
	}
}

class Circle { //*1 Circle class, like Square
	constructor (x, y, velX, velY, color, size) { //*2 Maintains info
		this._x = x; //*2
		this._y = y; //*2
		this._velX = velX;  //*2
		this._velY = velY;  //*2
		this._color = color;  //*2
		this._size = size;  //*2
	}

	draw (ctx) { //*3 Knows how to draw itself when told
		ctx.beginPath (); //*3
		ctx.fillStyle = this._color; //*3
		ctx.arc (this._x, this._y, this._size, 0, 2 * Math.PI); //*3
		ctx.fill (); //*3
	}

	update (circles) { //*4 Knows how to update itself when told
		// Check if circle has hit edge of canvas
		if ((this._x + this._size) >= myCanvas.width) { //*4
			this._velX = -(this._velX); //*4
		}

		if ((this._x - this._size) <= 0) { //*4
			this._velX = -(this._velX); //*4
		}

		if ((this._y + this._size) >= myCanvas.height) { //*4
			this._velY = -(this._velY); //*4
		}

		if ((this._y - this._size) <= 0) { //*4
			this._velY = -(this._velY); //*4
		}

		// Check if circle has hit another circle
		for (let c of circles) { //*7 Check for collision
			if (!(this === c)) { //*7
				let dx = this._x - c._x; //*7
				let dy = this._y - c._y; //*7
				let distance = Math.sqrt(dx*dx + dy*dy); //*7
				if (distance < this._size + c._size) { //*7
					c._color = this._color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')'; //*7
				}
			}
		}

		this._x += this._velX; //*4
		this._y += this._velY; //*4
	}
}

// Utility function, generate random integer between min and max
function random(min,max) {
	return Math.floor (Math.random() * (max-min)) + min;
}

/*
 **************************************************
 * Initialize
 **************************************************
 */

window.onload = function () { //*8 Initialize
	// Just instantiate, and loop the first time, which will trigger the next times
	new Main() //*8
}

</script>

</head>

<body>
<h1>Bouncing Circles</h1>
<canvas id="myCanvas"></canvas>
</body>

</html>
[download file]