Skip to content

Instantly share code, notes, and snippets.

@fabslab
Last active April 5, 2016 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabslab/7741255 to your computer and use it in GitHub Desktop.
Save fabslab/7741255 to your computer and use it in GitHub Desktop.
Pong game I started in JS one night so I could play with Canvas. Currently low on features but high on nostalgia.
(function() {
var requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback) { return window.setTimeout(callback, 1000/60); };
var cancelAnimationFrame =
window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
clearTimeout;
// using modifiers library from https://github.com/fabienbrooke/modifiers
window.modifiers.add({
leftArrow: 37,
upArrow: 38,
rightArrow: 39,
downArrow: 40,
w: 87,
a: 65,
s: 83,
d: 68
});
var canvas = document.getElementsByTagName('canvas')[0];
var context = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var animationRequest;
var paddleVelocity = 10;
var ball = new Ball();
var topPaddles = [], bottomPaddles = [];
topPaddles.push(new Paddle({ pos: 'top' }));
bottomPaddles.push(new Paddle({ pos: 'bottom' }));
var paddles = topPaddles.concat(bottomPaddles);
function renderLoop() {
animationRequest = requestAnimationFrame(renderLoop);
paintBackground();
for(var i = 0; i < paddles.length; ++i) {
paddles[i].draw();
}
ball.draw();
var activeTop = topPaddles[0], activeBottom = bottomPaddles[0];
// move paddles according to players' keyboard inputs
// top player has w a s d
if (modifiers.a && activeTop.x >= 0) {
activeTop.x -= paddleVelocity;
}
else if (modifiers.d && activeTop.x + activeTop.width <= canvas.width) {
activeTop.x += paddleVelocity;
}
// bottom player has arrow keys
if (modifiers.leftArrow && activeBottom.x >= 0) {
activeBottom.x -= paddleVelocity;
}
else if (modifiers.rightArrow && activeBottom.x + activeBottom.width <= canvas.width) {
activeBottom.x += paddleVelocity;
}
if (isGameOver(ball)) {
endGame();
}
else if (isWallCollision(ball)) {
// reverse x direction
ball.vx = -ball.vx;
}
else if ((ball.vy < 0 && isPaddleTopCollision(ball, topPaddles)) ||
(ball.vy > 0 && isPaddleBottomCollision(ball, bottomPaddles))) {
// reverse y direction
ball.vy = -ball.vy;
}
ball.x += ball.vx;
ball.y += ball.vy;
}
function paintBackground() {
context.fillStyle = "#ffffff";
context.fillRect(0, 0, canvas.width, canvas.height);
}
// functions to check collision between ball and paddles
function isPaddleTopCollision(ball, paddles) {
for (var i = 0; i < paddles.length; ++i) {
// whether the ball is contained within the dimensions of a paddle while travelling up
if (!isXCollision(ball, paddles[i])) return false;
var yCollision = ball.y - ball.radius <= paddles[i].y + paddles[i].height;
return yCollision;
}
}
function isPaddleBottomCollision(ball, paddles) {
for (var i = 0; i < paddles.length; ++i) {
// whether the ball is contained within the dimensions of a paddle while travelling down
if (!isXCollision(ball, paddles[i])) return false;
var yCollision = ball.y + ball.radius >= paddles[i].y;
return yCollision;
}
}
function isXCollision(ball, paddle) {
return (ball.x + ball.radius >= paddle.x) && (ball.x - ball.radius <= paddle.x + paddle.width);
}
function isWallCollision(ball) {
// left or right side walls
return (ball.x - ball.radius <= 0 || ball.x + ball.radius >= canvas.width);
}
function isGameOver(ball) {
// if the ball hits the top/bottom the game ends
return (ball.y >= canvas.height || ball.y <= 0);
}
function endGame() {
cancelAnimationFrame(animationRequest);
}
function Paddle(options) {
this.height = 5;
this.width = 150;
this.color = '#000000';
if (options) {
for (var key in options) {
this[key] = options[key];
}
}
// paddle supports two positions in options: top or bottom
this.x = canvas.width/2 - this.width/2;
this.y = (this.pos == "top") ? 0 : canvas.height - this.height;
}
Paddle.prototype.draw = function() {
context.fillStyle = this.color;
context.fillRect(this.x, this.y, this.width, this.height);
}
function Ball(options) {
this.x = 50;
this.y = 50;
this.vx = 4;
this.vy = 8;
this.radius = 8;
this.color = '#000000';
if (options) {
for (var key in options) {
this[key] = options[key];
}
}
}
// Function for drawing ball on canvas
Ball.prototype.draw = function() {
context.beginPath();
context.fillStyle = this.color;
context.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
context.fill();
}
renderLoop();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment