javascriptcanvasboundary

Character Not hitting boundary wall for right wall and bottom wall


I have been trying to figure out how to make the character stop when it hits the right wall and the bottom wall of the canvas with no luck, Please see the code below:

function place(id,x_pos, y_pos,)
{
  let element = document.getElementById(id);
  element.style.position = "absolute";
  element.style.left = x_pos + 'px';
  element.style.top = y_pos + 'px';

}

setInterval(update,1);

function update()
{
  document.addEventListener('keydown', keydown);
}

function keydown(e)
{
  let x = e.keyCode;

  let character = document.getElementById("character").getBoundingClientRect();
  let canvasbound = document.getElementById("canvas").getBoundingClientRect();
  let left = parseInt(character.left,10);
  let top = parseInt(character.top,10);

  switch (x) {

      //left
    case 37:
        if(!(character.left-15 < canvasbound.left))
          {
            place('character', left-15, top);
          }
      break;
      //right
    case 39:
        if(!(character.left+15 < canvasbound.left))
          {
          place('character', left+15, top);
          }
      break;
      //up
    case 38:
        if(!(character.top-15 < canvasbound.top))
          {
            place('character', left, top-15);
          }
      break;
      //down
    case 40:
          if(!(character.top+15 < canvasbound.down))
            {
                place('character', left, top+15);
            }
      break;
  }
  console.log(x)
  return x
}

Case 39 is meant to let the character travel until it hits the right wall and stop, but it goes through the wall:

case 39:
        if(!(character.left+15 < canvasbound.left))
          {
          place('character', left+15, top);
          }
      break;

Same for case 40 except the character goes down and passes the wall which it is not supposed to.

case 40:
          if(!(character.top+15 < canvasbound.top))
            {
                place('character', left, top+15);
            }
      break;

Is there something I am missing I was thinking that I might be missing something in this area of the code:

function place(id,x_pos, y_pos,)
{
  let element = document.getElementById(id);
  element.style.position = "absolute";
  element.style.left = x_pos + 'px';
  element.style.top = y_pos + 'px';

}

Solution

  • The code was a little mixed up which key is which, and the conditions were tough to read. like with x, y, left, right, plus, minus, <, >, and !.

    Here, the code is re-organized a bit, separating rules about movement from the constraints, and referring only to the bounding rects (no hard coded constants), to be durable if canvas or character change size.

    function place(id, x_pos, y_pos, ) {
      let element = document.getElementById(id);
      element.style.position = "absolute";
      element.style.left = x_pos + 'px';
      element.style.top = y_pos + 'px';
    }
    
    function init() {
      const bounds = document.getElementById("canvas").getBoundingClientRect();
      place('character', 0, 0);
      document.addEventListener('keydown', keydown);
    }
    init();
    
    function keydown(e) {
      let key = e.keyCode;
      const character = document.getElementById("character").getBoundingClientRect();
      let dx = 0, dy = 0;
    
      // get x and y increments based on the key, don't worry about the bounds
      const rules = {
        37: () => dx -= character.width,  // left
        38: () => dy -= character.height, // up
        39: () => dx += character.width,  // right
        40: () => dy += character.height  // down
      };
      if (key in rules) rules[key]();
    
      // functions that clamp x,y to bounds
      const bounds = document.getElementById("canvas").getBoundingClientRect();
      const clampX = x => Math.min(Math.max(x, bounds.left), bounds.right - character.width);
      const clampY = y => Math.min(Math.max(y, bounds.top), bounds.bottom - character.height);
    
      // increment the character position and clamp
      const newX = clampX(character.left + dx)
      const newY = clampY(character.top + dy)
      place('character', newX, newY);
    
      return key
    }
    html, body {
      margin: 0;
    }
    <div id="character" style="width:20px; height:20px; background-color:blue"></div>
    <canvas id="canvas" style="background-color:yellow;"></canvas>

    The most important idea relating to the OP is the idea of "clamping". We use this all the time to enforce endpoint constraints. It always takes this form....

    Math.min(upperLimit, Math.max(lowerLimit, someValue))