Создаём игру «Сапёр» в С++/SFML

  Дмитрий Бушуев  | 

  Обновл. 8 Фев 2020  | 

 6515

Игра «Сапёр» (англ. «Minesweeper«) — это простая, но в то же время очень интересная игра-головоломка. В начале игры открывается поле, разделенное на ровные клетки, на котором спрятаны мины. Когда игрок кликает мышкой по произвольной клетке на поле, то в этой клетке появляется цифра, показывающая сколько мин спрятано по соседству. Анализируя эти цифры можно понять, где спрятаны следующие мины. Затем на клетке (в которой игрок предполагает, что спрятана мина) ставится флажок для наглядного обозначения мины.

Таким образом, задача игрока — найти все мины, спрятанные на игровом поле, и при этом постараться не подорваться на них. А наша задача — разработать игру «Сапёр» средствами графической библиотеки SFML и языком программирования С++.

Модель игрового поля

Начнём с графики. Для обозначения элементов игрового поля нам потребуются картинки закрытой клетки, открытой пустой клетки, флажка, мины и цифр от 1 до 8. Т.к. отдельными изображениями пользоваться не очень удобно, то будет лучше, если мы соединим их в единую текстуру, а уж из неё по мере необходимости вырежем нужный элемент:

Размеры одного квадратного элемента текстуры составляют 32х32 пикселя. Размеры игрового поля — 10х10 квадратов.

Теперь перейдём непосредственно к написанию кода. Как вы уже наверняка знаете, минимальный каркас SFML-приложения имеет примерно следующий вид:

Модель игрового поля составляют 2 двумерных массива:

   int gridLogic[12][12] — представляет логическую часть игрового поля;

   int gridView[12][12] — отображает графическую составляющую игрового поля.

В коде это выглядит следующим образом:

Далее нужно создать спрайт из заготовленной текстуры и сформировать первоначальный вид игрового поля. Для этого мы всем элементам массива gridView[i][j] присваиваем значение (10) соответствующего порядкового номера квадратика текстуры:

Добавим функцию отрисовки игрового поля:

И в результате получим вот такую заготовку:

*Примечание: Если у вас ничего не отображается, то попробуйте прописать полный путь до файла текстуры. Например, вместо:

укажите:

При этом у вас на компьютере должна быть папка C:\images, в которой должен находиться файл tiles.jpg.

Расстановка и подсчёт мин


Для расстановки мин на игровом поле воспользуемся генератором случайных чисел с заданным диапазоном значений от 0 до 4. Если выпадает ноль, то ставим мину (9). В противном случае, пустая клетка (0). Индексы (9) и (0) совпадают с порядковыми номерами соответствующих изображений в текстуре:

Дальше реализуем подсчёт мин окружающих каждую клетку. Для этого в двойном цикле for поочерёдно пройдёмся по каждой клетке. Если в текущей клетке уже стоит мина, то просто переходим к новому шагу итерации. Если же в текущей клетке мины нет, то с помощью 9 условий if поочерёдно проверяем все примыкающие к ней клетки. Если там есть мины, то на каждом сработавшем if увеличиваем счётчик количества мин на 1:

Посмотрим, что у нас получилось. Для этого в код ниже добавим строчку gridView[i][j] = gridLogic[i][j], тем самым отобразив всё поле на экране:

Результат:

*Примечание: Учитывайте, что расстановка мин генерируется случайным образом. Поэтому ваш результат запуска программы наверняка будет отличаться от того, что изображено выше.

Обработка нажатий кнопок мыши

Теперь добавим функции обработки нажатия ЛКМ и установки флажка по щелчку ПКМ. Если по нажатию ЛКМ мы открыли клетку, а там находится мина, то следом открываем всё поле — игра окончена:

Настало время запустить приложение «Сапёр» и посмотреть на готовый игровой процесс:


Заключение


Вот такое небольшое и довольно простое приложение можно написать, используя средства C++ и SFML. Конечно, наша игра далека от идеала и не лишена недостатков. Например, алгоритм игры не исключает ситуации, когда игрок может проиграть уже на первом ходу. Также отсутствуют такие элементы игрового процесса, как: таймер обратного отсчёта, кнопки перезапуска и паузы игры, подсчёт уже отмеченных игроком мин и т.д. Возможно, мы рассмотрим реализацию подобных механизмов в следующих статьях, но ничего не мешает и вам самим попробовать добавить данный функционал. Как говорится, дорога в тысячу миль начинается с первого шага. Этот первый шаг мы сделали вместе, а дальше — дело за вами.

Дерзайте 🙂

*Статья написана по мотивам одноименного видеоролика за авторством FamTrinli.

Исходный код игры «Сапёр» в C++/SFML.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (11 оценок, среднее: 4,55 из 5)
Загрузка...

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *