文章目录
- 基于EasyX库的C语言小游戏
- 一、EASYX库
- 二、见缝插针小游戏
- 游戏实录
- 规则介绍
- 需求与技术难点分析
- 针的存储
- 圆盘的旋转
- 旋转的实现
- 游戏的失败条件
- 源码
一、EASYX库
EasyX Graphics Library 是针对 Visual C++ 的免费绘图库,支持 VC6.0 ~ VC2022,简单易用,学习成本极低,应用领域广泛。目前已有许多大学将 EasyX 应用在教学当中。
这个库最大的优点就是它的下载 -> 安装 -> 使用特别简单,全过程不超过一分钟,具体安装步骤请参考 安装EasyX库
另外一点就是这个库的使用文档也非常的详细。EasyX库在线文档
我们还可以下载它的离线文档,支持索引每一个函数的具体用法,
二、见缝插针小游戏 游戏实录 规则介绍对于这个游戏,想必大家都已经玩过了。
具体规则是:
需求与技术难点分析 针的存储按下空格键后发射一根针到圆盘上,所有针逆时针方向转动;如果新发射的针碰到已有的针,游戏结束。
用一维数组解决,为了避免游戏初期时,在绘制针的时候重复遍历大数组,我们采用lineNum这个变量作为计数变量,提升效率。
圆盘的旋转由于我们设置针盘为圆形的,所以圆盘的旋转可以转化为针的旋转。
旋转的实现对于一根针(线段)来讲,旋转本质上是角度的变化,我们自然会想到用三角函数来解决旋转问题:
EasyX库给我们提供line()函数来画线,以下为对应的参数
因此我们想当然的对应起单位圆的知识
x=rcosɑ
y=rsinɑ
那么我们不免想到角度从何而来?
我们可以借用针的数组,定义为Angles[1000],每个元素存储它的角度,用lineNum存储数组中有几个针,这有点类似线性表的知识,学过的同学应该知道。
xEnd = lineLength * cos(-Angles[i]) + width / 2; // 计算针的末端坐标 yEnd = lineLength * sin(-Angles[i]) + height / 2;
由此可知,旋转就只需将角度每次更新就行了
Angles[i] = Angles[i] + rotateSpeed; // 角度增加 if (Angles[i] > 2 * Pi) // 如果超过2*Pi,就减去2*Pi,防止角度数据无限增加 Angles[i] = Angles[i] - 2 * Pi; //
游戏的失败条件需要注意的是角度不能持续的增加,当超过2*Pi时,我们需要将其恢复,防止针“逃出”圆盘。
当新针与旧针的角度差小于某个数值时,判定两针相碰,游戏失败。
for (i = 0; i < lineNum - 1; i++) // 拿新增加的针和之前所有针比较
{
// 如果两根针之间角度接近,认为碰撞,游戏失败
if (abs(Angles[lineNum - 1] - Angles[i]) < Pi / 60)
{
rotateSpeed = 0; // 旋转速度设为0
break; // 不用再比较了,循环跳出
}
}
源码
#include#include #include #include int main() { const float Pi = 3.1415926; // Pi常量 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]; // 浮点数数组,存储所有针的旋转角度,最多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] = Angles[i] + rotateSpeed; // 角度增加 if (Angles[i] > 2 * Pi) // 如果超过2*Pi,就减去2*Pi,防止角度数据无限增加 Angles[i] = 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) // 如果按键,并且旋转速度不等于0 { char input = _getch(); // 获得用户按键输入 if (input == ' ') // 如果为空格键 { lineNum++; // 针的个数加1 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 (abs(Angles[lineNum - 1] - Angles[i]) < Pi / 60) { rotateSpeed = 0; // 旋转速度设为0 break; // 不用再比较了,循环跳出 } } score = score + 1; // 得分+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]; // 定义字符串数组 _stprintf(s, _T("%d"), score); // 将score转换为字符串 settextstyle(50, 0, _T("Times")); // 设置文字大小、字体 settextcolor(RGB(50, 50, 50)); // 设置字体颜色 outtextxy(65, 200, s); // 输出得分文字 FlushBatchDraw(); // 批量绘制 Sleep(10); // 暂停10毫秒 } closegraph(); // 关闭画面 return 0; }
如果在VS2019环境中,要改3处才能正常编译运行
kbhit改为_kbhit
abs改为fabs
_stprintf改为swprintf_s



