Last active
April 5, 2016 03:12
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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