Skip to content

ellvenro/WinAPI_shooter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Простая программа, реализованная с помощью графических приметивов API Windows

2D шутер-аркада с видом сверху

Программа реализовывает простую шутер-игру. Персонаж игрока – зеленый квадрат в центре окна, управление им производится с помощью клавиш W, A, S, D. Враги игрока – красные круги, которые постоянно появляются и требуют уничтожения. Игрок умирает, когда он касается врага.

В программе реализована возможность уничтожения врагов через стрельбу, которая производится нажатием левой кнопки мыши. Программа начинается заново при нажатии клавиши ПРОБЕЛ.

Видео с демонстрацией работы программы.

Данный шутер является бесконечной игрой на получение рекорда. Количество уничтоженных врагов запоминается, при проигрыше является показателем установки рекорда.

За основу взято видео: Язык Си – Пишем простую игру шутер с помощью WinAPI =).

Основные моменты при реализации

Программа реализована в среде Microsoft Visual Studio 2019. При клонировании репозитория в MS VS запуск программы необходимо осуществлять с помощью WinAPI_shooter.sln. После запуска программы в папке WinAPI_WinAPI_shooter/Debug будет создан файл WinAPI_shooter.exe, работающий отдельно.

Внутренние аспекты программы

Для реализации программы был создан класс object, описывающий каждый объект. Файл object.h содержит описание класса, а файл object.cpp его реализацию. Класс содержит методы для инициализации объекта, отображения на экране, подсчета сдвига объекта и задания скорости в зависимости от конечной точки. Также осуществляется возвращение некоторых данных класса с помощью методов get. Был реализован конструктор копирования и перегрузка оператора присваивания.

Была создана дружественная функция для проверки пересечения двух объектов. Проверка осуществляется между врагами и пулями, также между врагами и игроком.

Данные организованы в программе с помощью динамического массива, содержащего объекты класса. Для пуль и врагов массив один. При создании и удалении объектов массив перезаписывается.

Создание и удаление элемента динамического массива с количеством элементов, равных masCnt.

// Производится создание копии массива с количеством элементов, на единицу больше
object* buf = new object[masCnt + 1];
// Изначальный массив копируется в новый, а старый удаляется
for (int i = 0; i < masCnt; i++)
    buf[i] = masObject[i];
delete[] masObject;
masObject = buf;
...
masCnt--;
// Элемент, подлежащий удалению затирается последним
masObject[i] = masObject[masCnt];
// Производится создание копии массива с количеством элементов, на единицу меньше
object* buf = new object[masCnt];
// Изначальный массив копируется в новый, а старый удаляется
for (int j = 0; j < masCnt; j++)
    buf[j] = masObject[j];
delete[] masObject;
masObject = buf;

Графическая составляющая программы

Для отрисовки объектов был создан виртуальный контекст для рисования в памяти и изображение. После отрисовки изображение было скопировано из виртуальной памяти на форму.

HDC memDC = CreateCompatibleDC(dc);
HBITMAP memBM = CreateCompatibleBitmap(dc, rct.right - rct.left, rct.bottom - rct.top);
SelectObject(memDC, memBM);
...
BitBlt(dc, 0, 0, rct.right - rct.left, rct.bottom - rct.top, memDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
DeleteObject(memBM);

Отрисовка всех объектов производится с помощью графических примитивов: квадратов и эллипсов. Вывод текста производится с помощью функций TextOut и DrawTextA. С помощью CreateFont производится создание необходимого шрифта. При выводе текста на экран выбирается необходимый шрифт, в конце удаляется.

BeginPaint(hwnd, &ps);
SelectObject(memDC, font);
TextOut(memDC, 10, 10, (LPWSTR)buff, numChar);
DeleteObject(font);
EndPaint(hwnd, &ps);

При каждом изменении положения игрока производится вычисление сдвига по осям и положение всех объектов корректируется так, чтобы игрок оставался в центре экрана.

Добавление врагов производится два раза в определенное количество тактов (rate) с использованием рандомных чисел. Количество тактов постепенно уменьшается при увеличении количества убитых врагов.

int k = rand() % rate;
if (k == 1)
    NewObject(pos1 + x, pos2 + y, 40, 40, ENEMY);
if (k == 2)
    NewObject(pos2 + x, pos1 + y, 40, 40, ENEMY);

About

26.07.2021 Простой шутер, реализованный с помощью WinAPI

Topics

Resources

Stars

Watchers

Forks

Languages