Танк на игровом поле
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(). Настройка символов и их цветов позволяет создавать разнообразные элементы на поле. А механика стрельбы включает в себя создание, обновление, отрисовку пуль и их взаимодействие со стенами, что позволяет игроку взаимодействовать с полем лабиринта. Настройка скорости стрельбы и возможность изменения визуализации пуль могут сделать игровой процесс более увлекательным.