先了解一下easy-x庫
EasyX 是針對 C++ 的圖形庫,可以幫助 C++語言初學者快速上手圖形和游戲編程。
可以通過官網下載,文件很小,
easy-x的支持頭文件是
#include<graphics.h>
下載之后雙擊打開會有所有easy-x函數的語法和作用,中文軟件,上手很快
分割線,開始鐘表制作
這是最終的效果圖
第一步:
新建畫布
initgraph(Width,High);
Width,High在開頭定義為常量
第二步
在畫布中央繪制一個圓
定義圓心坐標為(Width/2,High/2)
int center_x=Width/2;int center_y=High/2;
繪制一個圓,顏色為藍色,半徑為Width/5+20
setcolor(BLUE);circle(center_x,center_y,Width/5+20);
第三步
繪制秒針
//定義秒針長度int secondlength=Width/5;//畫秒針setlinestyle(PS_SOLID,2);//定義線的類型,寬度為2setcolor(BLUE);//定義顏色為藍色line(center_x,center_y,secondend_x,secondend_y);
第三部
實現轉動
思路:使用三角函數知識,控制secondend_x,secondend_y的移動
- 轉動角度:每分鐘轉動
2*PI
,則每秒轉動2*PI/60
,獲得當前系統時間的秒值,乘以每秒轉動的角度,即可得出當前時間應該轉動的角度
注意:三角函數需要#include<math.h>
支持
//實現秒針轉動
SYSTEMTIME ti;//獲取系統時間
GetLocalTime(&ti);//得當當前系統時間float secondangle=0;//秒針轉動的角度secondangle=ti.wSecond*2*PI/60;//每秒轉動的角度等于當前時間*2*PI/60secondend_x=center_x+secondlength*sin(secondangle);secondend_y=center_y-secondlength*cos(secondangle);
2. 動畫的實現:思路:每次繪制完一幀圖像后,繪制一個與背景顏色一樣的秒針,隱藏前一個秒針,并使用while(1)
實現死循環
SYSTEMTIME ti;//獲取系統時間
while(1){GetLocalTime(&ti);//得當當前系統時間//實現秒針轉動secondangle=ti.wSecond*2*PI/60;secondend_x=center_x+secondlength*sin(secondangle);secondend_y=center_y-secondlength*cos(secondangle);//畫秒針setlinestyle(PS_SOLID,2);//定義線的類型,寬度為2setcolor(BLUE);//定義顏色為藍色line(center_x,center_y,secondend_x,secondend_y);//隱藏前一個秒針setcolor(BLACK);line(center_x,center_y,secondend_x,secondend_y);}
但是我們發現圖像一直在閃爍我們加上sleep
也不行,easyx提供了批量繪圖函數BeginBatchDraw();FlushBatchDraw();EndBatchDraw();
具體使用方法看百度
注意:sleep需要#include<conio.h>
支持
SYSTEMTIME ti;//獲取系統時間BeginBatchDraw();while(1){GetLocalTime(&ti);//得當當前系統時間//實現秒針轉動secondangle=ti.wSecond*2*PI/60;secondend_x=center_x+secondlength*sin(secondangle);secondend_y=center_y-secondlength*cos(secondangle);//畫秒針setlinestyle(PS_SOLID,2);//定義線的類型,寬度為2setcolor(BLUE);//定義顏色為藍色line(center_x,center_y,secondend_x,secondend_y);FlushBatchDraw();Sleep(50);//隱藏前一個秒針setcolor(BLACK);line(center_x,center_y,secondend_x,secondend_y);}EndBatchDraw();
類似的,畫出分針和時針,注意時針一個周期是12小時,所以時針的角度應該是
hourAngle=ti.wHour*2*PI/12;
注意代碼結構,先是定義,然后FlushBatchDraw();
批量繪制,最后隱藏
拿出代碼
float secondangle=0;//秒針轉動的角度float minuteangle=0;//分針轉動的角float hourAngle=0;//定義時針轉動的角SYSTEMTIME ti;//獲取系統時間BeginBatchDraw();while(1){GetLocalTime(&ti);//得當當前系統時間//實現秒針轉動secondangle=ti.wSecond*2*PI/60;secondend_x=center_x+secondlength*sin(secondangle);secondend_y=center_y-secondlength*cos(secondangle);//實現分針轉動minuteangle=ti.wMinute*2*PI/60;minuteend_x=center_x+minutelength*sin(minuteangle);minuteend_y=center_y-minutelength*cos(minuteangle);//實現時針轉動hourAngle=ti.wHour*2*PI/12;hourEnd_x=center_x+hourlength*sin(hourAngle);hourEnd_y=center_y-hourlength*cos(hourAngle);//畫秒針setlinestyle(PS_SOLID,2);//定義線的類型,寬度為2setcolor(BLUE);//定義顏色為藍色line(center_x,center_y,secondend_x,secondend_y);//畫分針setlinestyle(PS_SOLID,2);//定義線的類型,寬度為2setcolor(YELLOW);//定義顏色為黃色line(center_x,center_y,minuteend_x,minuteend_y);//畫分針setlinestyle(PS_SOLID,3);//定義線的類型,寬度為3setcolor(RED);//定義顏色為黃色line(center_x,center_y,hourEnd_x,hourEnd_y);setcolor(BLUE);FlushBatchDraw();Sleep(50);//隱藏前一個秒針setcolor(BLACK);line(center_x,center_y,secondend_x,secondend_y);//隱藏前一個分針 setcolor(BLACK);line(center_x,center_y,minuteend_x,minuteend_y);//隱藏前一個時針setcolor(BLACK);line(center_x,center_y,hourEnd_x,hourEnd_y);}EndBatchDraw();
最后,刻畫表盤
同樣是使用三角函數知識,可以類比指針畫,我使用了一種及其復雜和智障的方法畫,先畫出了12,3,6,9,然后再一個一個刻畫,寫完才想到懶得改了
easyx中文字的輸入用到outtextxy
函數以下為outtextxy
的用法和實例
outtextxy
這個函數用于在指定位置輸出字符串。void outtextxy(int x,int y,LPCTSTR str
);void outtextxy(int x,int y,TCHAR c
);參數:x
字符串輸出時頭字母的 x 軸的坐標值
y
字符串輸出時頭字母的 y 軸的坐標值。
str
待輸出的字符串的指針。
c
待輸出的字符。
返回值:(無)說明:該函數不會改變當前位置。字符串常見的編碼有兩種:MBCS 和 Unicode。VC6 新建的項目默認為 MBCS 編碼,VC2008 及高版本的 VC 默認為 Unicode 編碼。LPCTSTR 可以同時適應兩種編碼。為了適應兩種編碼,請使用 TCHAR 字符串及相關函數。
來自easyx官網
TCHAR s[] = _T("*輸入文字*");outtextxy(x_11+R/3-10, y_11+sqrt(3.0)/2*R+R/2, s);
最后貼上完整代碼和最終效果
上面的代碼是好幾年前寫的,新版本easyx已經放棄了之前的一些函數,有小伙伴反映代碼錯誤很多,我已經在新版本環境下修改了,目前環境是vs2019+easyx 2018春風版,上面代碼沒有修改,思路是一樣的下面貼上修改后的完整源碼
#include<graphics.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#define High 480
#define Width 640
#define PI 3.1415926
int main()
{//初始化畫布initgraph(Width, High);//定義鐘表中點坐標int center_x = Width / 2;int center_y = High / 2;//定義秒針長度int secondlength = Width / 5;//定義分針長度int minutelength = secondlength - 50;//定義時針長度int hourlength = minutelength - 20;//定義秒針終點坐標int secondend_x, secondend_y;secondend_x = center_x + secondlength;secondend_y = center_y;//定義分針終點坐標int minuteend_x = center_x + minutelength;int minuteend_y = center_y;//定義時針終點坐標int hourEnd_x = center_x + hourlength;int hourEnd_y = center_y;setcolor(BLUE);circle(center_x, center_y, secondlength + 20);//繪制6:00setfillcolor(GREEN);solidcircle(Width / 2 + 4, High / 2 + secondlength + 15, 4);TCHAR s_6[5];_stprintf_s(s_6, _T("%d"), 6); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(Width / 2 - 2, High / 2 + secondlength - 5, s_6);//繪制12:00solidcircle(Width / 2, High / 2 - secondlength - 17, 4);TCHAR s_12[5];_stprintf_s(s_12, _T("%d"), 12); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(Width / 2 - 6, High / 2 - secondlength - 13, s_12);//繪制3:00solidcircle(center_x + secondlength + 17, center_y, 4);TCHAR s_3[5];_stprintf_s(s_3, _T("%d"), 3); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(center_x + secondlength, center_y - 5, s_3);//繪制9:00solidcircle(center_x - secondlength - 17, center_y, 4);TCHAR s_9[5];_stprintf_s(s_9, _T("%d"), 9); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(center_x - secondlength - 8, center_y - 5, s_9);//繪制其他刻度int R = secondlength + 20;int x_11, y_11;x_11 = Width / 2 - R / 2;//11:00刻度橫坐標y_11 = High / 2 - sqrt(3.0) / 2 * R;//11:00刻度縱坐標solidcircle(x_11, y_11, 3);TCHAR s_11[5];_stprintf_s(s_11, _T("%d"), 11); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_11, y_11, s_11);int x_10, y_10;x_10 = Width / 2 - sqrt(3.0) / 2 * R;//10:00刻度橫坐標y_10 = High / 2 - R / 2;//11:00刻度縱坐標solidcircle(x_10, y_10, 3);TCHAR s_10[5];_stprintf_s(s_10, _T("%d"), 10); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_10, y_10, s_10);int x_8, y_8;x_8 = x_10;y_8 = y_10 + R;solidcircle(x_8, y_8, 3);TCHAR s_8[5];_stprintf_s(s_8, _T("%d"), 8); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_8, y_8, s_8);int x_7, y_7;x_7 = x_11;y_7 = y_11 + sqrt(3.0) * R;solidcircle(x_7, y_7, 3);TCHAR s_7[5];_stprintf_s(s_7, _T("%d"), 7); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_7, y_7, s_7);int x_5, y_5;x_5 = x_7 + R;y_5 = y_7;solidcircle(x_5, y_5, 3);TCHAR s_5[5];_stprintf_s(s_5, _T("%d"), 5); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_5, y_5, s_5);int x_4, y_4;x_4 = x_8 + sqrt(3.0) * R;y_4 = y_8;solidcircle(x_4, y_4, 3);TCHAR s_4[5];_stprintf_s(s_4, _T("%d"), 4); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_4, y_4, s_4);int x_2, y_2;x_2 = x_10 + sqrt(3.0) * R;y_2 = y_10;solidcircle(x_2, y_2, 3);TCHAR s_2[5];_stprintf_s(s_2, _T("%d"), 2); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_2, y_2, s_2);int x_1, y_1;x_1 = x_11 + R;y_1 = y_11;solidcircle(x_1, y_1, 3);TCHAR s_1[5];_stprintf_s(s_1, _T("%d"), 1); // 高版本 VC 推薦使用 _stprintf_s 函數outtextxy(x_1, y_1, s_1);float secondangle = 0;//秒針轉動的角度float minuteangle = 0;//分針轉動的角float hourAngle = 0;//定義時針轉動的角SYSTEMTIME ti;//獲取系統時間BeginBatchDraw();while (1){GetLocalTime(&ti);//得當當前系統時間//實現秒針轉動secondangle = ti.wSecond * 2 * PI / 60;secondend_x = center_x + secondlength * sin(secondangle);secondend_y = center_y - secondlength * cos(secondangle);//實現分針轉動minuteangle = ti.wMinute * 2 * PI / 60;minuteend_x = center_x + minutelength * sin(minuteangle);minuteend_y = center_y - minutelength * cos(minuteangle);//實現時針轉動hourAngle = ti.wHour * 2 * PI / 12;hourEnd_x = center_x + hourlength * sin(hourAngle);hourEnd_y = center_y - hourlength * cos(hourAngle);//畫秒針setlinestyle(PS_SOLID, 2);//定義線的類型,寬度為2setcolor(BLUE);//定義顏色為藍色line(center_x, center_y, secondend_x, secondend_y);//畫分針setlinestyle(PS_SOLID, 2);//定義線的類型,寬度為2setcolor(YELLOW);//定義顏色為黃色line(center_x, center_y, minuteend_x, minuteend_y);//畫分針setlinestyle(PS_SOLID, 3);//定義線的類型,寬度為3setcolor(RED);//定義顏色為黃色line(center_x, center_y, hourEnd_x, hourEnd_y);setcolor(BLUE);TCHAR s[] = _T("*小張鐘表*");outtextxy(x_11 + R / 3 - 10, y_11 + sqrt(3.0) / 2 * R + R / 2, s);FlushBatchDraw();Sleep(50);//隱藏前一個秒針setcolor(BLACK);line(center_x, center_y, secondend_x, secondend_y);//隱藏前一個分針 setcolor(BLACK);line(center_x, center_y, minuteend_x, minuteend_y);//隱藏前一個時針setcolor(BLACK);line(center_x, center_y, hourEnd_x, hourEnd_y);}EndBatchDraw();_getch();closegraph();system("pause");return 0;
}