Сапёр в изометрии. Поле — настоящая земля с травой. Под ней — противотанковые мины. Задача: обезвредить всё, выжить, отметить каждую угрозу.
«Что если сапёр — это не серые клетки, а настоящий участок земли? Трава колышется, флажки стоят в грунте, а под каждым кликом — риск.»
ISO MINES — полевая версия классического сапёра. Игрок получает изометрическое поле: каждая клетка — ромб земли с травяной поверхностью. Под травой — цифры, предупреждающие о минах в соседних клетках. Цель — раскопать всё безопасное и отметить каждую мину флажком.
Трава шевелится на ветру. Бабочки порхают. Облака плывут. Это не сетка — это клочок земли.
Противотанковые мины. Взрыв сотрясает экран, выбрасывает грязь, искры и дым. Нет пощады.
Красные флажки втыкаются в землю и развеваются. Каждый — решение. Каждый — риск.
Каждый клик — частицы. Каждая победа — салют. Каждый провал — эпичный взрыв.
Поле в изометрии: каждая клетка — ромб, наклонённый под 30°. ЛКМ — раскопать. ПКМ / долгий тап — поставить флажок. Первый клик всегда безопасен: поле генерируется после него, зона 3×3 вокруг клика свободна от мин.
Каскадное открытие: клетка с 0 мин вокруг открывает всех соседей рекурсивно.
| Действие | Мышь | Клавиатура | Тач |
|---|---|---|---|
| Раскопать | ЛКМ | Enter / Space | Тап |
| Флажок | ПКМ | F | Долгий тап 400мс |
| Chord | ЛКМ по цифре | Enter по цифре | Двойной тап по цифре |
| Навигация | — | Стрелки / WASD | Тап для выделения |
| Пауза | Кнопка | P / Esc | Кнопка |
| Участок | Размер | Мин | Особенности |
|---|---|---|---|
| Новичок | 9 × 9 | 10 | Базовая подготовка |
| Любитель | 16 × 16 | 40 | Стандартный участок |
| Профессионал | 30 × 16 | 99 | Поле для спецназа |
| Экстрим | 30 × 24 | 180 | Плотное минирование |
| Событие | Очки |
|---|---|
| Раскопать клетку | +10 |
| Каскад (1 клетка) | +5 |
| Правильный флажок (при победе) | +50 |
| Победа | +1000 × множитель |
| Бонус за время | +max(0, (300 − сек) × 2) |
| Серия верных флажков | ×1.5 к флажкам |
4 уровня сложности. Обычные правила. Рекорды по времени и очкам.
10 попыток. Лучшее время фиксируется. Нет очков — только секунды.
Каждые 30 секунд автоматически открывается одна безопасная клетка. Помощь, но штраф к очкам.
Флажков нет. Только раскапывание. Ошибка — смерть. Для профи.
После победы поле растёт: +2 строки, +10% мин. До первого поражения.
Видно только в радиусе 3 от последнего клика. Остальное — темнота. Фонари — бонусы.
Волна синусоиды с разной фазой на каждой клетке. Скорость — сила ветра (рандом при старте).
1–3 штуки летают по кривым Безье. Улетают при взрыве.
2–4 облака на фоне, параллакс при движении мыши.
Градиент солнца на фоне. Клетки ближе к свету — ярче.
| Местность | Разблокировка | Описание |
|---|---|---|
| Лето | Всегда | Зелёная трава, яркое солнце, голубое небо |
| Осень | Уровень 3 | Оранжевая трава, падающие листья, тёплый свет |
| Зима | Уровень 6 | Снег, лёд, снежинки |
| Пустыня | 50 побед | Песок, кактусы, волны жары |
| Марс | Уровень 10 | Красный грунт, звёзды, низкая гравитация частиц |
| Неон | 100 игр | Тёмное поле, светящиеся цифры, голографические мины |
Весь звук — процедурный, через Web Audio API. Никаких файлов.
| Слой | Условие | Описание |
|---|---|---|
| Ambience | Старт | Сверчки, ветер, тихий drone |
| Rhythm | 5 открытий | Перкуссия, noise bursts, BPM 80 |
| Melody | 25 открытий или 50% поля | Triangle melody, пентатоника, осторожная |
| Tension | <20% закрытых | Нарастающий drone, диссонанс |
Глобальный уровень. Сохраняется в localStorage. XP: 20 базово + сложность + время + точность.
| Награда | Условие | XP |
|---|---|---|
| Первый шаг | Первая клетка | 10 |
| Каскадёр | Каскад 20+ клеток | 50 |
| Мастер каскада | Каскад 50+ клеток | 150 |
| Флаговод | 100 флажков | 30 |
| Снайпер | 50 флажков подряд без ошибки | 100 |
| Сапёр-новичок | Победа на лёгком | 20 |
| Сапёр-профи | Победа на среднем | 50 |
| Сапёр-ветеран | Победа на сложном | 100 |
| Сапёр-легенда | Победа на экстриме | 200 |
| Молниеносный | Сложный быстрее 60 сек | 250 |
| Безупречный | Победа без ошибочных флажков | 80 |
| Глаз-алмаз | Победа в Точности | 150 |
| Строитель | 5-й уровень в Строителе | 120 |
| Ночной страж | Победа в Ночи | 100 |
| Аркадный чемпион | Аркада без подсказок | 100 |
| Серийный победитель | 3 победы подряд | 80 |
| Неостановимый | 10 побед подряд | 250 |
| Искатель | 10 фонарей в Ночи | 60 |
| Регуляр | 25 игр | 50 |
| Ветеран | 100 игр | 150 |
Скины — процедурный Canvas. Зима, Пустыня, Марс, Неон имеют уникальные анимации.
Выбор в профиле. Заблокированные — серые с замком. Сохраняется в localStorage.
| Жест | Действие |
|---|---|
| Тап по закрытой | Раскопать |
| Долгий тап 400мс | Флажок |
| Двойной тап по цифре | Chord |
Один HTML. Нет зависимостей, сборщиков, фреймворков. Работает офлайн.
Canvas 2D. Два слоя: field-canvas + fx-canvas для частиц.
Web Audio API — процедурный звук. Нет аудиофайлов.
localStorage. XP, уровень, статистика, достижения, скин, настройки, рекорды.
Vanilla JS. Плоский массив клеток: {mine, revealed, flagged, adjacent, bonus}.
Object pool для частиц. RAF loop. Музыка — раз в 30 кадров. Изометрия — предрасчёт.
initGame(difficulty) ├── Создать матрицу width × height ├── firstClick = true └── startRenderLoop() onCellClick(x, y) ├── Если firstClick: generateMines(x, y) ├── Если flagged: ничего ├── Если mine: explode() → частицы, взрыв, game over ├── Иначе: reveal(x, y) │ ├── Если adjacent === 0: floodFillReveal(x, y) │ ├── particles(dirt) │ └── checkWin() └── updateMusicLayers() generateMines(safeX, safeY) ├── Случайная растановка N мин ├── Исключение зоны 3×3 вокруг (safeX, safeY) └── Подсчёт adjacent для каждой не-мины floodFillReveal(x, y) ├── Очередь BFS/DFS ├── Для каждой клетки с adjacent === 0: добавить соседей └── Для каждой открытой: particles(dust) onCellRightClick(x, y) ├── toggleFlag(x, y) ├── particles(flag) └── checkWin() onChord(x, y) ├── Если flagsAround === adjacent: revealAllAround() ├── Если среди них mine: explode() └── Иначе: particles(dust) + checkWin()