The Code:
<!DOCTYPE html>
<html>
<head>
<title>Simple Pong HTML5</title>
<!-- Create a nice raised field of play with a shadow for the canvas
i.e. use class = "gamePong" in the canvas declaration to link to the below style
-->
<style >
.gamePong
{
border-width: 1px;
border-style: solid;
border-color:#a1a1d0;
border-radius: 8px;
box-shadow: #a1a1d0 4px 4px 10px;
}
</style>
</head>
<body>
<canvas id="gameCanvas0" width="480" height="320" onmousemove="handleMouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var score = 0;
var gameOver = false;
var canvas_context = document.getElementById("gameCanvas0").getContext("2d");
var canvas_width = document.getElementById("gameCanvas0").width;
var canvas_height = document.getElementById("gameCanvas0").height;
var FPS = 30;
var mouseX = -1;
var mouseY = -1;
var mouse = {};
// We will use baseRectangle as a parent "class"
function baseRectangle()
{
this.color = "#a1a1d0";
this.width = 16;
this.height = 16;
this.x = 1;
this.y = 1;
// Define draw() to be a member function of the baseRectangle "class"
this.draw = function()
{
canvas_context.fillStyle = this.color;
canvas_context.fillRect(this.x, this.y, this.width, this.height);
}
this.directionX = 1;
this.directionY = 1;
}
// Below we see that other classes inherit from baseRectangle
function gameBall()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.x = canvas_width / 2;
this.y = canvas_height - this.height - 1;
this.directionX = 1;
this.directionY = -1;
}
function wall()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.height = canvas_height;
this.x = canvas_width - this.width;
this.y = 0;
}
// player is the paddle
function player()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.width = 16;
this.height = 64;
this.x = 0;
this.y = (canvas_height/2) - (this.height/2);
}
// We need a text class to display the score and such
function baseText()
{
this.text = "";
this.color = "#000000";
this.x = 17;
this.y = 17;
// This class like baseRectangle, needs a member draw function
this.draw = function()
{
canvas_context.fillStyle = this.color;
canvas_context.fillText(this.text, this.x, this.y);
}
}
// Move the ball around
function moveBall(_ball, _player)
{
var ballSpeed = 5;
// Bounce off right side of the canvas and player's paddle
// We will check elsewhere for game over criteria
if ((_ball.x >= canvas_width-_ball.width - rightWall.width) || (collides(_player, _ball)) )
{
_ball.directionX = (-1) * _ball.directionX;
}
// Bounce off the top and bottom of the canvas
if ((_ball.y >= canvas_height - _ball.height) || (_ball.y <= 0))
{
_ball.directionY = (-1) * _ball.directionY;
}
_ball.x += _ball.directionX*ballSpeed;
_ball.y += _ball.directionY*ballSpeed;
}
// Move the player's paddle
function movePlayer(_player)
{
if ( (mouseX > 0) && (mouseY > (_player.height/2)) && (_player.y > 0) )
{
_player.y = mouseY - (_player.height / 2);
}
}
function handleMouseMove(evt)
{
// The below 2 lines work most of the time, but not always
//mouseX = evt.clientX - document.getElementById("gameCanvas0").offsetLeft;
//mouseY = evt.clientY - document.getElementById("gameCanvas0").offsetTop;
// If they do not, the canvas is likely
// embedded in a... complex fashion... in a document
// so try using the following
var rect = document.getElementById("gameCanvas0").getBoundingClientRect();
mouseX = evt.clientX - rect.left;
mouseY = evt.clientY - rect.top;
}
function handleMouseOut()
{
// If mouse moves off the canvas, set its position to NOT be applied to paddle
mouseX = -1;
mouseY = -1;
}
// Check for collisions
function collides(a, b)
{
// Is the below easy to read? Should it be done better?
return a.x <= b.x + b.width
&& a.x + a.width >= b.x
&& a.y <= b.y + b.height
&& a.y + a.height >= b.y;
}
// Did the ball go past the paddle to the left?
function isGameOver(_player, _ball)
{
return (_ball.x <= 16) && (!(collides(_player, _ball)));
}
// Create the global game objects
var ball = new gameBall();
var rightWall = new wall();
var player1 = new player();
var scoreText = new baseText();
// Update routine for the global objects
function update()
{
if (!gameOver)
{
gameOver = isGameOver(player1, ball);
}
if ((collides(player1, ball)) && (!gameOver))
{
score++;
}
if (gameOver)
{
scoreText.text = "Game Over. Press [F5] to play again. Score : " + score;
}
else
{
moveBall(ball, player1);
scoreText.text = "Score : " + score;
}
movePlayer(player1);
}
// Render objects to the canvas
// Use the member draw() functions
function draw()
{
canvas_context.clearRect(0, 0, canvas_width, canvas_height);
player1.draw();
rightWall.draw();
if (!gameOver)
{
ball.draw();
}
scoreText.draw();
}
// Main game loop
setInterval(function()
{
update();
draw();
}, 1000 / FPS);
// Could also use 2 setInterval calls here:
//setInterval(update, 1000 / FPS);
//setInterval(draw, 1000 / FPS);
</script>
</body>
</html>
<html>
<head>
<title>Simple Pong HTML5</title>
<!-- Create a nice raised field of play with a shadow for the canvas
i.e. use class = "gamePong" in the canvas declaration to link to the below style
-->
<style >
.gamePong
{
border-width: 1px;
border-style: solid;
border-color:#a1a1d0;
border-radius: 8px;
box-shadow: #a1a1d0 4px 4px 10px;
}
</style>
</head>
<body>
<canvas id="gameCanvas0" width="480" height="320" onmousemove="handleMouseMove(event)">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var score = 0;
var gameOver = false;
var canvas_context = document.getElementById("gameCanvas0").getContext("2d");
var canvas_width = document.getElementById("gameCanvas0").width;
var canvas_height = document.getElementById("gameCanvas0").height;
var FPS = 30;
var mouseX = -1;
var mouseY = -1;
var mouse = {};
// We will use baseRectangle as a parent "class"
function baseRectangle()
{
this.color = "#a1a1d0";
this.width = 16;
this.height = 16;
this.x = 1;
this.y = 1;
// Define draw() to be a member function of the baseRectangle "class"
this.draw = function()
{
canvas_context.fillStyle = this.color;
canvas_context.fillRect(this.x, this.y, this.width, this.height);
}
this.directionX = 1;
this.directionY = 1;
}
// Below we see that other classes inherit from baseRectangle
function gameBall()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.x = canvas_width / 2;
this.y = canvas_height - this.height - 1;
this.directionX = 1;
this.directionY = -1;
}
function wall()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.height = canvas_height;
this.x = canvas_width - this.width;
this.y = 0;
}
// player is the paddle
function player()
{
this.superclass = baseRectangle;
this.prototype = new this.superclass;
this.superclass();
delete this.superclass;
this.width = 16;
this.height = 64;
this.x = 0;
this.y = (canvas_height/2) - (this.height/2);
}
// We need a text class to display the score and such
function baseText()
{
this.text = "";
this.color = "#000000";
this.x = 17;
this.y = 17;
// This class like baseRectangle, needs a member draw function
this.draw = function()
{
canvas_context.fillStyle = this.color;
canvas_context.fillText(this.text, this.x, this.y);
}
}
// Move the ball around
function moveBall(_ball, _player)
{
var ballSpeed = 5;
// Bounce off right side of the canvas and player's paddle
// We will check elsewhere for game over criteria
if ((_ball.x >= canvas_width-_ball.width - rightWall.width) || (collides(_player, _ball)) )
{
_ball.directionX = (-1) * _ball.directionX;
}
// Bounce off the top and bottom of the canvas
if ((_ball.y >= canvas_height - _ball.height) || (_ball.y <= 0))
{
_ball.directionY = (-1) * _ball.directionY;
}
_ball.x += _ball.directionX*ballSpeed;
_ball.y += _ball.directionY*ballSpeed;
}
// Move the player's paddle
function movePlayer(_player)
{
if ( (mouseX > 0) && (mouseY > (_player.height/2)) && (_player.y > 0) )
{
_player.y = mouseY - (_player.height / 2);
}
}
function handleMouseMove(evt)
{
// The below 2 lines work most of the time, but not always
//mouseX = evt.clientX - document.getElementById("gameCanvas0").offsetLeft;
//mouseY = evt.clientY - document.getElementById("gameCanvas0").offsetTop;
// If they do not, the canvas is likely
// embedded in a... complex fashion... in a document
// so try using the following
var rect = document.getElementById("gameCanvas0").getBoundingClientRect();
mouseX = evt.clientX - rect.left;
mouseY = evt.clientY - rect.top;
}
function handleMouseOut()
{
// If mouse moves off the canvas, set its position to NOT be applied to paddle
mouseX = -1;
mouseY = -1;
}
// Check for collisions
function collides(a, b)
{
// Is the below easy to read? Should it be done better?
return a.x <= b.x + b.width
&& a.x + a.width >= b.x
&& a.y <= b.y + b.height
&& a.y + a.height >= b.y;
}
// Did the ball go past the paddle to the left?
function isGameOver(_player, _ball)
{
return (_ball.x <= 16) && (!(collides(_player, _ball)));
}
// Create the global game objects
var ball = new gameBall();
var rightWall = new wall();
var player1 = new player();
var scoreText = new baseText();
// Update routine for the global objects
function update()
{
if (!gameOver)
{
gameOver = isGameOver(player1, ball);
}
if ((collides(player1, ball)) && (!gameOver))
{
score++;
}
if (gameOver)
{
scoreText.text = "Game Over. Press [F5] to play again. Score : " + score;
}
else
{
moveBall(ball, player1);
scoreText.text = "Score : " + score;
}
movePlayer(player1);
}
// Render objects to the canvas
// Use the member draw() functions
function draw()
{
canvas_context.clearRect(0, 0, canvas_width, canvas_height);
player1.draw();
rightWall.draw();
if (!gameOver)
{
ball.draw();
}
scoreText.draw();
}
// Main game loop
setInterval(function()
{
update();
draw();
}, 1000 / FPS);
// Could also use 2 setInterval calls here:
//setInterval(update, 1000 / FPS);
//setInterval(draw, 1000 / FPS);
</script>
</body>
</html>