[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;

}

微信截图_20240711085111

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;
}
}

微信截图_20240711103025

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;

}

微信截图_20240711105542