首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Turbo C 圖形模式實現模擬鬧鐘:BGI 繪圖與 DOS 時間讀取實戰

     編輯:關於C語言

經典 Turbo C 圖形編程教學案例:使用 BGI 庫繪製模擬時鐘表盤,通過 dos.h 讀取系統實時時間,實現秒針動畫與時分針更新。代碼雖屬 DOS 時代產物,但其「幾何計算 + 雙緩衝動畫 + 硬件時間讀取」的框架思想仍具參考價值。

核心代碼結構

#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include <stdio.h>

void main() {
    int gd = DETECT, gm;
    int x = 320, y = 240, r = 200;          // 屏幕中心與表盤半徑
    int i, h, m, s, thetamin, thetasec;
    struct time t;
    char n[12][3] = {"3","2","1","12","11","10","9","8","7","6","5","4"}; // 刻度標籤

    initgraph(&gd, &gm, "g:\\tc\\bgi");     // BGI 路徑需按實際調整
    circle(x, y, 210);                      // 外圓
    setcolor(4); settextstyle(4, 0, 5);     // 紅色、大字體

    // 繪製 12 個刻度數字(極座標轉直角座標)
    for (i = 0; i < 12; i++) {
        int dx = (r - 14) * cos(M_PI / 6 * i);
        int dy = (r - 14) * sin(M_PI / 6 * i);
        int offset = (i == 3) ? 20 : 10;    // "12" 兩位數需額外偏移
        outtextxy(x + dx - offset, y - dy - 26, n[i]);
    }

    gettime(&t);
    printf("Current: %2d:%02d:%02d.%02d\n", t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund);

    // ========== 主動畫循環 ==========
    while (!kbhit()) {
        // 1. 繪製中心固定圓
        setcolor(5); setfillstyle(1, 5);
        circle(x, y, 10); floodfill(x, y, 5);

        // 2. 讀取最新時間
        gettime(&t);

        // 3. 分鐘變化時,清除舊時分針並重新計算角度
        if (t.ti_min != m) {
            setcolor(0); // 背景色擦除
            // 擦除舊分针、時針(略,幾何計算同下)
        }

        // 4. 時針角度計算(12 小制,考慮分针影響)
        if (t.ti_hour > 12) t.ti_hour -= 12;
        h = (t.ti_hour < 4) ? abs(t.ti_hour - 3) : 15 - t.ti_hour;
        m = t.ti_min;
        thetamin = (t.ti_min <= 15) ? (15 - t.ti_min) * 6 : 450 - t.ti_min * 6;
        thetasec = (t.ti_sec <= 15) ? (15 - t.ti_sec) * 6 : 450 - t.ti_sec * 6;

        // 5. 繪製新時針(紅)、分针(紅)、秒針(白)
        setcolor(4);
        // 時針:長度 r-110,末端圓半徑 10
        line(x, y, x + (r-110)*cos(M_PI/6*h - (m/2)*(M_PI/180)), y - (r-110)*sin(...));
        circle(x + (r-130)*cos(...), y - (r-130)*sin(...), 10);
        // 分针:長度 r-60
        line(x, y, x + (r-60)*cos(thetamin*M_PI/180), y - (r-60)*sin(...));
        circle(x + (r-80)*cos(...), y - (r-80)*sin(...), 10);
        // 秒針:白色,長度 r-70
        setcolor(15);
        line(x, y, x + (r-70)*cos(thetasec*M_PI/180), y - (r-70)*sin(...));

        delay(1000); // 粗略 1 秒

        // 6. 擦除秒針(背景色),下一幀重繪
        setcolor(0);
        line(x, y, x + (r-70)*cos(thetasec*M_PI/180), y - (r-70)*sin(...));
    }
    closegraph();
}

關鍵技術點解析

1. 極座標幾何:角度 → 屏幕座標

屏幕座標系:X 右正,Y 下正。數學極座標:角度從 X 軸逆時針。

screen_x = center_x + R * cos(angle_rad);
screen_y = center_y - R * sin(angle_rad); // 注意負號翻轉 Y 軸

代碼中 M_PI/6 * i 即 30° 步進,thetamin/thetasec 將 0-59 映射到 0-360°。

2. 時針平滑移動:考慮分鐘影響

時針不應跳躍,需隨分鐘連續轉動:

hour_angle = (hour % 12) * 30 + minute * 0.5; // 每分鐘 0.5°

代碼以 M_PI/6*h - (m/2)*(M_PI/180) 實現此邏輯。

3. 簡易雙緩衝動畫:畫 → 延時 → 擦除

無真正雙緩衝頁面,採用「前景色畫、背景色擦」模擬:

  • 秒針每幀重繪:白色畫 → delay(1000) → 黑色擦。
  • 時分針僅在分鐘變化時重繪,減少閃爍。

缺點:delay(1000) 阻塞主循環,無法響應鍵盤;系統調度誤差導致走時不準。

4. DOS 時間結構體

struct time { unsigned char ti_hour, ti_min, ti_sec, ti_hund; };
// ti_hund: 百分之一秒(0-99)

現代化移植建議

模塊Turbo C現代替代
圖形庫BGI (graphics.h)SDL2, Raylib, OpenGL, Qt
時間獲取dos.h gettime()time.h localtime(), chrono (C++11), clock_gettime()
延時dos.h delay()SDL_Delay, std::this_thread::sleep_for, nanosleep
鍵盤檢測conio.h kbhit()SDL_PollEvent, GetAsyncKeyState, ncurses
數學常數math.h M_PI自定義 const double PI = acos(-1); 或 C23 M_PI

總結

這個鬧鐘程序展示了「圖形初始化 → 靜態繪製 → 動態循環(讀取時間 → 幾何計算 → 增量重繪 → 幀率控制)」的經典遊戲/儀表循環架構。雖然 Turbo C/BGI 已退出歷史舞台,但掌握其中的座標變換、極坐標動畫、時間驅動邏輯,能無縫遷移至任何現代圖形框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved