[TOC]
案例分析
首先绘制圆盘与针,利用三角函数实现针的旋转;
然后利用数组实现多根针的效果;
接着利用批量绘制函数分析绘制效果改进方法;
最后分析针的发射与增加、游戏失败判断、得分与显示效果的改进方法。
1.绘制圆盘与针
line(x1,y1,x2,y2)可以画一条直线,(x1,y1)(x2,y2)是直线两个端点的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<graphics.h> #include<conio.h> #include<stdio.h> int main() { int width = 800; int height = 600; initgraph(width, height);//新建画布 setbkcolor(RGB(255, 255, 255));//背景为白色 cleardevice();// 以背景色清空背景
setlinestyle(PS_SOLID, 3);//实线,线条宽度3 setlinecolor(RGB(0, 0, 0));//线为黑色 line(width / 2, height / 2, width / 2 + 160, height / 2);//画一根针 setlinecolor(HSVtoRGB(0, 0.9, 0.8));//设置圆盘线条为红色 circle(width / 2, height / 2, 60); _getch();//防止闪退 return 0;
}
|

2.针的旋转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<graphics.h> #include<conio.h> #include<stdio.h> #include<math.h> int main() { const float PI = 3.1415926; int width = 800; int height = 600; initgraph(width, height);//新建画布 setbkcolor(RGB(255, 255, 255));//背景为白色
float linelength = 160; float xend, yend;//针的末端坐标,起始坐标为圆心 float angle = 0;//针的旋转角度 float rotatespeed = PI / 360;//针的旋转速度 setlinestyle(PS_SOLID, 3);//实线,线条宽度3 while (1) { cleardevice();// 以背景色清空背景 angle += rotatespeed;//角度增加 if (angle > 2 * PI) angle -= 2 * PI; xend = linelength * cos(-angle) + width / 2; yend = linelength * sin(-angle) + height / 2; setlinecolor(RGB(0, 0, 0));//线为黑色 line(width / 2, height / 2,xend,yend);//画一根针 setlinecolor(HSVtoRGB(0, 0.9, 0.8));//设置圆盘线条为红色 circle(width / 2, height / 2, 60); Sleep(10); } _getch();//防止闪退 return 0;
}
|
其中核心代码为:
angle += rotatespeed;//角度增加
if (angle > 2 * PI) angle -= 2 * PI;
xend = linelength * cos(-angle) + width / 2;
yend = linelength * sin(-angle) + height / 2;
3.利用数组实现多根针的绘制
要实现多根针的绘制,需要记录每根针的角度值。
int linenum=20;//假设有20根针
float angles[20];//定义浮点数数组存储所有针的旋转角度
for(int i=0;i<linenum;i++)//利用for循环让数组中针的角度均匀分布到0-2*PI
angles[i] = i* 2 * PI/linenum;
4.批量绘制函数
当绘制的元素较多时,会出现明显的画面闪烁,这时可以使用批量绘图函数。
BeginBatchDraw()用于开始批量绘图
FlushBatchDraw()用于执行未完成的绘制任务
EndBatchDraw()用于结束批量绘制
5.针的发射与新增
初始linenum置为0;
if (_kbhit()) {
char input = _getch();
if (input == ‘ ‘) {
linenum++;//针的个数增加
angles[linenum - 1] = PI;//这根新增针的初始角度
xend = linelength * cos(-angles[linenum - 1]) + width / 2;
yend = linelength * sin(-angles[linenum] - 1) + height / 2;
line(width / 2, height / 2,xend, yend);//画出这根新增的针
}
}
6.游戏失败判断
abs();是求绝对值的函数;
当然也可以用fabs();
当新增加的针和已有针发生碰撞时,游戏失败,在此设定当两根针的旋转角度差的绝对值小于PI/60时,认为两根针足够接近,即发生了碰撞。
for (int i = 0; i < linenum - 1; i++) {//拿新增加的针和之前所有针做比较
if (fabs(angles[linenum - 1] - angles[i]) < PI / 60) {
rotatespeed = 0;//旋转速度置为0
break;
}
}

7.全部代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| #include<graphics.h> #include<conio.h> #include<stdio.h> #include<math.h> int main() { const float PI = 3.1415926; int width = 800; int height = 600; initgraph(width, height);//新建画布 setbkcolor(RGB(255, 255, 255));//背景为白色 setlinestyle(PS_SOLID, 3);//实线,线条宽度3
float linelength = 160; float xend, yend;//针的末端坐标,起始坐标为圆心 float rotatespeed = PI / 360;//针的旋转速度 int linenum = 0;//在旋转的针的个数 float angles[1000]; int score = 0;//记录得分 BeginBatchDraw(); while (1) { cleardevice();// 以背景色清空背景 setlinecolor(RGB(0, 0, 0));//线为黑色 line(0, height / 2, linelength, height / 2);//左边发射区域的一根针 for (int i = 0; i < linenum; i++) { angles[i] += rotatespeed;//角度增加 if (angles[i] > 2 * PI) //如果超过2PI,就减去2PI angles[i] -= 2 * PI; xend = linelength * cos(-angles[i]) + width / 2; yend = linelength * sin(-angles[i]) + height / 2; line(width / 2, height / 2, xend, yend);//画一根针 } if (_kbhit()) { char input = _getch(); if (input == ' ') { linenum++;//针的个数增加 angles[linenum - 1] = PI;//这根新增针的初始角度 xend = linelength * cos(-angles[linenum - 1]) + width / 2; yend = linelength * sin(-angles[linenum] - 1) + height / 2; line(width / 2, height / 2,xend, yend);//画出这根新增的针 for (int i = 0; i < linenum - 1; i++) {//拿新增加的针和之前所有针做比较 if (fabs(angles[linenum - 1] - angles[i]) < PI / 60) { rotatespeed = 0;//旋转速度置为0 break; } } }score++; } setfillcolor(HSVtoRGB(0, linenum / 60.0, 0.8));//针越多,中间圆盘颜色越鲜艳 setlinecolor(HSVtoRGB(0, 0.9, 0.8));//设置圆盘线条为红色 circle(width / 2, height / 2, 60); TCHAR s[20]; _stprintf_s(s, _T("%d"), score); settextstyle(50, 0, _T("Times"));//设置文字大小,字体 settextcolor(RGB(50, 50, 50));//设置文字颜色 outtextxy(65, 200, s);//输出得分文字 FlushBatchDraw(); Sleep(10); } return 0;
}
|
