Search code examples
javascriptcollision-detectioncollision

How to prevent block from leaving canvas width and height?


I'm very new to programming. I've been working on this bit of code, and have not been able to successfully add collision detection to this block in regards to the width and height of the canvas. The collision detection does, however, work for the upper and left side of the canvas. What would I have to do differently to prevent the block from leaving the canvas width and length?

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const keys = [];

const player = new Image();
player.src = "https://lh3.googleusercontent.com/9pPCK70Rw0k3wethMHb1qMaIB0VjeWLy57vYgSzKbF7oJuvO2nA0Nakk-95cvibWUDcEhYkfCKvdPKT03tXZd4M5jdhIEibLO9qw-XE=w102-h68-n-l50-sg-rj";
const background = new Image();
background.src = "https://lh3.googleusercontent.com/taykG37GWDgY-FGkdogDvsHSJMUGRMvkuVRT6yR-5UNkKvGRKeRlpGYXlslocOcS0txlfUdGW59JGtzADknxbMqnh6AtVCv9EXyB8nHp80YsRNA0Yw=w1024-h683-n-l50-sg-rj";

function drawSprite(img, sX, sY, sW, sH, dX, dY, dW, dH){
    ctx.drawImage(img, sX, sY, sW, sH, dX, dY, dW, dH);
}

var xPos = 0;
var yPos = 0;
function movement(e){
    if (e.keyCode == 37 && !xPos <=0){
      xPos -= 6;
    }
    else if (e.keyCode == 37 && xPos <=0){
      xPos -= xPos;
    }
    else if (e.keyCode == 38 && !yPos <= 0){
      yPos -= 6;
    }
    else if (e.keyCode == 38 && yPos <= 0){
      yPos -= yPos;
    }
    else if (e.keyCode == 39 && !xPos <= canvas.width){
      xPos += 6; 
    }
    else if (e.keyCode == 39 && xPos <= canvas.width){
      xPos -= 100; 
    }
    else if (e.keyCode == 40){
      yPos += 6;
    }
}

document.onkeydown = movement;

function animate(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
    drawSprite(player, 0, 0, 30, 52, xPos, yPos, 30, 52);
    requestAnimationFrame(animate);
}
animate();
<canvas id="canvas"></canvas>


Solution

  • For right and bottom collisions you need subtract width/height of the block from width/height of the canvas.

    If x or y position is larger than max number, than set it to max number

    Oh and you don't have to check all that before you change the x/y position, you can check them afterwards

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    const keys = [];
    
    const player = new Image();
    player.src = "https://lh3.googleusercontent.com/taykG37GWDgY-FGkdogDvsHSJMUGRMvkuVRT6yR-5UNkKvGRKeRlpGYXlslocOcS0txlfUdGW59JGtzADknxbMqnh6AtVCv9EXyB8nHp80YsRNA0Yw=w102-h200-n-l50-sg-rj";
    const background = new Image();
    background.src = "https://lh3.googleusercontent.com/9pPCK70Rw0k3wethMHb1qMaIB0VjeWLy57vYgSzKbF7oJuvO2nA0Nakk-95cvibWUDcEhYkfCKvdPKT03tXZd4M5jdhIEibLO9qw-XE=w1024-h683-n-l50-sg-rj";
    
    function drawSprite(img, sX, sY, sW, sH, dX, dY, dW, dH){
        ctx.drawImage(img, sX, sY, sW, sH, dX, dY, dW, dH);
    }
    
    var xPos = 0;
    var yPos = 0;
    var playerWidth = 30;
    var playerHeight = 52
    const step = 6;
    function movement(e){
        if (e.keyCode == 37){
          xPos -= step;
        }
        else if (e.keyCode == 38){
          yPos -= step;
        }
        else if (e.keyCode == 39){
          xPos += step; 
        }
        else if (e.keyCode == 40){
          yPos += step;
        }
    
        if (xPos < 0)
          xPos = 0;
    
        if (xPos > canvas.width - playerWidth)
          xPos = canvas.width - playerWidth;
    
        if (yPos < 0)
          yPos = 0;
    
        if (yPos > canvas.height - playerHeight)
          yPos = canvas.height - playerHeight;
    }
    
    document.onkeydown = movement;
    
    function animate(){
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
        drawSprite(player, 0, 0, player.width, player.height, xPos, yPos, playerWidth, playerHeight);
        requestAnimationFrame(animate);
    }
    animate();
    <canvas id="canvas"></canvas>