赞
踩
“见缝插针”游戏:按下空格键后发射一根针到圆盘上,所有针逆时针方向转动;如果新发射的针碰到已有的针,游戏结束

绘制一个圆表示圆盘、一条线段表示一根针,圆心坐标及线段起点坐标均为(width/2, height/2)
#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(); closegraph(); return 0; }

针的起点坐标为画面中心(width/2, height/2),假设针的长度为lineLength,针的旋转角度为angle,则由三角函数可以求出针的末端坐标(xEnd, yEnd)。然后,让针的角度逐渐增加,就实现了针的旋转效果
#include <graphics.h> #include <conio.h> #include <stdio.h> #include <math.h> int main() { 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); } closegraph(); return 0; }
用数组记录每根针的角度值。另外,当绘制的元素较多时,会出现明显的画面闪烁,这时可以使用批量绘图函数。BeginBatchDraw()用于开始批量绘图,执行后任何绘图操作都将暂时不输出到屏幕上,直到FlushBatchDraw()或EndBatchDraw()才将之前的绘图输出
#include <graphics.h> #include <conio.h> #include <stdio.h> #include <math.h> int main() { 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 = 20; float Angles[20]; int i; for (i = 0; i < lineNum; i++) { Angles[i] = i * 2 * PI / lineNum; } BeginBatchDraw(); while (1) { cleardevice(); setlinecolor(RGB(0, 0, 0)); for (i = 0; i < lineNum; i++) { Angles[i] += rotateSpeed; if (Angles[i] > 2 * PI) // 防止角度数据无限增加 { 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); // 绘制一根针 } setlinecolor(HSVtoRGB(0, 0.9, 0.8)); // 设置圆盘线条颜色为红色 circle(width / 2, height / 2, 60); FlushBatchDraw(); Sleep(10); } closegraph(); return 0; }
首先在画面左边绘制一根针,表示待发射的位置;当用户按下空格键,针的个数加1,并且新增加的针初始角度为PI。用户不断按下空格键,即可持续生成新的针
#include <graphics.h> #include <conio.h> #include <stdio.h> #include <math.h> int main() { 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 i; BeginBatchDraw(); while (1) { cleardevice(); setlinecolor(RGB(0, 0, 0)); line(0, height / 2, lineLength, height / 2); // 左边发射区域的一根针 for (i = 0; i < lineNum; i++) { Angles[i] += rotateSpeed; if (Angles[i] > 2 * PI) // 防止角度数据无限增加 { 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); } } setlinecolor(HSVtoRGB(0, 0.9, 0.8)); // 设置圆盘线条颜色为红色 circle(width / 2, height / 2, 60); FlushBatchDraw(); Sleep(10); } closegraph(); return 0; }
当两根针的旋转角度差的绝对值小于PI/60时,判断发生了碰撞
for (i = 0; i < lineNum - 1; i++) // 拿新的针和之前所有针比较
{
if (fabs(Angles[lineNum - 1] - Angles[i]) < PI / 60)
{
rotateSpeed = 0; // 如果碰撞,停止旋转
break;
}
}
当用户按空格键并且游戏没有失败,则得分增加1:
score += 1;
最后将score转换为字符串输出:
TCHAR s[20]; // 定义字符串数组
_stprintf(s, _T("%d"), score);
settextstyle(50, 0, _T("Times"));
settextcolor(RGB(50, 50, 50));
outtextxy(65, 200, s);
填充绘制圆盘,随着针数的增加,圆盘填充颜色越来鲜艳:
setfillcolor(HSVtoRGB(0, lineNum / 60.0, 0.8));
setlinecolor(HSVtoRGB(0, 0.9, 0.8));
fillcircle(width / 2, height / 2);
将正在旋转的针的颜色设为蓝色,最新发射的针的颜色设为红色:
setlinecolor(RGB(0, 0, 255));
if (i == lineNum - 1)
{
setlinecolor(RGB(255, 0, 0));
}
#include <graphics.h> #include <conio.h> #include <stdio.h> #include <math.h> int main() { 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; int i; BeginBatchDraw(); while (1) { cleardevice(); setlinecolor(RGB(0, 0, 0)); line(0, height / 2, lineLength, height / 2); // 左边发射区域的一根针 for (i = 0; i < lineNum; i++) { Angles[i] += rotateSpeed; if (Angles[i] > 2 * PI) // 防止角度数据无限增加 { Angles[i] -= 2 * PI; } xEnd = lineLength * cos(-Angles[i]) + width / 2; // 计算针的末端坐标 yEnd = lineLength * sin(-Angles[i]) + height / 2; setlinecolor(RGB(0, 0, 255)); // 设定旋转针的颜色为蓝色 if (i == lineNum - 1) { setlinecolor(RGB(255, 0, 0)); // 新增的针为红色 } line(width / 2, height / 2, xEnd, yEnd); // 绘制一根针 } if (_kbhit() && rotateSpeed != 0) { 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 (i = 0; i < lineNum - 1; i++) // 拿新的针和之前所有针比较 { if (fabs(Angles[lineNum - 1] - Angles[i]) < PI / 60) { rotateSpeed = 0; // 如果碰撞,停止旋转 break; } } score += 1; } } setfillcolor(HSVtoRGB(0, lineNum / 60.0, 0.8)); // 针越多,圆盘颜色越鲜艳 setlinecolor(HSVtoRGB(0, 0.9, 0.8)); // 圆盘线条颜色为红色 fillcircle(width / 2, height / 2, 60); // 绘制中间的圆盘 TCHAR s[20]; // 定义字符串数组 swprintf_s(s, _T("%d"), score); settextstyle(50, 0, _T("Times")); // 设置文字大小、字体 settextcolor(RGB(50, 50, 50)); outtextxy(65, 200, s); FlushBatchDraw(); Sleep(10); } closegraph(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。