This was a student project that recreated everyone's favorite game- a game in which you move a paddle around to keep a ball up in the air to ensure it breaks all the bricks on the screen. The game had three rounds with different patterns of bricks to break, and it also kept score.
Built by Krista Handel and Cameron Buscher
Previously we had built small applications where all of our javascript was housed in a single file. One of the main goals we had for this project was to piece out different bits of functionality and give them their own files. This was easy to do, considering we were also implementing Object Oriented Programming. For each feature of our game we created a class that would take care of the functionality of that specific feature. This was the point where I realized how beautiful programming really was- I had gone from creating a single, ugly javascript file for my projects to separating out functionality based on concerns. This led to more readable code and made the writing process a bit easier because our focus was more clear.
We also focused on writing a test suite for the functionality of our client-side application. Having the separate classes handling the different bits of functionality made the application easier to test.
- Clone down the repository
git clone https://github.com/meloncatty/game-time.git
- cd into the repository and install the dependencies:
npm install
To see this code in action, you need to fire up a development server. Use the command:
npm start
Once the server is running, visit in your browser:
http://localhost:8080/webpack-dev-server/
to run the application.http://localhost:8080/webpack-dev-server/test.html
to run the test suite in the browser.
To run all of the tests:
npm test
Webpack is a little opinionated about how files are organized. Here is a brief guide on how to organize development and test files.
Node and webpack work together to help us organize our files and keep responsibilities separated.
For example, if we have the lib/index.js
file and a lib/Block.js
file:
lib/index.js
var Block = require('./Block');
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
var blocks = [];
blocks.push(new Block(50, 50, 10, 10, context));
blocks.push(new Block(100, 50, 10, 10, context));
requestAnimationFrame(function gameLoop() {
context.clearRect(0, 0, canvas.width, canvas.height);
this.blocks.forEach(function(block){
block.draw()
block.move()
})
requestAnimationFrame(gameLoop);
});
lib/Block.js
function Block(x, y, width, height, context) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.context = context;
}
Block.prototype.draw = function () {
this.context.fillRect(this.x, this.y, this.width, this.height);
};
Block.prototype.move = function () {
this.y++;
};
module.exports = Block;
All of the Block.js
code could live in the index.js
file, but that would go against our philosophy of separating responsibility between files.
There are two main things to pay attention to here:
-
At the top of the
index.js
file, we require theBlock.js
file using the line of codevar Block = require('./Block');
(we leave out the.js
). This brings in the code from theBlock.js
file so we can use that file's code in theindex.js
file. -
In the
Block.js
file, the bottom line saysmodule.exports = Block;
which says what we want this file to export when we sayrequire
in other files, like inindex.js
.
So now we have two files that can share code between each other, but we have to pay attention to what we export and what we require. If we didn't do this, then when we try to make a new Block in the index.js
file, it won't know what Block we're talking about!
Near the end of game time, we had multiple objects for our game that are tested separately with individual test files. The test/index.js
file serves as an "entry point" for mocha to load all of the tests we wrote.
Test file organization is a bit different from development files. If we want to test the Block.js
file from above, we would need to have a corresponding test file. So in the test
directory, we created a new file called test/Block-test.js
. Here is what a basic outline of the file looks like:
test/Block-test.js
var chai = require('chai');
var assert = chai.assert;
var Block = require('../lib/Block');
describe('Block', function() {
context('with default attributes', function() {
// Your tests here...
});
});
test/index.js
require('./Block-test')
Two main points to pay attention to:
-
In the
Block-test.js
file, we require theBlock.js
file so that we can construct blocks in our tests. -
In the
test/index.js
file, we require theBlock-test.js
file so that we can view the test results in the browser (athttp://localhost:8080/webpack-dev-server/test.html
).