C++入门——实现见缝插针游戏

分类: APPBET365 时间: 2025-10-02 05:04:33 作者: admin 阅读: 666

参考

《C和C++游戏趣味编程》 童晶

见缝插针

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

绘制圆盘与针

绘制一个圆表示圆盘、一条线段表示一根针,圆心坐标及线段起点坐标均为(width/2, height/2)

#include

#include

#include

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

#include

#include

#include

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

#include

#include

#include

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

#include

#include

#include

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

#include

#include

#include

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;

}

相关文章

哪个快递能邮寄手机

APPBET365 · 09-07 阅读 2901

QQ音乐收藏歌曲的完整指南

APPBET365 · 07-02 阅读 3139

为什么word里显示乱码

365app安卓客户端下载 · 08-11 阅读 2648