0

I'm making a game that utilizes an HTML canvas and draws images on it. 60 times every second it clears the screen and redraws all the elements to create animations. However, when I use images instead of just shapes, the images will be there, but will flash in and out and won't be visible all the time. I've made a game like this before(https://graphics-game.napoleon1027.repl.co/) and it was composed of entirely squares and circles and never had issues. Then when I added an image it began to flash in and out.

<!DOCTYPE html>
<html>

<body>

    <canvas id="canvas" width="900" height="600" style="border:1px solid #d3d3d3;">
    </canvas>

    <script>
        var xcoord = 50
        var ycoord = 50
        function drawscreen() {
            var ctx = document.getElementById('canvas').getContext('2d');
            void ctx.clearRect(0, 0, 900, 600);
            image = new Image()
            image.src = "https://upload.wikimedia.org/wikipedia/en/c/c8/Very_Black_screen.jpg"
            void ctx.drawImage(image, 0, 0, 200, 200, xcoord, ycoord, 50, 50);
            ycoord++
            xcoord++

        }

        setInterval(drawscreen, 16);
    </script>

</body>

</html>
Omkar76
  • 1,317
  • 1
  • 8
  • 22
George
  • 31
  • 5

1 Answers1

1

I've not reproduced your flickering behavior with the few lines of code you gave. However, there are things you can do to optimize your code from what can be seen here:

  • Do the least possible operations while drawing a frame:
    • Get your canvas drawing context only once
    • Load your image only once
  • Use window.requestAnimationFrame to run your drawing function when the client is ready to draw a new frame (aiming for 60fps)

window.addEventListener('DOMContentLoaded', _e => {

  const c = document.querySelector('#game-screen');
  if (!c || !c.getContext)
    return;
  
  runGame();

  function runGame() {
    //Resources
    const ctx = c.getContext('2d');
    const image = new Image();
    image.src = "https://picsum.photos/200";
    //Game state
    let xcoord = 50;
    let ycoord = 50;
    //Last rendered frame timestamp
    let lastTs;

    //Launch animation
    window.requestAnimationFrame(drawFrame);

    function drawFrame(timestamp) {
      //Draw frame
      ctx.clearRect(0, 0, 900, 600);
      ctx.drawImage(image, 0, 0, 200, 200, xcoord, ycoord, 50, 50);
      //Don't count on actual frame rate to compute moves
      //ycoord++; xcoord++; //Will appear slower if frameRate on client < 60fps
      updatePos(timestamp, lastTs);
      lastTs = timestamp;
      
      //Carry on animation
      window.requestAnimationFrame(drawFrame);
    }
    
    function updatePos(timestamp, lastTs) {
      //Move picture diagonaly at 60px/s
      if (lastTs) {
        const delta = timestamp - lastTs;
        const deltaXY = Math.floor(delta * 60 / 1000); //60px per second
        ycoord += deltaXY;
        xcoord += deltaXY;
      }
    }
  }
  
});
canvas {
  border: 1px solid black;
}
<canvas id="game-screen" width="900" height="600">
Canvas not supported
</canvas>
julien.giband
  • 2,467
  • 1
  • 12
  • 19