Добавление стен для игры Top-Down js, html, css (обнаружение столкновений)

У меня ОЧЕНЬ маленькая 2D-игра сверху вниз. Я действительно не думаю, что мне нужно объяснять всю игру для этого вопроса, но вы можете поиграть с ним в фрагменте кода, чтобы получить представление. Я хочу сделать стены/препятствия, может быть, всего несколько блоков, с которыми игрок может столкнуться, я могу добавить другие стены позже, как только узнаю код, как это сделать. Вы можете прочитать инструкции в нижней части экрана во фрагменте, чтобы увидеть элементы управления, если вам это нужно.

Вот мой код для игры в HTML, CSS и JS:

//Canvas
mycan.style.display = "block";
mycan.height = 600;
mycan.width = 600;
//make players
let player = {x:510, y: 541, w:30, h:30};
let player2 = {x:60, y:31, w:30, h:30};

//Context
const ctx = mycan.getContext("2d");


const moveHandler = (isPlayer1) => {
    if (player.x == player2.x && player.y == player2.y) {
        document.getElementById('info').textContent = isPlayer1 ? 'Player1 killed player2' : 'Player2 killed player1'
    }
}

//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
ctx.fillRect(player2.x, player2.y, player2.w, player2.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    let key = e.key;
  //player1(red)
    switch (key) {
        case 'w':
            player2.y -= 30;
            moveHandler(false);
            break;
        case 'a':
            player2.x -= 30;
            moveHandler(false);
            break;
        case 's':
            player2.y += 30;
            moveHandler(false);
            break;
        case 'd':
            player2.x += 30;
            moveHandler(false);
            break;
        case 'ArrowRight':
            player.x += 30;
            moveHandler(true);
            break;
        case 'ArrowLeft':
            player.x -= 30;
            moveHandler(true);
            break;
        case 'ArrowDown':
            player.y += 30;
            moveHandler(true);
            break;
        case 'ArrowUp':
            player.y -= 30;
            moveHandler(true);
            break;
    }
}

const draw = ()=>{
//player draw, and player colors
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillRect(player.x, player.y, player.w, player.h);
  ctx.fillStyle = "blue";
  ctx.fillRect(player2.x,player2.y, player2.w, player2.h);
  ctx.fillStyle = 'red';
  
  
  
};

setInterval(()=>{
  draw();
},1000/60);
html, body {
    margin: 20;
    padding: 10;
  }
  canvas {
    display: block;
  }
  
  #mycan {
    background-size: 30px 30px;
    background-image:
      linear-gradient(to right, black 1px, transparent 1px),
      linear-gradient(to bottom, black 1px, rgb(136, 136, 136) 1px);
  
  }


  body {
    background-color: grey;

  }
<!DOCTYPE html>
<html lang = "en">
  <head>
    <link rel = "stylesheet" type = "text/css" href = "style.css">
    <meta charset = "utf-8" />
<canvas id = "mycan" > </canvas>
    <p id = "info"></p>
    <font color = 'blue'> <h1>Player1 = blue</h1></font>
    <font color = 'red'> <h1>Player2 = red</h1></font>

  </head>
  <body>
    <main>
    </main>
    <script src = "script.js"></script>
   
   <h2>
   Direction:
   Player1(Blue), is controlled by the WASD keys, and player2(red), is controlled by the arrow keys. The objecitve of the game is to stop in front
   of the other player, and let them run into you, if they run into you, then they die, at the same time you have avod running into the other
   player.Good luck, and have fun.
   </h2>
   
   

  </body>
</html>

Не стесняйтесь задавать любые вопросы о коде или вопрос в комментариях!

Где в процессе написания кода вы застряли? Вы не задали здесь конкретного вопроса. Кроме того: Подтвердите свой HTML . Попробуйте использовать requestAnimationFrame вместо setInterval . Предпочитаю addEventListener("keydown",…); более window.onkeydown =;. Некоторые из ваших переменных не объявлены; не надейтесь на это.

Sebastian Simon 19.11.2022 03:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, что вы пытаетесь сделать, очень распространено в играх, я бы порекомендовал узнать больше о разработке игр и объектах. Вот несколько полезных статей:

Обнаружение 2D-столкновений: https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

Тайлы и тайловые карты: https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps

Объекты в javascript: https://www.w3schools.com/js/js_objects.asp

Существует также гораздо больше информации, если вы знаете, что искать.

Но чтобы ответить на ваш вопрос:

Вам следует подумать об использовании объектов для игроков и всех стен (сущностей), с которыми вы собираетесь столкнуться, но простым примером будет создание стены:

let obsticle = {x: 90, y: 91, w: 30, h:30};

Визуализируйте это на странице, как вы это делаете с игроками

ctx.fillStyle = 'green';
ctx.fillRect(obsticle.x, obsticle.y, obsticle.w, obsticle.h);

Затем создайте функцию, которая проверяет наличие коллизий:

function checkCollison(rect1, rect2) {
    if (
        rect1.x < rect2.x + rect2.w &&
        rect1.x + rect1.w > rect2.x &&
        rect1.y < rect2.y + rect2.h &&
        rect1.h + rect1.y > rect2.y
    ) {
        // Collision detected!
        return true;
    } else {
        // No collision
        return false;
    }
}

Также я рекомендую создать функцию для движения игроков, потому что каждый раз, когда игроки перемещаются, вам придется вызывать checkCollision(), и если произойдет столкновение, то игроки не смогут двигаться или вернуть его на исходное место, что-то вроде этого:

function movePlayer(object, x, y) {
    object.x += x;
    object.y += y;

    if (checkCollison(object, obsticle)) {
        object.x -= x;
        object.y -= y;
        return;
    };
}

Итак, ваше движение становится:

 case 'w':
        movePlayer(player2, 0, -30);
        moveHandler(false);
        break;

Если вы используете объекты и тайловое отображение для всего, этот процесс будет намного проще, и ваш код станет более масштабируемым.

Также здесь есть снайпер, так что вы можете проверить это

//Canvas
mycan.style.display = "block";
mycan.height = 600;
mycan.width = 600;
//make players
let player = {x:510, y: 541, w:30, h:30};
let player2 = {x:60, y:31, w:30, h:30};

let obsticle = {x: 90, y: 91, w: 30, h:30};

//Context
const ctx = mycan.getContext("2d");

function checkCollison(rect1, rect2) {
    if (
        rect1.x < rect2.x + rect2.w &&
        rect1.x + rect1.w > rect2.x &&
        rect1.y < rect2.y + rect2.h &&
        rect1.h + rect1.y > rect2.y
    ) {
        // Collision detected!
        return true;
    } else {
        // No collision
        return false;
    }
}

function movePlayer(object, x, y) {
    object.x += x;
    object.y += y;

    if (checkCollison(object, obsticle)) {
        object.x -= x;
        object.y -= y;
        return;
    };
}

const moveHandler = (isPlayer1) => {
    if (player.x == player2.x && player.y == player2.y) {
        document.getElementById('info').textContent = isPlayer1 ? 'Player1 killed player2' : 'Player2 killed player1'
    }
}

//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
ctx.fillRect(player2.x, player2.y, player2.w, player2.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    let key = e.key;
  //player1(red)
    switch (key) {
        case 'w':
            movePlayer(player2, 0, -30);
            moveHandler(false);
            break;
        case 'a':
            movePlayer(player2, -30, 0);
            moveHandler(false);
            break;
        case 's':
            movePlayer(player2, 0, 30);
            moveHandler(false);
            break;
        case 'd':
            movePlayer(player2, 30, 0);
            moveHandler(false);
            break;
        case 'ArrowRight':
            movePlayer(player, 30, 0);
            moveHandler(true);
            break;
        case 'ArrowLeft':
            movePlayer(player, -30, 0);
            moveHandler(true);
            break;
        case 'ArrowDown':
            movePlayer(player, 0, 30);
            moveHandler(true);
            break;
        case 'ArrowUp':
            movePlayer(player, 0, -30);
            moveHandler(true);
            break;
    }
}

const draw = ()=>{
//player draw, and player colors
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillStyle = "blue";
  ctx.fillRect(player.x, player.y, player.w, player.h);
  ctx.fillStyle = 'red';
  ctx.fillRect(player2.x,player2.y, player2.w, player2.h);
  ctx.fillStyle = 'green';
  ctx.fillRect(obsticle.x, obsticle.y, obsticle.w, obsticle.h);

};

setInterval(()=>{
  draw();
},1000/60);
html, body {
    margin: 20;
    padding: 10;
  }
  canvas {
    display: block;
  }
  
  #mycan {
    background-size: 30px 30px;
    background-image:
      linear-gradient(to right, black 1px, transparent 1px),
      linear-gradient(to bottom, black 1px, rgb(136, 136, 136) 1px);
  
  }


  body {
    background-color: grey;

  }
<!DOCTYPE html>
<html lang = "en">
  <head>
    <link rel = "stylesheet" type = "text/css" href = "style.css">
    <meta charset = "utf-8" />
<canvas id = "mycan" > </canvas>
    <p id = "info"></p>
    <font color = 'blue'> <h1>Player1 = blue</h1></font>
    <font color = 'red'> <h1>Player2 = red</h1></font>

  </head>
  <body>
    <main>
    </main>
    <script src = "script.js"></script>
   
   <h2>
   Direction:
   Player1(Blue), is controlled by the WASD keys, and player2(red), is controlled by the arrow keys. The objecitve of the game is to stop in front
   of the other player, and let them run into you, if they run into you, then they die, at the same time you have avod running into the other
   player.Good luck, and have fun.
   </h2>
   
   

  </body>
</html>

Другие вопросы по теме