Как ограничить движущийся div внутри содержащего div?

#javascript #html #css

#javascript #HTML #css

Вопрос:

Я пытаюсь написать небольшую игру, используя HTML, CSS и JavaScript. Красный блок — это игрок, зеленый блок — враг. У меня есть div, содержащий эти два, с черной рамкой. Как мне сохранить красный блок внутри границы? Я использую клавиши со стрелками для перемещения красного блока, поэтому код, который я нашел в Интернете, не помог, потому что все это относится к перетаскиваемым элементам с помощью мыши. Я размещу здесь свой код для моего индекса, css и js.

 $(document).keydown(function(e) {
  switch (e.which) {
    case 37: //left arrow key
      $(".player").finish().animate({
        containment: ".container",
        left: "-=5"
      });
      break;
    case 38: //up arrow key
      $(".player").finish().animate({
        containment: ".container",
        top: "-=5"
      });
      break;
    case 39: //right arrow key
      $(".player").finish().animate({
        containment: ".container",
        left: " =5"
      });
      break;
    case 40: //bottom arrow key
      $(".player").finish().animate({
        containment: ".container",
        top: " =5"
      });
      break;
  }
}); 
 .player {
  width: 50px;
  height: 50px;
  background: #9C2259;
  border: 1px solid #000;
  position: relative;
}

.badguy {
  width: 50px;
  height: 50px;
  background: #376F46;
  border: 1px solid #000;
  position: absolute;
  bottom: 0;
  right: 0;
}

.container {
  width: 700px;
  height: 500px;
  border: 1px solid #000;
  position: absolute;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="author" content="Tim T. Hall" />
  <meta name="keywords" content="Test, Testing" />

  <link href="css/normalize.css" rel="stylesheet">
  <link href="css/styles.css" rel="stylesheet">

  <script src="https://code.jquery.com/jquery-1.12.4.min.js">
  </script>
  <script type="text/javascript" src="js/game.js"></script>
</head>


<body>

  <main>
    <div class="container">
      <div class="player"></div>
      <div class="badguy"></div>
    </div>
  </main>

</body> 

Комментарии:

1. .animate может обрабатывать только свойства CSS… И не все. В CSS нет containement свойства. Как вы упомянули, это существует только в методе jQuery-ui .draggable . Вам нужно будет вычислить и сравнить положение, чтобы пропустить анимацию при достижении границы.

2. getBoundingClientRect будет полезен для этих вычислений.

Ответ №1:

@donnieth65,

Однако я не совсем уверен в описании вашего сообщения, я собрал некоторый код, чтобы определить, когда дочерний div с именем player касается или достигает родительской границы, как только это произойдет, я остановлю player от продолжения в этом направлении, чтобы не оставлять родительское тело или оболочку. Я решил проверить это с помощью некоторых условий, чтобы сначала найти текущую позицию, и если это было внутри родительского тела, тогда мы будем перемещаться, используя текущие правила оператора switch, которые вы уже установили. Я, конечно, надеюсь, что это поможет, m8!

 $(document).keydown(function (e) {
    // Assign elements to variables
    let player = $('.player');
    let container = $('.container');
  // These 2 vars will help us getting the bottom and right boundaries
  // so that we can stop the div from moving outside of the parent
 let getBottom = parseInt(player.position().top   player.outerHeight(true));
 let getRight = parseInt(player.position().left   player.outerWidth(true));

    // Are these elements touching the parent edges?
    // If is so, let us get them back in by 1 unit
    // first for the top case
    if (player.position().top < 0) {
        player.css({
            top: 1
        });
    }
    // Then for the left case
    else if (player.position().left < 0) {
        player.css({
            left: 1
        });
    }
    // Then for the right case
    else if (getRight > 692) {
        player.css({
            left: 640
        });
    }
    // Last for the bottom case
    else if (getBottom > 492) {
        player.css({
            top:440
        });
    }
    // If is not touching any edge, then increase their position
    // This will be validated with a switch case now
    else {
        switch (e.which) {
            case 37: //left arrow key
                $(".player").finish().animate({
                    left: "-=5px"
                });
                break;
            case 38: //up arrow key
                $(".player").finish().animate({
                    top: "-=5px"
                });
                break;
            case 39: //right arrow key
                $(".player").finish().animate({
                    left: " =5px"
                });
                break;
            case 40: //bottom arrow key
                $(".player").finish().animate({
                    top: " =5px"
                });
                break;
        } //End of Switch case
    } // End of main conditional statement with else
}); 
 html, body {margin: 0; height: 100%; overflow: hidden}

.player {
    width: 50px;
    height: 50px;
    background: #9C2259;
    border: 1px solid #000;
    position: absolute;
}

.badguy {
    width: 50px;
    height: 50px;
    display: block;
    background: #376F46;
    border: 1px solid #000;
    position: absolute;
    bottom: 0;
    right: 0;
}

.container {
    width: 700px;
    height: 500px;
    border: 2px solid #000;
    position: relative;
    overflow: hidden;
} 
 <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="author" content="Tim T. Hall" />
    <meta name="keywords" content="Test, Testing" />

    <link href="css/normalize.css" rel="stylesheet">
    <link href="css/styles.css" rel="stylesheet">

    <script src="https://code.jquery.com/jquery-1.12.4.min.js">
    </script>
    <script type="text/javascript" src="js/game.js"></script>
</head>
<body>
    <main>
        <div class="container">
            <div class="player"></div>
            <div class="badguy"></div>
        </div>
    </main>
</body> 

Комментарии:

1. Спасибо, это было полезно. Тем не менее, я тестировал его, и, похоже, он работает для верхнего и левого, но не для правого и нижнего.

2. Пожалуйста, повторите попытку, я внес некоторые дополнительные коррективы, народ!