├── bg.png
├── main.css
├── README.md
├── physics.js
├── fps.js
├── request-animation-frame.js
├── index.html
├── game-loop.js
└── ball.js
/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnars/blockout/master/bg.png
--------------------------------------------------------------------------------
/main.css:
--------------------------------------------------------------------------------
1 | body {background: #669;}
2 | #game {background: #000 url(bg.png);}
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blockout
2 |
3 | Recreating one of my first games for the web to learn Canvas.
4 |
--------------------------------------------------------------------------------
/physics.js:
--------------------------------------------------------------------------------
1 | var BLOCKS = this.BLOCKS || {};
2 |
3 | BLOCKS.physics = {};
4 |
5 | BLOCKS.physics.a = 0.5; // px/s^2, acceleration
6 |
--------------------------------------------------------------------------------
/fps.js:
--------------------------------------------------------------------------------
1 | var BLOCKS = this.BLOCKS || {};
2 |
3 | (function (B) {
4 |
5 | var lastTime = +new Date();
6 |
7 | B.calculateFPS = function () {
8 | var now = +new Date(),
9 | fps = 1000 / (now - lastTime);
10 | lastTime = now;
11 |
12 | return fps;
13 | };
14 |
15 | }(BLOCKS));
16 |
--------------------------------------------------------------------------------
/request-animation-frame.js:
--------------------------------------------------------------------------------
1 | window.requestNextAnimationFrame = window.requestAnimationFrame ||
2 | window.webkitRequestAnimationFrame ||
3 | window.mozRequestAnimationFrame ||
4 | window.msRequestAnimationFrame ||
5 | window.oRequestAnimationFrame ||
6 | alert("Your browser does not support proper animation. May I suggest Chrome?");
7 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Blockout
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/game-loop.js:
--------------------------------------------------------------------------------
1 | var canvas = document.getElementById("game");
2 | var ctx = canvas.getContext("2d");
3 |
4 | var world = {
5 | width: canvas.width,
6 | height: canvas.height
7 | };
8 |
9 | var ball = BLOCKS.ball.create(75, 75, 250, 0);
10 |
11 | ctx.fillStyle = "rgba(255, 255, 255, 1);";
12 |
13 | function renderWorld() {
14 | world.fps = BLOCKS.calculateFPS();
15 | ctx.clearRect(0, 0, world.width, world.height);
16 | ball.tick(world);
17 | ball.draw(ctx);
18 | window.requestNextAnimationFrame(renderWorld);
19 | }
20 |
21 | window.requestNextAnimationFrame(renderWorld);
22 |
--------------------------------------------------------------------------------
/ball.js:
--------------------------------------------------------------------------------
1 | var BLOCKS = this.BLOCKS || {};
2 |
3 | BLOCKS.ball = {
4 | create: function (x, y, vx, vy) {
5 | var instance = Object.create(this);
6 |
7 | instance.x = x; // px from 0, x position
8 | instance.y = y; // px from 0, y position
9 | instance.vx = vx; // px/s, x velocity
10 | instance.vy = vy; // px/s, y velocity
11 |
12 | return instance;
13 | }
14 | };
15 |
16 | BLOCKS.ball.draw = function (ctx) {
17 | ctx.beginPath();
18 | ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, true);
19 | ctx.fill();
20 | };
21 |
22 | BLOCKS.ball.tick = function (world) {
23 | this.adjustXVelocity(world);
24 | this.adjustYVelocity(world);
25 | this.x += this.vx / world.fps;
26 | this.y += this.vy / world.fps;
27 | };
28 |
29 | BLOCKS.ball.adjustYVelocity = function (world) {
30 | var bottomEdgeY = this.y + this.r;
31 | if (bottomEdgeY < world.height) {
32 | this.vy += (this.terminalVelocity - this.vy) * BLOCKS.physics.a / world.fps;
33 | } else if (bottomEdgeY > world.height) {
34 | this.vy *= -1 * this.e;
35 | this.vx *= this.f;
36 | this.y = world.height - this.r;
37 | }
38 | };
39 |
40 | BLOCKS.ball.adjustXVelocity = function (world) {
41 | if (this.x + this.r > world.width) {
42 | this.vx *= -1 * this.e;
43 | this.vy *= this.f;
44 | this.x = world.width - this.r;
45 | } else if (this.x - this.r < 0) {
46 | this.vx *= -1 * this.e;
47 | this.vy *= this.f;
48 | this.x = this.r;
49 | }
50 | };
51 |
52 | BLOCKS.ball.terminalVelocity = 1000; // px/s
53 | BLOCKS.ball.e = 0.8; // %, coefficient of restitution
54 | BLOCKS.ball.f = 0.8; // %, friction
55 | BLOCKS.ball.r = 20; // px, radius
56 |
--------------------------------------------------------------------------------