Search code examples
javascripthtmlcanvasviewport

making the canvas viewport move and enlarge (slither.io)


I'm learning how to use canvas and I thought it'd be fun making a simple game similar in style to slither.io (not the online, but how the map moves and the character stays in the center).

I've created a canvas and draw a box in the center

function init () {
    e = document.getElementById ("mycanv");
    var canvas = document.getElementById('mycanv');
    var context = canvas.getContext('2d');
    drawCircle(canvas); 
}

but I can't wrap my brain around how I would create a similar style that to slither.io where the viewport of the canvas is only a portion of the whole map.

Do I start by setting a large background image and then positing my 'player' in the center?

I've been able to create a player that I can move with the 'WASD' key's but then what?

Anyone have any suggestions?


Solution

  • You can use translate to move the entire canvas around by a number of pixels. All elements on the canvas will move along with it.

    This answer uses the WASD keys to move. But instead of moving the player, the entire canvas is displaced. To keep the player appearing in the center, we keep track of X and Y variables that are the opposite of the displacement of the canvas.

    You could also use transform to scale the entire canvas.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    let playerX = 130;
    let playerY = 90;
    
    // by using translate we move the entire world
    function moveWorld(key){
      switch (key) {
        case "a" : 
          ctx.translate(10, 0);
          playerX -= 10;
          break;
        case "d" : 
          ctx.translate(-10, 0);
          playerX += 10;
          break;
        case "w" : 
          ctx.translate(0, 10);
          playerY -= 10;
          break;
        case "s" : 
          ctx.translate(0, -10);
          playerY += 10;
          break;
      }
      drawWorld();
    }
    
    // the world elements have fixed positions
    function drawWorld(){
      ctx.clearRect(0, 0, 600, 400);
      // world
      ctx.fillStyle = 'red';
      ctx.fillRect(10, 10, 50, 50);
      ctx.fillRect(110, 30, 50, 50);
      // player
      ctx.fillStyle = 'green';
      ctx.fillRect(playerX, playerY, 20, 20);
    }
    
    document.addEventListener('keydown', (event) => {
      moveWorld(event.key);
    });
    
    drawWorld();
    <canvas id="canvas" width="600" height="400"></canvas>