UPD: ПРОБЛЕМА РЕШЕНА Всем привет, всё работало, решила добавить препятствие в виде камня, при этом, если змейка его поедает, то очно вычитается и когда счёт становится = -1, то игра заканчивается, так вот, получилось так, что хвост вообще стал не виден, а он должен быть красным. Прошу отредачить мой код, в ответе копипаст моего и вашего уже с исправлениями. Буду благодарна
Извиняюсь, но фон и еда тут не работают нормально, я что-то не так прикрепляю
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Игра на JavaScript</title>
<style>
canvas {
display: block;
margin: 0 auto;
}
</style>
</head>
<body>
<canvas id="game" width="608" height="608"></canvas>
<script>
const canvas = document.getElementById("game"); // вызов канваса
const ctx = canvas.getContext("2d"); // формат игры
const ground = new Image(); // Создание объекта
ground.src = "https://javascript.ru/forum/attachment.php?attachmentid=4447&d=1601818593"; // Указываем нужное изображение
const foodImg = new Image(); // Создание объекта
foodImg.src = "https://javascript.ru/forum/attachment.php?attachmentid=4446&d=1601818593"; // Указываем нужное изображение,
// размер еды 32x32,т.к каждая клетка 32 пкс
const barImg = new Image(); // Создание объекта
barImg.src = "https://javascript.ru/forum/attachment.php?attachmentid=4445&d=1601818593"; // Указываем нужное изображение
let box = 32; // ширина/высота квадратика
let score = 0; // счёт
let food = {
x: Math.floor((Math.random() * 17 + 1)) * box, // еда в
// случайном месте от 0 до 1, увеличиваем его *17 и +1(от 1)
// и *box(1 квадратик)
y: Math.floor((Math.random() * 15 + 3)) * box, // еда в
// случайном месте от 0 до 1, увеличиваем его *15 и +3
// (чтобы не залазила на верхнюю панель)
};
let snake = [];
snake[0] = { // голова змейки в начале игры по центру
x: 9 * box,
y: 10 * box
};
let bar = {
x: Math.floor((Math.random() * 17 + 1)) * box, // еда в
// случайном месте от 0 до 1, увеличиваем его *17 и +1(от 1)
// и *box(1 квадратик)
y: Math.floor((Math.random() * 15 + 3)) * box, // еда в
// случайном месте от 0 до 1, увеличиваем его *15 и +3
// (чтобы не залазила на верхнюю панель)
};
document.addEventListener("keydown", direction); // При нажатии
// какую-либо кнопку
// Вызывается метод (функция) direction
let dir;
function direction(event) { // изменяем в коде >>>
// это обработчик событий, проверка, какая клавиша нажата
if(event.keyCode == 37 && dir != "right") // проверка dir,
//чтобы нельзя было одновременно двигать то в одну,
// то в другую сторону
dir = "left";
else if(event.keyCode == 38 && dir != "down")
dir = "up";
else if(event.keyCode == 39 && dir != "left")
dir = "right";
else if(event.keyCode == 40 && dir != "up")
dir = "down";
}
function eatTail(head, arr) { // проврка на поедание хвоста
for(let i = 0; i < arr.length; i++) { // перебор всех
// элементов змейки(массива)
if(head.x == arr[i].x && head.y == arr[i].y) // если
// координаты совпадают, то конец игры
clearInterval(game); // очищаем интервал
}
}
function drawGame() {
ctx.drawImage(ground, 0, 0); // рисуем картинку
// в координатах, x, y
ctx.drawImage(foodImg, food.x, food.y); // еда в рандомном
// месте
ctx.drawImage(barImg, bar.x, bar.y); // препятствие в рандомном
// месте
for(let i = 0; i < snake.length; i++) { // счётчик
ctx.fillStyle = i == 0 ? "green" : "red"; // рисуем квадрат,
//тело змейки, для первого элемента зеленый,
// а для последующих красный
ctx.fillRect(snake[i].x, snake[i].y, box, box); // позиция
// объекта, координаты по x и y, размерность
//(ширина и высота)
}
ctx.fillStyle = "white"; // шрифт белый
ctx.font = "50px Arial"; // 50 кегглей шрифт ариал
ctx.fillText(score, box * 2.5, box * 1.7); // рисуем шрифт
//(какой текст, коорд.по x и по y (выравниваем число))
let snakeX = snake[0].x; // координата по иксу
let snakeY = snake[0].y; // координата по игреку
if(snakeX == food.x && snakeY == food.y) { // проверяем
// если голова змейки на еде, то еду в новом месте
score++; // добавляем очко
food = { // ставим еду в новом месте
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else {
snake.pop(); // удаляем последний элемент в змейке
}
if(snakeX == bar.x && snakeY == bar.y) { // проверяем
// если голова змейки на препятствии, то еду в новом месте
score--; // вычитаем очко
bar = { // ставим еду в новом месте
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else {
snake.pop(); // удаляем последний элемент в змейке
}
if(snakeX < 2 * box || snakeX > box * 16 // чтобы змейка не
// выезжала за границы канваса(а точнее туда, где нет
// клеток на канвасе)
|| snakeY < 4 * box || snakeY > box * 16)
clearInterval(game); // завершаем игру(очищением переменной)
if(dir == "left") snakeX -= box; // передвигаем на
// один бокс влево
if(dir == "right") snakeX += box;
if(dir == "up") snakeY -= box;
if(dir == "down") snakeY += box;
let newHead = { // голова змейки в новых координатах
x: snakeX,
y: snakeY
};
eatTail(newHead, snake);
snake.unshift(newHead); // добавляем новый элемент
// в самое начало массива
}
let game = setInterval(drawGame, 100); // Вызов функции из вне,
// каждые 100 миллисекунд вызывается
</script>
</body>
</html>