Танк на игровом поле

1. Задание игрового поля и отрисовка карты по массиву.

Задание игрового поля:

Игровое поле (далее поле лабиринта) задается в виде двумерного массива, где каждый элемент представляет собой символ, указывающий на тип клетки. Я использую следующий набор символов:

'$' — внешние стены лабиринта
' ' — пустые клетки
'@' — сердца
'#' — остальное

Отрисовка карты по массиву:

Отрисовка карты происходит в функции drawMaze(), которая выполняет следующие шаги:

- Очистка холста: перед каждой отрисовкой очищаем холст, чтобы не было наложения предыдущих кадров.

- Определение размера ячейки: размер каждой ячейки нашего поля, определяется в зависимости от размеров канваса (размер мы задаем в файле html) и размеров самого массива.

cellSize = Math.min(canvas.width / gameMaze[0].length, canvas.height / gameMaze.length);

Мы получаем, что каждая ячейка, начиная с левого верхнего угла (0:0), будет иметь координаты, кратные единице.

- Цикл отрисовки: здесь мы используем цикл (первый цикл по x, второй цикл по y) для прохода по всем элементам массива. Внутри цикла проверяется символ в текущей ячейке и устанавливается соответствующий цвет отрисовки на определенной координате.

for (let y = 0; y < gameMaze.length; y++) {
    for (let x = 0; x < gameMaze[y].length; x++) {
        ctx.fillStyle = gameMaze[y][x] == '$' ? 'black' : '#cccccc'; // стены черным, остальное серым
        ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
    }
}

- После отрисовки лабиринта вызываются функции для отрисовки всего прочего.

2. Описание механики стрельбы

Создание пули:

При нажатии на кнопку "Стрельба" (shoot), вызывается функция shoot(), которая выполняет следующие действия:

- Определение угла стрельбы: угол (он же направление), под которым игрок стреляет, преобразуется из градусов в радианы (для использования в тригонометрических функциях). Пуля летит туда, куда направлен танк (player).

radians = player.angle * Math.PI / 180;

- Получение скорости пули: скорость пули считывается из ползунка, что позволяет игроку настраивать скорость стрельбы.

bulletSpeed = parseInt(bulletSpeedInput.value);

- Создание объекта пули: создается объект с текущими координатами игрока (x, y), изменениями по осям (dx, dy), а также временем жизни пули (Количество кадров, в течение которых пуля будет активна. Это используется на тот случай, если вдруг размер карты будет большим. Пуля ведь не может лететь бесконечно).

bullets.push({
    x: player.x,
    y: player.y,
    dx: Math.cos(radians) * bulletSpeed / 2,
    dy: Math.sin(radians) * bulletSpeed / 2,
    life: 100
});

Обновление пуль:

Функция updateBullets() отвечает за обновление состояния всех пуль на экране. Она выполняет следующие шаги:

- Перебор массива пуль: цикл проходит по всем пулям в обратном порядке (чтобы лучше удалять элементы из массива).

- Обновление координат: для каждой пули обновляются ее координаты на основе текущих изменений (dx, dy).

bullet.x += bullet.dx;
bullet.y += bullet.dy;

Проверка столкновений:

- Если пуля сталкивается с внутренними стенами ('#' или '@'), то стена удаляется, создается взрыв, и пуля удаляется из массива.

if (gameMaze[nextCellY] && (gameMaze[nextCellY][nextCellX] === '#' || gameMaze[nextCellY][nextCellX] === '@')) {
    gameMaze[nextCellY] = gameMaze[nextCellY].substring(0, nextCellX) + ' ' + gameMaze[nextCellY].substring(nextCellX + 1);
    createExplosion(nextCellX, nextCellY);
    bullets.splice(i, 1);
}

- Если пуля сталкивается с внешней стеной ('$'), также создается взрыв и пуля удаляется. Но стена не удаляется.

3. Отрисовка пуль

Функция drawBullets(cellSize) отвечает за отрисовку пуль:

- Установка цвета: цвет пуль задается желтым.

- Масштабирование: размер пули рассчитывается относительно размера экрана и масштаба игрока.

bulletScale = Math.min(canvas.width / 900, canvas.height / 900);
bulletRadius = 10 * bulletScale * player.scale;

- Отрисовка каждой пули: для каждой пули создается круг с заданным радиусом и координатами.

ctx.arc(bullet.x * cellSize, bullet.y * cellSize, bulletRadius, 0, Math.PI * 2);

Здесь мы так же используем размер ячейки.

Таким образом, вы можете легко задавать поле лабиринта с помощью массива и визуализировать его drawMaze(). Настройка символов и их цветов позволяет создавать разнообразные элементы на поле. А механика стрельбы включает в себя создание, обновление, отрисовку пуль и их взаимодействие со стенами, что позволяет игроку взаимодействовать с полем лабиринта. Настройка скорости стрельбы и возможность изменения визуализации пуль могут сделать игровой процесс более увлекательным.