当前位置: 首页 > backend >正文

趣味编程:爱心

概述:五月十一号就是母亲节了,本篇博客主要是为母亲所写,这是属于程序员的浪漫,这篇博客是对母亲这么多年无微不至爱的情书。

目录

 1. 效果展示

2. 源码展示 

3. 代码逻辑详解 

3.1 头文件与常量定义

 3.2 心形曲线参数方程

3.3 颜色渐变方程

3.4 绘制动态爱心函数

3.5 绘制跳动文字函数 

3.6 主函数 

 4. 运行问题

4.1 解决Unicode字符集下编译报错

5. 完整效果  ​编辑

6.小结


 1. 效果展示

 

 这是一个动态的效果,因此实际运行会比文章展示的更有动态感,这也是这个程序的核心。

2. 源码展示 

#define _CRT_SECURE_NO_WARNINGS
#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include<stdio.h>// 使用 const 定义常量,提高类型安全性
const float PI = 3.14159265f;
const int WIDTH = 800;  // 窗口宽度
const int HEIGHT = 600; // 窗口高度// 心形曲线参数方程
float heartX(float t) {return 16 * powf(sinf(t), 3);
}float heartY(float t) {return 13 * cosf(t) - 5 * cosf(2 * t) - 2 * cosf(3 * t) - cosf(4 * t);
}// 颜色渐变函数
COLORREF getRainbowColor(float progress) {int r = (int)(sinf(progress) * 127 + 128);int g = (int)(sinf(progress + PI / 1.5) * 127 + 128);int b = (int)(sinf(progress + PI / 3) * 127 + 128);return RGB(r, g, b);
}// 绘制动态爱心
void drawHeart(int offsetX, int offsetY, float scale, COLORREF color) {setfillcolor(color);setlinecolor(color);POINT pts[100];for (int i = 0; i < 100; i++) {float t = (float)i / 100 * 2 * PI;pts[i].x = offsetX + heartX(t) * scale;pts[i].y = offsetY - heartY(t) * scale;}solidpolygon(pts, 100);
}// 绘制跳动文字
void drawText(int frame) {static const char* text = "母亲节快乐!";int textWidth = textwidth(text);int x = (WIDTH - textWidth) / 2;int y = HEIGHT - 300 + 10 * sinf(frame * 0.1);settextstyle(30, 0, "Consolas");settextcolor(HSVtoRGB(frame % 360, 1, 1));setbkmode(TRANSPARENT);outtextxy(x, y, text);
}int main() {// 初始化图形窗口if (initgraph(WIDTH, HEIGHT) == NULL) {printf("无法初始化图形窗口!\n");return 1;}setbkcolor(WHITE);cleardevice();BeginBatchDraw();int frame = 0;float hue = 0;int isGrowing = 1;float scale = 10.0f;while (!_kbhit()) {cleardevice();// 计算颜色和缩放hue += 0.02f;if (hue > 2 * PI) hue -= 2 * PI;if (scale > 15) isGrowing = 0;if (scale < 10) isGrowing = 1;scale += isGrowing ? 0.1f : -0.1f;// 绘制渐变背景for (int y = 0; y < HEIGHT; y++) {COLORREF color = HSVtoRGB(fmodf(y * 0.5f + frame, 360), 0.3f, 1);setlinecolor(color);line(0, y, WIDTH, y);}// 绘制主爱心drawHeart(WIDTH / 2, HEIGHT / 2, scale, getRainbowColor(hue));// 绘制环绕小爱心for (int i = 0; i < 6; i++) {float angle = frame * 0.02f + i * PI / 3;int x = WIDTH / 2 + (int)(cosf(angle) * 150);int y = HEIGHT / 2 + (int)(sinf(angle) * 150);drawHeart(x, y, 3, HSVtoRGB((frame * 2 + i * 60) % 360, 1, 1));}// 绘制文字drawText(frame);FlushBatchDraw();frame++;Sleep(30);}EndBatchDraw();closegraph();return 0;
}

3. 代码逻辑详解 

3.1 头文件与常量定义
#define _CRT_SECURE_NO_WARNINGS
#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include<stdio.h>// 使用 const 定义常量,提高类型安全性
const float PI = 3.14159265f;
const int WIDTH = 800;  // 窗口宽度
const int HEIGHT = 600; // 窗口高度
  • #define _CRT_SECURE_NO_WARNINGS:为了避免一些编译器对于不安全函数(如scanfstrcpy等)的警告。
  • 包含了多个头文件,其中graphics.h用于图形绘制conio.h用于控制台输入输出,算math.h用于数学运算time.h用于时间处理stdio.h用于标准输入输出
  • 定义了常量PIWIDTHHEIGHT,分别表示圆周率、窗口宽度和窗口高度。
 3.2 心形曲线参数方程
// 心形曲线参数方程
float heartX(float t) {return 16 * powf(sinf(t), 3);
}float heartY(float t) {return 13 * cosf(t) - 5 * cosf(2 * t) - 2 * cosf(3 * t) - cosf(4 * t);
}
  • heartXheartY函数根据参数t计算心形曲线上点的xy坐标,这是基于心形曲线的参数方程实现的。
3.3 颜色渐变方程
// 颜色渐变函数
COLORREF getRainbowColor(float progress) {int r = (int)(sinf(progress) * 127 + 128);int g = (int)(sinf(progress + PI / 1.5) * 127 + 128);int b = (int)(sinf(progress + PI / 3) * 127 + 128);return RGB(r, g, b);
}
  • getRainbowColor函数根据传入的progress参数,通过正弦函数计算红、绿、蓝三个颜色通道的值,从而实现颜色渐变效果。
3.4 绘制动态爱心函数
// 绘制动态爱心
void drawHeart(int offsetX, int offsetY, float scale, COLORREF color) {setfillcolor(color);setlinecolor(color);POINT pts[100];for (int i = 0; i < 100; i++) {float t = (float)i / 100 * 2 * PI;pts[i].x = offsetX + heartX(t) * scale;pts[i].y = offsetY - heartY(t) * scale;}solidpolygon(pts, 100);
}
  • drawHeart函数用于绘制动态爱心。它首先设置填充颜色和线条颜色,然后根据心形曲线参数方程计算 100 个点的坐标,最后使用solidpolygon函数绘制实心多边形。
3.5 绘制跳动文字函数 
// 绘制跳动文字
void drawText(int frame) {static const char* text = "母亲节快乐!";int textWidth = textwidth(text);int x = (WIDTH - textWidth) / 2;int y = HEIGHT - 300 + 10 * sinf(frame * 0.1);settextstyle(30, 0, "Consolas");settextcolor(HSVtoRGB(frame % 360, 1, 1));setbkmode(TRANSPARENT);outtextxy(x, y, text);
}
  • drawText函数用于绘制跳动的文字。它首先计算文字的宽度和位置,然后根据帧数frame计算文字的y坐标,实现跳动效果。接着设置文字样式、颜色和背景模式,最后使用outtextxy函数输出文字。
3.6 主函数 
int main() {// 初始化图形窗口if (initgraph(WIDTH, HEIGHT) == NULL) {printf("无法初始化图形窗口!\n");return 1;}setbkcolor(WHITE);cleardevice();BeginBatchDraw();int frame = 0;float hue = 0;int isGrowing = 1;float scale = 10.0f;while (!_kbhit()) {cleardevice();// 计算颜色和缩放hue += 0.02f;if (hue > 2 * PI) hue -= 2 * PI;if (scale > 15) isGrowing = 0;if (scale < 10) isGrowing = 1;scale += isGrowing ? 0.1f : -0.1f;// 绘制渐变背景for (int y = 0; y < HEIGHT; y++) {COLORREF color = HSVtoRGB(fmodf(y * 0.5f + frame, 360), 0.3f, 1);setlinecolor(color);line(0, y, WIDTH, y);}// 绘制主爱心drawHeart(WIDTH / 2, HEIGHT / 2, scale, getRainbowColor(hue));// 绘制环绕小爱心for (int i = 0; i < 6; i++) {float angle = frame * 0.02f + i * PI / 3;int x = WIDTH / 2 + (int)(cosf(angle) * 150);int y = HEIGHT / 2 + (int)(sinf(angle) * 150);drawHeart(x, y, 3, HSVtoRGB((frame * 2 + i * 60) % 360, 1, 1));}// 绘制文字drawText(frame);FlushBatchDraw();frame++;Sleep(30);}EndBatchDraw();closegraph();return 0;
}
  • 初始化图形窗口,如果初始化失败则输出错误信息并退出程序。
  • 设置背景颜色为白色并清空绘图设备。
  • 开启批量绘图模式
  • 定义变量framehueisGrowingscale,分别表示帧数、色调、缩放状态和缩放比例。
  • 进入主循环,直到用户按下任意键退出循环。
    • 清空绘图设备。
    • 计算色调和缩放比例,实现颜色渐变和爱心缩放效果。
    • 绘制渐变背景。
    • 绘制主爱心。
    • 绘制 6 个环绕小爱心。
    • 绘制跳动文字。
    • 刷新批量绘图。
    • 帧数加 1,程序暂停 30 毫秒。
  • 关闭批量绘图模式,关闭图形窗口。

 4. 运行问题

博主是使用 Visual Studio2022 来编写程序,运行程序的,在运行本程序前,需要先下好 EasyX图形库。以及在 Unicode字符集 下会编译报错的解决方式。

4.1 解决Unicode字符集下编译报错

 在 Unicode字符集下会出现这样的错误。

对于这样的“没有与参数列表匹配的重载函数的”错误, 我们就需要用到 多字节字符集 能解决问题,博主展示一种简单快捷的解决方式。

 之后打开最下面的“调试属性”

 最后点击“应用”即可

5. 完整效果  

6.小结

以上便是本篇博客的所有内容,如果大家学到知识的话,还请给博主点点赞,记得在5月11号的晚上对母亲说出那句:“爱你老妈,明天见!”哦。

 

http://www.xdnf.cn/news/4659.html

相关文章:

  • 昆仑万维财报解读:AI商业化卷王
  • CF每日5题
  • 《数据结构初阶》【链式二叉树】
  • 【时时三省】(C语言基础)怎样定义和引用二维数组
  • 数字孪生医疗:构建患者特异性数字孪生体路径探析
  • 【NLP 71、常见大模型的模型结构对比】
  • 缓存套餐-01.Spring Cache入门案例
  • 阿里云 golang 一面
  • 【开源】Python打造高效剪贴板历史管理器:实现跨平台生产力工具
  • 使用 Vite 创建 Vue 3 项目并手动配置路由的完整步骤
  • 如何通过服务主体获取 Azure 凭据
  • Ansible 流程控制
  • MySQL的索引和事务
  • @AutoConfigureBefore功能简介-笔记
  • ideal创建Springboot项目(Maven,yml)
  • 在Git历史中移除现有的Commit
  • Python 异常处理与文件 IO 操作:构建健壮的数据处理体系(3/10)
  • 高低比率策略
  • 天选5Pro(锐龙版)设备声音、显卡消失等问题完整解决记录
  • 表达式求值(算法题)
  • CMU-15445(3)——PROJECT#1-BufferPoolManager-Task#1
  • 【MySQL】存储引擎 - CSV详解
  • C++ stl中的string的相关用法
  • 【人工智能agent】--dify通过mcp协议调用工具
  • HR新战场:构建AI战略时代的认知分工与生态化人才供应链
  • 嵌入式C进阶路线指南
  • 创建虚拟服务时实现持久连接。
  • [人机交互]交互设计过程
  • 堆排序(算法题)
  • Easy云盘总结篇-文件分享