童晶老师的游戏开发课程作业--实时时钟的实现

此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11577]

作业要求

  1. 课程网址 [https://www.icourse163.org/course/HHU-1206797807]
  2. 项目名称及分值
游戏名称 满分分值 功能点提示
实时时钟 20 当前时刻、绘制指针
  1. 作业提交要求
    除代码及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

关键技术

  1. 引入第三方图形库,用于绘制各类图形
    Easy-x的下载地址:http://www.easyx.cn/downloads/
    在头文件中加入include <graphics.h>,绘制图形举例:
    void main()
    {
    initgraph(640, 480); // 创建图形界面
    circle(200, 200, 100); // 画圆,圆心(200, 200),半径 100
    getch(); // 按任意键继续
    closegraph(); // 关闭图形界面
    }

  2. 绘制静态秒针

        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;

  1. 秒针根据时间转动
    使用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();
        }
  1. 表盘绘制
    表盘的绘制,主要难点在于刻度的绘制。将一个表盘分割为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.完成效果图

posted @ 2020-11-30 15:44  张宵  阅读(201)  评论(0编辑  收藏  举报