此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11577]
作业要求
- 课程网址 [https://www.icourse163.org/course/HHU-1206797807]
- 项目名称及分值
游戏名称 | 满分分值 | 功能点提示 |
---|---|---|
实时时钟 | 20 | 当前时刻、绘制指针 |
- 作业提交要求
除代码及git以外,要求 WBS、PSP,要求使用博客报告完成的功能和截图,讲解
关键技术和代码片断。其中WBS要求包括不限于每个子任务的工时估算时间和实
际耗时,精确到分钟。子任务可以包括分析、设计、代码、测试、调试、文档,
鼓励精确到二级子任务如功能点等。
项目git地址
https://github.com/ZigHello/learngit/tree/master/%E5%AE%9E%E6%97%B6%E6%97%B6%E9%92%9F
项目PSP
类型 | 任务 | 开始时间 | 结束时间 | 中断时间(分钟) | delta时间(分钟) |
---|---|---|---|---|---|
准备 | 课程学习 | 11.29 14:42 | 11.29 15:07 | 0 | 25 |
编程 | 功能实现 | 11.29 15:07 | 11.29 20:16 | 121 | 188 |
编程 | 调试 | 11.29 19:27 | 11.29 20:16 | 0 | 43 |
文档 | 技术文档说明 | 11.30 9:50 | 11.30 13:36 | 147 | 79 |
项目WBS
关键技术
-
引入第三方图形库,用于绘制各类图形
Easy-x的下载地址:http://www.easyx.cn/downloads/
在头文件中加入include <graphics.h>
,绘制图形举例:
void main()
{
initgraph(640, 480); // 创建图形界面
circle(200, 200, 100); // 画圆,圆心(200, 200),半径 100
getch(); // 按任意键继续
closegraph(); // 关闭图形界面
} -
绘制静态秒针
int center_x, center_y; //中心坐标,秒针的起始坐标
center_x = Width/2;
center_y = High/2;
int secondLength; //秒钟的长度
secondLength = Width / 5;
int secondEnd_x, secondEnd_y; //秒钟的终点坐标
secondEnd_x = center_x + secondLength;
secondEnd_y = center_y;
- 秒针根据时间转动
使用GetLocalTime(&ti)
获取系统时间,获取秒针一秒钟转动的角度secondAngle = (double)ti.wSecond * 2 * PI / 60
,记录秒针终点坐标
secondEnd_x = (int)center_x + secondLength * sin(secondAngle);
secondEnd_y = (int)center_y - secondLength * cos(secondAngle);
时针、分针的绘制及转动与秒针类似,具体代码如下:
float secondAngle = 0;//秒针对应转动角度
SYSTEMTIME ti; //定义变量存储系统时间
BeginBatchDraw();
while (1)
{
GetLocalTime(&ti);
secondAngle = (double)ti.wSecond * 2 * PI / 60; //一圈的角度为2PI,一圈60秒,一秒钟走过的角度为2*PI/60
//角度决定秒针终点坐标
secondEnd_x = (int)center_x + secondLength * sin(secondAngle);
secondEnd_y = (int)center_y - secondLength * cos(secondAngle);
//画秒针
setlinestyle(PS_SOLID, 2); //画实线,宽度为2个像素
setcolor(WHITE);
line(center_x, center_y, secondEnd_x, secondEnd_y);
FlushBatchDraw();
Sleep(50);
//隐藏前面一帧的秒针
setcolor(BLACK);
line(center_x, center_y, secondEnd_x, secondEnd_y);
EndBatchDraw();
}
- 表盘绘制
表盘的绘制,主要难点在于刻度的绘制。将一个表盘分割为60等份,0,15,30,45,60表示的是表盘0,3,6,9时间;5,10,20,25,35,40,50,55表示的是表盘的整点时间。用if...else可以实现。
此外,我在绘制表盘名称时,使用outtextxy(center_x-20 , center_y + Width/6, "我的时钟")遇到了问题,第三个参数为字符串,编辑器提示我当前的字符太多,查找了outtextxy()函数的定义,用char[]存储字符串,理论上是没有问题的,最后查明原因是由于字符编码不匹配引起的。用 char 表示字符时,英文占用一个字节,中文占用两个字节。使用了Unicode、 MBCS两种编码方式,导致char类型的编码出错。
解决办法:可以参考https://codeabc.cn/yangw/a/error-c2665
//绘制表盘边缘
setlinestyle(PS_SOLID, 2);
setcolor(WHITE);
circle(center_x, center_y, Width / 4);
//绘制刻度
int x, y;
for (int i = 0; i < 60; i++)
{
x = center_x + int(Width / 4.5 * sin(i * 2 * PI / 60));
y = center_y + int(Width / 4.5 * cos(i * 2 * PI / 60));
if (i % 15 == 0) //0,15,30,45,60
{
bar(x - 5, y + 5, x + 5, y - 5);
}
else if (i % 5 == 0) //5,10,20,25,35,40,50,55
{
circle(x, y, 3);
}
else {
putpixel(x, y, WHITE);
}
}
5.完成效果图