«Танчики» на HTML5
Уничтожение базы
Что сделано и как.
Ну во-первых появилась сущность Базы
class Base {
constructor(x, y, gameMap = null) {
this.x = x;
this.y = y;
this.width = BASE_SIZE;
this.height = BASE_SIZE;
// Состояние
this.destroyed = false;
// Временная защита бетоном (бонус "лопата")
this.fortified = false;
this.fortifyTimeLeft = 0;
// Ссылка на карту
this.gameMap = gameMap;
}
}
Там на самом деле много служебных методов, типа рендера и получить границы. Но их сюда не пихаю, так как там ничего интересного. Есть ещё метод takeDamage, который просто удаляет визуальное отображение базы с экрана и помечает базу как уничтоженную.
В main.js появились такие нюансы:
for (const bullet of bullets) {
if (!bullet.active) continue;
bullet.update(gameMap, allTanks);
// Создаём эффекты при попадании
if (bullet.hitResult === 'base') {
// Попадание в базу - большой взрыв и мгновенный Game Over
if (base && !base.destroyed) {
const baseCenterX = base.x + base.width / 2;
const baseCenterY = base.y + base.height / 2;
effects.push(createBigExplosion(baseCenterX, baseCenterY));
base.takeDamage();
gameOver = true;
}
} else if (bullet.hitResult === 'tank' && bullet.hitTarget) {
// Попадание в танк - большой взрыв в центре танка
...
} else if (bullet.hitResult === 'wall') {
// Попадание в стену - маленький взрыв в позиции пули
...
}
}
//Не очень мне нравится это, скорее всего на финальном этапе полировки, перепишу
Внутри "коллизии" появился новый метод
export function checkBulletBaseCollision(bullet, base) {
if (!base || base.destroyed) return false;
const bulletBox = {
x: bullet.x,
y: bullet.y,
width: BULLET_SIZE,
height: BULLET_SIZE
};
const baseBox = base.getBounds();
return checkAABBCollision(bulletBox, baseBox);
}
В оригинальной игре квадратики справа от игрового поля показывали, сколько танков ещё должно родиться, я решил сделать, чтоб отображалось сколько танков ещё осталось убить для завершения уровня. Ну а сам спавн сделан вот таким образом:
function updateEnemySpawn() {
// Не спавним если игра окончена или уровень пройден
if (gameOver || stageComplete) return;
// Не спавним если больше нет врагов
if (enemiesRemaining <= 0) return;
// Не спавним если на экране максимум врагов
if (enemies.length >= SpawnSettings.MAX_ON_SCREEN) return;
// Уменьшаем таймер
spawnCooldown--;
// Если таймер истёк - спавним врага
if (spawnCooldown <= 0) {
// Получаем текущую точку спавна
const spawnPoint = ENEMY_SPAWN_POINTS[spawnPointIndex];
// Спавним врага
spawnEnemy(spawnPoint.x, spawnPoint.y);
// Уменьшаем счётчик оставшихся врагов
enemiesRemaining--;
// Переключаемся на следующую точку (по кругу)
spawnPointIndex = (spawnPointIndex + 1) % ENEMY_SPAWN_POINTS.length;
// Сбрасываем таймер
spawnCooldown = SpawnSettings.SPAWN_COOLDOWN;
// Обновляем ссылки на танки
updateAllTanksReferences();
}
}
Я, честно признаться, не помню как там оно было на дэнди, поэтому решил, что начиная с этого этапа уже не буду пытаться повторить танки какими они были на самом деле, а буду делать такими, какими я их помню/вижу в своей голове. Так что тут могут начаться расхождения с каноном. Но, учитывая, что я в итоге собираюсь сделать с игрой, это меньшее зло))
Комментарий