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

趣味编程:爱心

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

目录

 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号的晚上对母亲说出那句:“爱你老妈,明天见!”哦。

 

相关文章:

  • QMK开发环境搭建指南:Eclipse和VS Code详解
  • VGGNet详解
  • 裸辞8年前端的面试笔记——JavaScript篇(一)
  • 深入理解 Docker 网络原理:构建高效、灵活的容器网络
  • 在Lua中使用轻量级userdata在C/C++之间传递数据和调用函数
  • MySQL中MVCC的实现原理
  • 【MySQL】存储引擎 - InnoDB详解
  • 区块链内容创作全攻略:海报、白皮书与视频的视觉化革命
  • commonmark.js 源码阅读(一) - Block Parser
  • 【Linux】FreeRTOS与Linux:实时与通用的终极对比
  • DApp开发:开启去中心化应用新时代
  • Solidity语言基础:区块链智能合约开发入门指南
  • Windows Server 2025 安装AMD显卡驱动
  • C++内存管理与模板初阶详解:从原理到实践
  • Webug4.0靶场通关笔记22- 第27关文件包含
  • systemd vs crontab:Linux 自动化运行系统的全面对比
  • 架空输电线巡检机器人轨迹优化设计
  • 阿里云ddos云防护服务器有哪些功能?ddos防御手段有哪些??
  • C++入门(下)--《Hello C++ World!》(2)(C/C++)
  • 金仓数据库征文-金仓KES数据同步优化实践:逻辑解码与增量同步
  • 国防部:正告菲方停止以任何方式冲撞中方核心利益
  • 央视315晚会曝光“保水虾仁”后,湛江4家涉事企业被罚超800万元
  • 建筑瞭望|融入自然的新泳池,治愈了中央公园的历史旧伤
  • 金正恩视察重要军工企业要求推进武力强化变革
  • 印巴冲突升级,巴防长称已击落5架印度战机
  • 证监会主席吴清:我们资本市场最重要的特征是“靠谱”