Аналоговые часы SFML C++

Аналоговые часы SFML C++

Мультимедийная библиотека SFML лечит головную боль не только новичкам в игровой индустрии, но и преподавателям информатики в школе. Основная задача которых состоит в том, чтобы не только научить ребёнка программировать, но и привить любовь к разработке приложений. Используя простые графические объекты и их методы можно за короткое время создать прототип игры или симулятор физико-математических процессов. В этой статье мы рассмотрим разработку аналоговых часов на C++ используя библиотеку SFML.

Инструменты для разработки

Подготовительная работа

Подключаем к Visual Studio библиотеку SFML и копируем шаблон кода библиотеки SFML в редактор кода.

#include <SFML/Graphics.hpp> #include"SFMLWorldTime.h" using namespace sf; int main() { // Создаём графическое окно размером 900х900 RenderWindow window(VideoMode(900, 900), L"Аналоговые часы", Style::Default); window.setVerticalSyncEnabled(true); // Вертикальная синхронизация SFMLWorldTime etm(50, 50, 4, Color::Yellow); // Объект электронные часы while (window.isOpen()) { Event event; while (window.pollEvent(event)) { if (event.type == Event::Closed) window.close(); } window.clear(Color::Blue); // Очищаем графическое окно и закрашиваем в синий цвет etm.drawTime(window); // Рисуем электронные часы в графическом окне window.display(); } return 0; }

Добавляем в папку проекта файлы SFMLWorldTime.h и SFMLWorldTime.cpp и папку со шрифтами lib.

Добавляем в проект файлы SFMLWorldTime.h и SFMLWorldTime.cpp.

Аналоговые часы SFML C++
Аналоговые часы SFML C++

В код шаблона программы прописываем вызов заголовочного файла SFMLWorldTime.h.

#include"SFMLWorldTime.h"

Создаём объект электронные часы и рисуем их в графическом окне.

SFMLWorldTime etm(50, 50, 4, Color::Yellow); etm.drawTime(window);
Аналоговые часы SFML C++

Часовых дел мастер

#define _USE_MATH_DEFINES #include <SFML/Graphics.hpp> #include"SFMLWorldTime.h" #include<math.h> using namespace sf; using namespace std; int main() { RenderWindow window(VideoMode(900, 900), L"Аналоговые часы", Style::Default); window.setVerticalSyncEnabled(true); SFMLWorldTime etm(50, 50, 4, Color::Yellow); // Корпус аналоговых часов CircleShape circleTime(300.f); circleTime.setOrigin(150, 150); circleTime.setPosition(303, 303); circleTime.setFillColor(Color::Blue); circleTime.setOutlineThickness(10); circleTime.setOutlineColor(Color::Yellow); // Риски аналоговых часов объявление переменных CircleShape PointMin; PointMin.setFillColor(Color::Yellow); float radiusNum = 280; // радиус расположения рисок float radiusPoint; float CenterClockX = 450; float CenterClockY = 450; float xPoint, yPoint; // Оцифровка циферблата аналоговых часов объявление переменных Font fontTime; if (!fontTime.loadFromFile("lib/dockerthree.ttf")) return 777; Text TimeText; TimeText.setFont(fontTime); TimeText.setCharacterSize(30); TimeText.setFillColor(Color::Yellow); float numx, numy; // Рисуем стрелки аналоговых часов RectangleShape secArrow(Vector2f(2, 280)); //секундная InitRect(secArrow, 453, 453, 1, 280, Color::Red); RectangleShape minArrow(Vector2f(8, 260)); //минутная InitRect(minArrow, 455, 455, 4, 260, Color::Yellow); RectangleShape hourArrow(Vector2f(12, 180)); //часовая InitRect(hourArrow, 455, 455, 6, 180, Color::Yellow); while (window.isOpen()) { Event event; while (window.pollEvent(event)) { if (event.type == Event::Closed) window.close(); } window.clear(Color::Blue); etm.drawTime(window); // электронные часы window.draw(circleTime); // корпус аналоговых часов // Риски аналоговых часов for (int a = 0; a < 60; a++) { if (a % 5 == 0) radiusPoint = 8; else radiusPoint = 4; xPoint = CenterClockX + radiusNum * cos(-6 * a * (M_PI / 180) + M_PI / 2); yPoint = CenterClockY - radiusNum * sin(-6 * a * (M_PI / 180) + M_PI / 2); PointMin.setRadius(radiusPoint); PointMin.setOrigin(radiusPoint / 2, radiusPoint / 2); PointMin.setPosition(xPoint, yPoint); window.draw(PointMin); } // Оцифровка циферблата аналоговых часов for (int i = 1; i <= 12; i++) { numx = CenterClockX + (radiusNum - 30) * cos(-30 * i * (M_PI / 180) + M_PI / 2); numy = CenterClockX - (radiusNum - 30) * sin(-30 * i * (M_PI / 180) + M_PI / 2); if (i <= 5) TimeText.setPosition(numx - 10, numy - 17); else TimeText.setPosition(numx - 8, numy - 15); TimeText.setString(to_string(i)); window.draw(TimeText); } secArrow.setRotation(6 * etm.getsec()); // вращение секундной стрелки minArrow.setRotation(6 * etm.getmin() + etm.getsec() * 0.1); // вращение минутной стрелки hourArrow.setRotation(30 * etm.gethour() + etm.getmin() * 0.5); // вращение часовой стрелки window.draw(hourArrow); // часовая стрелка window.draw(minArrow); // минутная стрелка window.draw(secArrow); // секундная window.display(); } return 0; }

Рисуем окружность т.е. контур будущих часов

// Блок объявления и установки параметров объектов CircleShape circleTime(300.f); circleTime.setOrigin(150, 150); circleTime.setPosition(303, 303); circleTime.setFillColor(Color::Blue); circleTime.setOutlineThickness(10); circleTime.setOutlineColor(Color::Yellow); // Блок отрисовки графических объектов window.draw(circleTime);
Аналоговые часы SFML C++

Подключаем макрос математических констант

#define _USE_MATH_DEFINES

Подключаем заголовочный файл математических функций

#include<math.h>

Объявляем объекты и переменные для рисования рисок часов.

Создаём объект круга, который и будет отображать окружность в виде рисок.

// Блок объявления и установки параметров объектов CircleShape PointMin; // объект круга PointMin.setFillColor(Color::Yellow); // цвет круга жёлтый

Объявим и инициализируем вещественную переменную значением расстояния от центра часов до расположения рисок.

float radiusNum = 280;
Аналоговые часы SFML C++

Создадим вещественную переменную размера рисок т.е. радиуса объекта круга PointMin

float radiusPoint;

Обозначим переменными координаты центра окружности

float CenterClockX = 450; float CenterClockY = 450;
Аналоговые часы SFML C++

Объявим переменные координат рисок

float xPoint, yPoint;

Рисуем риски в графическом окне

for (int a = 0; a < 60; a++) { // каждой пятой риски увеличиваем радиус if (a % 5 == 0) radiusPoint = 8; else radiusPoint = 4; // вычисляем координаты риски xPoint = CenterClockX + radiusNum * cos(-6 * a * (M_PI / 180) + M_PI / 2); yPoint = CenterClockY - radiusNum * sin(-6 * a * (M_PI / 180) + M_PI / 2); // задаём координаты и параметры риски т.е. объекту круга PointMin PointMin.setRadius(radiusPoint); PointMin.setOrigin(radiusPoint / 2, radiusPoint / 2); PointMin.setPosition(xPoint, yPoint); // рисуем риску в графическом окне window.draw(PointMin); }

В формуле вычисления координат рисок, используем математическую константу числа Пи - M_PI.

Объявим объекты и переменные для отображения циферблата часов

Загрузим шрифт для отображения цифр, создаём объект шрифта fontTime и загружаем в него шрифт dockerthree.ttf

Font fontTime; if (!fontTime.loadFromFile("lib/dockerthree.ttf")) return 777;

Создаём объект текста и задаём ему параметры: шрифта, размера и цвета.

Text TimeText; TimeText.setFont(fontTime); TimeText.setCharacterSize(30); TimeText.setFillColor(Color::Yellow);

Объявляем переменные координат текстового объекта, для отображения цифр.

float numx, numy;

Рисуем циферблат в графическом окне

for (int i = 1; i <= 12; i++) { // вычисляем координаты для текстового объекта с цифрами numx = CenterClockX + (radiusNum - 30) * cos(-30 * i * (M_PI / 180) + M_PI / 2); numy = CenterClockX - (radiusNum - 30) * sin(-30 * i * (M_PI / 180) + M_PI / 2); // Корректируем координаты расположения цифр if (i <= 5) TimeText.setPosition(numx - 10, numy - 17); else TimeText.setPosition(numx - 8, numy - 15); // заносим значение цифры в текстовый объект TimeText.setString(to_string(i)); // рисуем текстовый объект window.draw(TimeText); }
Аналоговые часы SFML C++

Объявляем объекты для стрелок часов и настраиваем их.

RectangleShape secArrow(Vector2f(2, 280)); // Секундная стрелка InitRect(secArrow, 453, 453, 1, 280, Color::Red); RectangleShape minArrow(Vector2f(8, 260)); // Минутная стрелка InitRect(minArrow, 455, 455, 4, 260, Color::Yellow); RectangleShape hourArrow(Vector2f(12, 180)); // Часовая стрелка InitRect(hourArrow, 455, 455, 6, 180, Color::Yellow);

Графическое отображение стрелок базируются на объекте формы прямоугольника RectangleShape. Настраиваем объекты с помощью функции InitRect (), которая находится в заголовочном файле SFMLWorldTime.h.

Рисуем стрелки часов

// Изменение угла положения прямоугольников т.е. стрелок secArrow.setRotation(6 * etm.getsec()); // Вращение секундной стрелки minArrow.setRotation(6 * etm.getmin() + etm.getsec() * 0.1); // Вращение минутной стрелки hourArrow.setRotation(30 * etm.gethour() + etm.getmin() * 0.5); // Вращение часовой стрелки // Рисование стрелок в графическом окне window.draw(hourArrow); // часовая стрелка window.draw(minArrow); // минутная стрелка window.draw(secArrow); // секундная

Метод setRotation вращает объект вокруг заданной оси, согласно установленному углу поворота в параметрах метода.

Рассчитаем угол поворота стрелок.

Секундная стрелка повернется на угол равный 360 °/60 сек = 6 ° (вся окружность 360 ° по ней распределяем 60 секунд) и умножаем на текущее значение времени секунд.

Минутная стрелка за это время повернется на 360 °/60 мин = 6 ° умноженных на текущее значение времени минут и добавляем 6 °/60сек=0.1 ° умноженный на количество пройденного времени секунд.

Часовая стрелка за это время повернётся на 360°/12 часов = 30 ° умноженных на текущее время часов и добавляем 30 °/60мин=0,5° умноженным на пройденное время минут.

Более подробную инструкцию вы можете получить посмотрев видео "Аналоговые часы SFML C++".

22
4 комментария

круто , а я на с# пишу можешь почитать посты мои

Ответить

Конечно почитаю, я пишу код на unity

Ответить