Все статьи / Ещё одна практика на SFML

На этом занятии вы освоите более гибкие приёмы работы с SFML: виртуальную камеру, рисование произвольных фигур, проверку столкновения


Задания из этой практики выполняются на выбор, в любом порядке.

Все задания надо выполнять с учётом нескольких требований:

  • нужно соблюдать Соглашения о кодировании на C++
  • программа должна быть разделена на части с помощью функций (или методов) и типов данных (например, структур либо классов)
    • вам поможет руководство Классы в C++ для новичков
    • вы должны следовать паттерну Game Loop и выделить шаги игрового цикла в отдельные функции (например, в функции createWindow, init, pollEvents, update, drawFrame)
    • размер одной функции не превышает 20 строк, в идеале от 1 до 15 строк
  • программа должна быть разделена на несколько файлов
    • вам поможет руководство Программы из нескольких файлов на C++
    • один из файлов должен называться main.cpp, он должен содержать только функцию main и, возможно, несколько функций, составляющих игровой цикл; всё остальное находится в других файлах
  • сделанные работы выкладываются на github

В выполнении заданий могут помочь следующие статьи:

Также вы можете изучить примеры на странице github.com/ps-group/sfml-from-scratch

Задание workshop3.1 (до 3 баллов)

Часть I (1 балл)

Напишите программу, которая рисует ваше имя либо ваши инициалы с помощью примитива sf::Text. Имя (инициалы) должно быть нарисовано в круге с обводкой.

Скриншот

Часть II (1 балл)

Модифицируйте программу, чтобы шарик с инициалами подпрыгивал. Прыжок должен происходит по правилам равноускоренного движения: в начале прыжка шарик получает начальную скорость, которую затем постепенно теряет из-за гравитации - до тех пор, пока не столкнётся с землёй. Прыжки шарика должны повторяться в цикле.

Часть III (1 балл)

Доработайте программу так, чтобы ваш тип данных был классом и наследовался от Drawable, а рисовать кружок с вашими инициалами можно было привычным и удобным способом:

window.draw(initials);

Задание workshop3.2 (до 6 баллов)

Реализовать камеру вам поможет руководство Controlling the 2D camera with views

В этом задании вы сможете вернуться к прошлой задаче с шариками!

Иллюстрация

Часть I (2 балла)

Увеличьте размер виртуального поля с шариками так, чтобы он был в 3 раза больше размера окна и по ширине, и по высоте. Добавьте возможность передвигаться по увеличенному полю с помощью клавиш-стрелок, которые передвигают виртуальную камеру, основанную на sf::View.

Чтобы совместить камеру и обработку нажатий мыши, надо учесть, что координаты в событиях мыши заданы в оконной системе координат, а координаты фигур заданы в системе координат сцены; при установке своего View эти системы координат становятся различными. Вы можете использовать методы sf::RenderWindow::mapPixelToCoords и sf::RenderWindow::mapCoordsToPixel, которые преобразуют вектора из оконной системы координат в систему координат сцены и обратно.

Часть II (2 балла)

Закон притяжения в векторной форме вы можете найти в статье Newton’s law of universal gravitation

Добавьте в систему с шариками взаимное притяжение: небольшая сила должна притягивать шары друг к другу.

  • можно считать, что сила, действующая на шарик, равна сумме сил притяжения к каждому из остальных шариков
  • корректно решать задачу трёх тел не нужно, достаточно на каждом кадре подсчитывать суммарную силу и затем применять её
  • сила притяжения обратно пропорциональна квадрату расстояния между шариками

Вы можете изучить интерактивный пример на JavaScript.

Часть III (2 балла)

Закон кулоновского отталкивания в векторной форме вы можете найти в статье Newton’s law of universal gravitation

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

Задание workshop3.3 (2 балла)

Рисовать линии вам поможет руководство Designing your own entities with vertex arrays

Напишите программу, которая рисует линию между центром окна и курсором, а также выводит в консоль расстояние от центра окна до курсора (в пикселях). Программа не обязана обрабатывать ситуации, когда курсор находится за пределами окна.

Иллюстрация

Вы можете изучить интерактивный пример на JavaScript.

Задание workshop3.4 (3 балла)

Рисовать космический корабль вам поможет руководство Designing your own entities with vertex arrays

Напишите программу, в которой под управлением клавиш-стрелок в космическом пространстве двигается космический корабль.

  • Клавиша Вверх включает двигатели (до тех пор, пока клавишу не отпустят)
  • Клавиши Влево/Вправо наращивают/убавляют угол поворота корабля
  • Корабль должен обладать инерцией, т.е. при нажатии на клавиши-стрелки скорость не сразу возрастает до предельной
  • Скорость поворота корабля ограничена
  • На корабль действует сила, направленная против его движения, и эта сила увеличивается с ростом скорости корабля пропорционально квадрату скорости

Иллюстрация

Вы можете изучить интерактивный пример на JavaScript.

Задание workshop3.5 (3 балла)

Функции для работы с датой и временем описаны в документации языка C. Скорее всего вам пригодятся функции std::time и std::localtime, которые позволят получить объект типа std::tm.

В рамках задания следует разработать приложение, симулирующее аналоговые часы. Требования по внешнему виду показаны ниже на иллюстрации. В том числе:

  • по краям циферблата должны быть расположены 12 арабских или римских цифр
  • также по краям циферблата должны стоять 60 засечек, из них 12 крупнее остальных (т.к. в них попадает часовая стрелка в начале каждого часа)
  • отображаемое время совпадает с локальным временем пользователя системы
  • секундная стрелка должна отличаться по цвету от остальных стрелок

Стрелки должны передвигаться раз в секунду; секундная стрелка за это время передвинется на одно деление, минутная - на 1/60 часть деления, а часовая - на 1 / (60 * 12) часть деления.

Иллюстрация

Задание workshop3.6 (3 балла)

Напишите программу, в которой блоки случайно выбранного размера со случайно выбранной координатой x падают с верхней границы экрана вниз. Блоки должны накладываться друг на друга. Чтобы проверить, пересекается ли блок с другими блоками, достаточно проверить пересечение двух прямоугольников.

Иллюстрация

Если выровненные по осям координат прямоугольники пересекаются, то их пересечение будет прямоугольником, в котором:

  • левая граница равна наименьшей из двух левых границ двух прямоугольника
  • правая граница равна наибольшей из двух правых границ двух прямоугольника
  • верхняя граница равна наименьшей из двух верхних границ двух прямоугольника
  • нижняя граница равна наибольшей из двух нижних границ двух прямоугольника

Если же вычисленный таким образом прямоугольник области пересечения имеет отрицательную ширину или высоту, то прямоугольники не пересекаются.

Иллюстрация

Вы можете изучить интерактивный пример на JavaScript.