OpenSiv3D로 아날로그 시계 그려보기

28250 단어 C++siv3dopensiv3dtech

만든 물건


최근에 OpenSiv3D를 접하지 못한 것 같아서 프로그램을 만들어서 API를 복습하면서 아날로그 시계를 그렸습니다.

크기 관리를 위한 변수 및 배경색 설정


먼저 시계의 크기와 바늘의 굵기를 관리하기 위해 변수를 설명합니다.
겸사겸사 배경색Scene::SetBackground(Palette::Black)을 블랙으로 설정합니다.
Main.cpp
# include <Siv3D.hpp>

void Main()
{
    // 縁の半径
    const int size = 200;
    // 針の太さのベース(時針の太さ)
    const int thick = 6;
    // 時刻用のフォント
    const Font hourFont(24);

    // 背景を黒に
    Scene::SetBackground(Palette::Black);

    while (System::Update())
    {
    }
}

시계 테두리 그리기


다음은 화면 중심에 시계 가장자리를 그립니다.화면의 중심 좌표Scene::Center()Point형의 중심 좌표를 얻을 수 있다.
그런 다음 가장자리에서 중심까지의 선을 그립니다.전방에 모두 60개for (auto i : step(60)가 있기 때문에 60개의 선을 사용해 각도를 엇갈리게 하면서 그린다.i를 5로 나누면 시간 문자도 그려집니다.
Main.cpp
/* 省略 */
void Main()
{
    /* 省略 */
    while (System::Update())
    {
        // 中心の座標
        const auto center = Scene::Center();

        // 縁に秒単位の線を描画
        for (auto i : step(60))
        {
            // 角度
            const double theta = i * 6_deg;
            // 時刻を描画するか
            const bool isHour = i % 5 == 0;
            // 描画する座標
            const Vec2 pos = OffsetCircular(center, size, theta);

            if (isHour)
            {
                // i == 0の場合は12を描画
                const String hourString = i == 0 ? U"12" : ToString(i / 5);
                hourFont(hourString).drawAt(pos.lerp(center, 0.2), Palette::White);
            }

            // 線を描画
            Line(pos, pos.lerp(center, isHour ? 0.1 : 0.05)).draw(thick / 2, Palette::White);
        }

        // 縁の描画
        Circle(center, size).drawFrame(thick / 2, Palette::White);
    }
 }

바느질 그리기

DateTime::Now()에서 현재 시간을 가져오고 시간에 따라 바늘을 그립니다.
Main.cpp
/* 省略 */
void Main()
{
   /* 省略 */
   while (System::Update())
   {
       /* 省略 */
           // 現在時刻を取得
       const DateTime now = DateTime::Now();

       // 秒針を描画
       Line(center, OffsetCircular(center, size * 0.9, now.second * 6_deg)).draw(thick / 3, Palette::White);
       // 分針を描画
       Line(center, OffsetCircular(center, size * 0.85, now.minute * 6_deg)).draw(thick / 2 , Palette::White);
       // 時針を描画
       Line(center, OffsetCircular(center, size * 0.5, now.hour * 30_deg)).draw(thick, Palette::White);

       // 針の中心に円を描画
       Circle(center, size * 0.03).draw(Palette::White);
   }
}

수정 시계 바늘


방금 포인터를 그리는 프로그램에서 시계 바늘은 1시간 간격으로 한 번만 이동하기 때문에 분을 사용하면 시계 바늘을 그리면 진정한 시계에 접근할 수 있다.
Main.cpp
 /* 省略 */
void Main()
{
   /* 省略 */
   while (System::Update())
   {
       /* 省略 */
   // 時針を描画
       Line(center, OffsetCircular(center, size * 0.5, (now.hour % 12 + now.minute / 60.0) * 30_deg)).draw(thick, Palette::White);
   /* 省略 */
   }
}

끝맺다


마지막으로 색과 선의 균형을 맞추면 완성됩니다.

코드 전체 텍스트


Main.cpp

# include <Siv3D.hpp>

void Main()
{
   // 縁の半径
   const int size = 200;
   // 針の太さのベース(時針の太さ)
   const int thick = 6;
   // 時刻用のフォント
   const Font hourFont(24);

   // 背景を黒に
   Scene::SetBackground(Palette::Black);

   while (System::Update())
   {
       // 中心の座標
       const auto center = Scene::Center();

       // 縁に秒単位の線を描画
       for (auto i : step(60))
       {
           // 角度
           const double theta = i * 6_deg;
           // 時刻を描画するか
           const bool isHour = i % 5 == 0;
           // 描画する座標
           const Vec2 pos = OffsetCircular(center, size, theta);

           if (isHour)
           {
               // i == 0の場合は12を描画
               const String hourString = i == 0 ? U"12" : ToString(i / 5);
               hourFont(hourString).drawAt(pos.lerp(center, 0.2), Palette::White);
           }

           // 線を描画
           Line(pos, pos.lerp(center, isHour ? 0.1 : 0.03)).draw(thick / 2, isHour ? Palette::White : Palette::Lightgrey);
       }

       // 縁の描画
       Circle(center, size).drawFrame(thick / 2, Palette::White);

       // 現在時刻を取得
       const DateTime now = DateTime::Now();

       // 秒針を描画
       Line(center, OffsetCircular(center, size * 0.9, now.second * 6_deg)).draw(thick / 3, Palette::Yellow);
       // 分針を描画
       Line(center, OffsetCircular(center, size * 0.85, now.minute * 6_deg)).draw(thick / 2 , Palette::White);
       // 時針を描画
       Line(center, OffsetCircular(center, size * 0.6, (now.hour % 12 + now.minute / 60.0) * 30_deg)).draw(thick, Palette::White);

       // 針の中心に円を描画
       Circle(center, size * 0.03).draw(Palette::White);
   }
}

좋은 웹페이지 즐겨찾기