Problem when using image in game Pong with JavaScript

0

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 &lt;canvas&gt; element
  </div>
</canvas>
    
asked by JESUS ESPINOSA 11.12.2016 в 19:58
source

1 answer

1

XD then indeed, after reviewing tutorials, I could solve it in the following way, in pong.js replace the draw function: D

  draw: function(ctx) {
  var img = new Image(10,10)
  img.src = "ball.png";
  var w = h = this.radius * 2;
  ctx.fillStyle = Pong.Colors.ball;
  ctx.drawImage(img, this.x - this.radius, this.y - this.radius, w, h);
  if (this.pong.cfg.footprints) {
    var max = this.footprints.length;
    ctx.strokeStyle = Pong.Colors.footprint;
    for(var n = 0 ; n < max ; n++)
      ctx.strokeRect(this.footprints[n].x - this.radius, this.footprints[n].y - this.radius, w, h);
    
answered by 12.12.2016 / 03:43
source