I'm trying to adapt a code that I found googling for the Pong game. What I try is to replace the ball drawn by an image of a ball in image. Searching the Internet suggest that you use the following code:
var img = new Image(200,200);
img.src = "img.jpg";
contexto.clearRect(0,0,700,500);
contexto.drawImage(img, x, y);
Which insert almost at the end of the code in the "ball" section but this does not work for me, and sends error. Everything fails when I make the modification in pong js. when adding this line ctx.drawImage(img, x, y);
.
This is the js file called pong.js
//=============================================================================
// PONG
//=============================================================================
Pong = {
Defaults: {
width: 640, // logical canvas width (browser will scale to physical canvas size - which is controlled by @media css queries)
height: 480, // logical canvas height (ditto)
wallWidth: 10,
balls: 1,
stats: true
},
//-----------------------------------------------------------------------------
initialize: function(runner, cfg) {
this.cfg = cfg;
this.runner = runner;
this.width = runner.width;
this.height = runner.height;
this.court = Object.construct(Pong.Court, this);
this.balls = this.constructBalls();
this.runner.start();
},
constructBalls: function() {
var balls = [];
for(var n = 0 ; n < this.cfg.balls ; n++)
balls.push(Object.construct(Pong.Ball, this));
return balls;
},
update: function(dt) {
for(var n = 0 ; n < this.balls.length ; n++)
this.balls[n].update(dt);
},
draw: function(ctx) {
this.court.draw(ctx);
for(var n = 0 ; n < this.balls.length; n++)
this.balls[n].draw(ctx);
},
//==========
// COURT
//=============================================================================
Court: {
initialize: function(pong) {
var w = pong.width;
var h = pong.height;
var ww = pong.cfg.wallWidth;
this.walls = [];
this.walls.push({x: 0, y: 0, width: w, height: ww});
this.walls.push({x: 0, y: h - ww, width: w, height: ww});
this.walls.push({x: 0, y: 0, width: ww, height: h});
this.walls.push({x: w-ww, y: 0, width: ww, height: h});
},
draw: function(ctx) {
ctx.fillStyle = '#96ef10';
for(var n = 0 ; n < this.walls.length ; n++)
ctx.fillRect(this.walls[n].x, this.walls[n].y, this.walls[n].width, this.walls[n].height);
}
},
// BALL
//=============================================================================
Ball: {
initialize: function(pong) {
this.pong = pong;
this.radius = Game.random(1, 30);
this.minX = pong.cfg.wallWidth + this.radius;
this.minY = pong.cfg.wallWidth + this.radius;
this.maxX = pong.width - pong.cfg.wallWidth - this.radius;
this.maxY = pong.height - pong.cfg.wallWidth - this.radius;
this.x = Game.random(this.minX, this.maxX);
this.y = Game.random(this.minY, this.maxY);
this.dx = (this.maxX - this.minX) / (Game.random(1, 10) * Game.randomChoice(1, -1));
this.dy = (this.maxY - this.minY) / (Game.random(1, 10) * Game.randomChoice(1, -1));
},
update: function(dt, leftPaddle, rightPaddle) {
this.x = this.x + (this.dx * dt);
this.y = this.y + (this.dy * dt);
if ((this.dx > 0) && (this.x > this.maxX)) {
this.x = this.maxX;
this.dx = -this.dx;
}
else if ((this.dx < 0) && (this.x < this.minX)) {
this.x = this.minX;
this.dx = -this.dx;
}
if ((this.dy > 0) && (this.y > this.maxY)) {
this.y = this.maxY;
this.dy = -this.dy;
}
else if ((this.dy < 0) && (this.y < this.minY)) {
this.y = this.minY;
this.dy = -this.dy;
}
},
draw: function(ctx) {
var w = h = this.radius * 2;
var img = new Image(200,200);
img.src = "pelota.png";
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI, true);
ctx.fill();
// Si pongo esta linea ocurre el error /// ctx.drawImage(img, x, y);
ctx.closePath();
}
}
}; // Pong
Here I leave the complete code. It includes the pong.js file above and a second JS file called game.js that is a bit long, but it works correctly:
/**** GAME.JS *****/
/*
Pong implemented with HTML features.
Version: 1.1
Author: David Laurell <[email protected]>
License: GPLv3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
var game, canvas, ctx, soundLeft, soundRight, soundWall, gameTimeLast;
function init() {
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
soundLeft = document.getElementById("bounceLeft");
soundRight = document.getElementById("bounceRight");
soundWall = document.getElementById("bounceWall");
game = {
player : {
y : canvas.height / 2,
score : 0
},
computer : {
y : canvas.height / 2,
score : 0,
speed: 2
},
ball : {
x : canvas.width / 2,
y : canvas.height / 2,
vx : Math.round(Math.random()) ? 1 : -1,
vy : Math.random() * 4 - 2,
bounces : 0,
radius : 3,
reset: function() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.vy = Math.random() * 4 - 2;
},
multiplier: .2,
maxspeed: 5
},
playerHeight : 80,
playerWidth : 4,
pause : false,
sound: true
};
document.onmousemove = moveMouse;
gameTimeLast = new Date();
update();
}
function moveMouse(e) {
var y;
if(!e) {
e = window.event;
y = e.event.offsetY;
}
else {
y = e.pageY;
}
y -= canvas.offsetTop;
if(y - game.playerHeight/2 >= 0 && y + game.playerHeight/2 <= canvas.height)
game.player.y = y;
}
function playSound(snd) {
if(game.sound) {
try {
if (!snd.paused) {
// Pause and reset it
snd.pause();
snd.currentTime = 0;
}
snd.play();
}
catch(e) {}
}
}
function update() {
dateTime = new Date();
gameTime = (dateTime - gameTimeLast);
if(gameTime < 0)
gameTime = 0;
moveAmount = gameTime > 0 ? gameTime / 10 : 1;
if (!game.pause) {
/* Move cpu player */
if(game.computer.y + 20 < game.ball.y && game.computer.y + game.playerHeight/2 <= canvas.height)
game.computer.y += game.computer.speed * moveAmount;
else if(game.computer.y - 20 > game.ball.y && game.computer.y - game.playerHeight/2 >= 0)
game.computer.y -= game.computer.speed * moveAmount;
/* Change direction of ball when hitting a wall */
if (game.ball.y + game.ball.radius > canvas.height
|| game.ball.y - game.ball.radius < 0) {
playSound(soundWall);
if(game.ball.y <= game.ball.radius)
game.ball.y = game.ball.radius;
else
game.ball.y = canvas.height - game.ball.radius;
game.ball.vy *= -1;
}
/* checking collision between ball and player */
if (game.ball.x + game.ball.radius >= canvas.width - game.playerWidth) {
if (game.ball.y + game.ball.radius >= game.player.y - game.playerHeight / 2
&& game.ball.y + game.ball.radius <= game.player.y + game.playerHeight / 2) {
playSound(soundRight);
if(game.ball.vx <= game.ball.maxspeed) {
game.ball.vx += game.ball.multiplier;
}
changeBallDirection(game.player);
} else {
game.computer.score++;
document.getElementById("computerScore").innerHTML = game.computer.score;
game.ball.reset();
game.ball.vx = -1;
}
}
/* checking collision between ball and cpu */
else if(game.ball.x - game.ball.radius <= game.playerWidth) {
if (game.ball.y + game.ball.radius >= game.computer.y - game.playerHeight / 2
&& game.ball.y + game.ball.radius <= game.computer.y + game.playerHeight / 2) {
playSound(soundLeft);
if(game.ball.vx >= -game.ball.maxspeed) {
game.ball.vx -= game.ball.multiplier;
}
changeBallDirection(game.computer);
} else {
game.player.score++;
document.getElementById("playerScore").innerHTML = game.player.score;
game.ball.reset();
game.ball.vx = 1;
}
}
game.ball.x += game.ball.vx * moveAmount;
game.ball.y += game.ball.vy * moveAmount;
}
draw();
setTimeout(update,1000/30);
gameTimeLast = dateTime;
}
function changeBallDirection(player) {
if(player.y > game.ball.y)
game.ball.vy -= (player.y - game.ball.y) / game.playerHeight * game.ball.maxspeed;
else if(player.y < game.ball.y)
game.ball.vy += (game.ball.y - player.y) / game.playerHeight * game.ball.maxspeed;
game.ball.vx *= -1;
}
/**
* Draw everything in the canvas
*/
function draw() {
if (!game.pause) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
/*
var bgFade = ctx.createLinearGradient(0,0,0,canvas.height);
bgFade.addColorStop(0, '#000');
bgFade.addColorStop(1, '#211');
ctx.fillStyle = bgFade;
ctx.fillRect(0, 0, canvas.width, canvas.height);
*/
ctx.fillStyle = "rgb(64,64,64)";
var size = 3;
for(var y=0;y<canvas.height;y+=size*3) {
ctx.fillRect(canvas.width / 2 - size/2, y, size, size);
}
// left player
ctx.fillStyle = "rgba(128,128,128,.8)";
ctx.fillRect(0, game.computer.y - game.playerHeight / 2,
game.playerWidth, game.playerHeight);
// right player
ctx.fillRect(canvas.width - game.playerWidth, game.player.y
- game.playerHeight / 2, game.playerWidth, game.playerHeight);
ctx.fillStyle = "rgba(192,192,192,8)";
ctx.fillRect(game.ball.x - game.ball.radius, game.ball.y
- game.ball.radius, game.ball.radius * 2, game.ball.radius * 2);
}
}
function intro() {
var playButton = document.getElementById('playButton');
playButton.onclick = function() {
document.getElementById('titleScreen').style.display = "none";
document.getElementById('playScreen').style.display = "block";
init();
}
var pauseButton = document.getElementById('pauseButton');
pauseButton.onclick = function() {
if (!game.pause) {
game.pause = true;
this.innerHTML = "Continue";
document.getElementById('pauseText').style.display = "block";
}
else {
game.pause = false;
this.innerHTML = "Pause";
document.getElementById('pauseText').style.display = "none";
}
}
var soundButton = document.getElementById('soundButton');
soundButton.onclick = function() {
if (!game.sound) {
game.sound = true;
this.innerHTML = "Turn off sound";
}
else {
game.sound = false;
this.innerHTML = "Turn on sound";
}
}
}
intro();
/**** PONG.JS *****/
//=============================================================================
// PONG
//=============================================================================
Pong = {
Defaults: {
width: 640, // logical canvas width (browser will scale to physical canvas size - which is controlled by @media css queries)
height: 480, // logical canvas height (ditto)
wallWidth: 10,
balls: 1,
stats: true
},
//-----------------------------------------------------------------------------
initialize: function(runner, cfg) {
this.cfg = cfg;
this.runner = runner;
this.width = runner.width;
this.height = runner.height;
this.court = Object.construct(Pong.Court, this);
this.balls = this.constructBalls();
this.runner.start();
},
constructBalls: function() {
var balls = [];
for(var n = 0 ; n < this.cfg.balls ; n++)
balls.push(Object.construct(Pong.Ball, this));
return balls;
},
update: function(dt) {
for(var n = 0 ; n < this.balls.length ; n++)
this.balls[n].update(dt);
},
draw: function(ctx) {
this.court.draw(ctx);
for(var n = 0 ; n < this.balls.length; n++)
this.balls[n].draw(ctx);
},
//==========
// COURT
//=============================================================================
Court: {
initialize: function(pong) {
var w = pong.width;
var h = pong.height;
var ww = pong.cfg.wallWidth;
this.walls = [];
this.walls.push({x: 0, y: 0, width: w, height: ww});
this.walls.push({x: 0, y: h - ww, width: w, height: ww});
this.walls.push({x: 0, y: 0, width: ww, height: h});
this.walls.push({x: w-ww, y: 0, width: ww, height: h});
},
draw: function(ctx) {
ctx.fillStyle = '#96ef10';
for(var n = 0 ; n < this.walls.length ; n++)
ctx.fillRect(this.walls[n].x, this.walls[n].y, this.walls[n].width, this.walls[n].height);
}
},
// BALL
//=============================================================================
Ball: {
initialize: function(pong) {
this.pong = pong;
this.radius = Game.random(1, 30);
this.minX = pong.cfg.wallWidth + this.radius;
this.minY = pong.cfg.wallWidth + this.radius;
this.maxX = pong.width - pong.cfg.wallWidth - this.radius;
this.maxY = pong.height - pong.cfg.wallWidth - this.radius;
this.x = Game.random(this.minX, this.maxX);
this.y = Game.random(this.minY, this.maxY);
this.dx = (this.maxX - this.minX) / (Game.random(1, 10) * Game.randomChoice(1, -1));
this.dy = (this.maxY - this.minY) / (Game.random(1, 10) * Game.randomChoice(1, -1));
},
update: function(dt, leftPaddle, rightPaddle) {
this.x = this.x + (this.dx * dt);
this.y = this.y + (this.dy * dt);
if ((this.dx > 0) && (this.x > this.maxX)) {
this.x = this.maxX;
this.dx = -this.dx;
}
else if ((this.dx < 0) && (this.x < this.minX)) {
this.x = this.minX;
this.dx = -this.dx;
}
if ((this.dy > 0) && (this.y > this.maxY)) {
this.y = this.maxY;
this.dy = -this.dy;
}
else if ((this.dy < 0) && (this.y < this.minY)) {
this.y = this.minY;
this.dy = -this.dy;
}
},
draw: function(ctx) {
var w = h = this.radius * 2;
var img = new Image(200,200);
img.src = "pelota.png";
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI, true);
ctx.fill();
ctx.clearRect(0,0,700,500);
// Si pongo esta linea ocurre el error /// ctx.drawImage(img, x, y);
ctx.closePath();
}
}
}; // Pong
/**** CODIGO PARA INICIAR EL JUEGO ****/
Game.ready(function() {
Game.start('game', Pong);
});
body { background-image: url("cancha.jpg"); color: #AAA; font-size: 12pt; padding: 1em; }
#unsupported { border: 1px solid yellow; color: black; background-color: #FFFFAD; padding: 2em; margin: 1em; display: inline-block; }
#sidebar { width: 18em; height: 40em; float: left; font-size: 0.825em; background-color: #333; border: 1px solid white; padding: 1em; }
#sidebar h2 { color: white; text-align: center; margin: 0; }
#sidebar .parts { padding-left: 1em; list-style-type: none; margin-bottom: 2em; text-align: right; }
#sidebar .parts li a { color: white; text-decoration: none; }
#sidebar .parts li a:visited { color: white; }
#sidebar .parts li a:hover { color: white; text-decoration: underline; }
#sidebar .parts li a.selected { color: #F08010; }
#sidebar .parts li a i { color: #AAA; }
#sidebar .parts li a.selected i { color: #F08010; }
#sidebar .settings { line-height: 1.2em; height: 1.2em; text- align: right; }
#sidebar .settings.size { }
#sidebar .settings.speed { margin-bottom: 1em; }
#sidebar .settings label { vertical-align: middle; }
#sidebar .settings input { vertical-align: middle; }
#sidebar .settings select { vertical-align: middle; }
#sidebar .description { margin-bottom: 2em; }
#sidebar .description b { font-weight: normal; color: #FFF; }
@media screen and (min-width: 0px) {
#sidebar { display: none; }
#game { display: block; width: 480px; height: 360px; margin: 0 auto; }
}
@media screen and (min-width: 800px) {
#game { width: 640px; height: 480px; }
}
@media screen and (min-width: 1000px) {
#sidebar { display: block; }
#game { margin-left: 18em; }
}
@media screen and (min-width: 1200px) {
#game { width: 800px; height: 600px; }
}
@media screen and (min-width: 1600px) {
#game { width: 1024px; height: 768px; }
}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<div id="sidebar">
<div class='description'>
<p>
Using the Game.Runner from the previous section. You can build a simple animation
by implementing the <b>update()</b> and <b>draw()</b> methods.
</p>
<p>
Here are some bouncing balls
</p>
</div>
</div>
<canvas id="game">
<div id="unsupported">
Sorry, this example cannot be run because your browser does not support the <canvas> element
</div>
</canvas>