C/C++跳动的爱心

系列文章

序号直达链接
1C/C++李峋同款跳动的爱心
2C/C++跳动的爱心
3C/C++经典爱心
4C/C++满屏飘字
5C/C++大雪纷飞
6C/C++黑客帝国字母雨
7C/C++樱花树
8C/C++奥特曼
9C/C++精美圣诞树
10C/C++俄罗斯方块小游戏
11C/C++贪吃蛇小游戏
12C/C++孤单又灿烂的神
13C/C++闪烁的爱心
14C/C++哆啦A梦
15C/C++简单圣诞树
16C/C++小宇宙
17C/C++冰墩墩
18C/C++七彩花朵
19C/C++玫瑰花
20C/C++小猪佩奇
21C/C++简易爱心
22C/C++流星雨①
23C/C++2048小游戏
24C/C++爱心圣诞树
25C/C++文字跑马灯
26C/C++教师工作量管理系统
27C/C++满天繁星
28C/C++漂浮爱心
29C/C++五子棋小游戏
30C/C++球球大作战小游戏
31C/C++走迷宫小游戏
32C/C++粉色爱心
33C/C++棕色小熊
34C/C++粉色动态爱心
35C/C++炫酷烟花①
36C/C++炫酷烟花②
37C/C++炫酷烟花③
38C/C++炫酷烟花④
39C/C++星空漩涡
40C/C++流星雨②
敬请期待……

写在前面

C/C++语言实现李峋同款跳动的爱心完整代码。

首先,我们需要知道C++作为一种高级编程语言,拥有强大的功能和灵活的语法,非常适合用来制作各种有趣的动画效果。而跳动的爱心,正是一种既简单又富有创意的动画效果,非常适合用来作为编程初学者的练习项目。要实现这个效果,我们需要用到C++的图形库和定时器功能。图形库可以帮助我们在控制台或窗口中绘制出爱心的形状,而定时器则可以让爱心以一定的频率跳动起来。

技术需求

  1. 图形库(Graphics Library):使用 graphics.h 提供的图形功能来绘制点、圆形、文字等图形元素。通过 setfillcolorsolidcircleouttextxy 等函数来控制图形的颜色、形状和位置。

  2. 数学运算与公式:代码使用了数学公式生成心形曲线的点坐标。特别是通过 sincos 函数,结合参数方程绘制心形曲线。同时使用了距离计算公式 sqrt(pow(x, 2) + pow(y, 2)) 来处理点之间的关系。

  3. 随机数生成:通过 rand() 函数生成随机数,用于随机化图形的颜色、大小、位置等,使得动画效果更具动感和变化性。随机数还被用来控制每个点是否生成。

  4. 动画生成:通过逐帧生成图像,利用 saveimageloadimage 函数保存并加载每一帧图像,实现动画效果。每帧的点位置随着时间变化,形成动态效果。

  5. 图像处理:利用 setoriginsetaspectratio 等函数调整图形坐标系,使得图形能适应不同的屏幕分辨率和显示效果。

  6. 文本绘制:使用 outtextxy 函数将文本绘制到图形上,这里用来显示"我爱你"等信息,增强图形的表现力。

  7. 内存与性能管理:通过存储每一帧的图像,使用 images[frame] 数组来管理图像数据,确保每一帧能够被独立处理和保存。

环境搭建

环境:C/C++

软件:Visual Studio 2022

安装教程:C语言环境搭建教程(Visual Studio)

1. EasyX是什么

EasyX是一个专为C++初学者和爱好者设计的图形库。该库以简洁易用、功能实用为宗旨,通过封装Windows GDI接口,极大降低了C++编程中图形界面设计的复杂度,使得用户能够快速上手并实现各类图形图像处理任务。

EasyX提供了一系列丰富的API函数,涵盖了绘制基本图形(如线段、圆形、矩形等)、填充图形、显示文本、加载与保存图片、颜色设置以及鼠标键盘事件处理等功能。通过简单的函数调用,开发者可以高效地进行2D图形绘制和交互式程序设计。

总的来说,EasyX以其友好的学习曲线和高效的图形处理能力,极大地激发了C++初学者对计算机图形学的兴趣,是广大编程入门者和教育领域广泛采用的一款图形库工具。

2. 下载安装EasyX

1.进入EasyX官网,点击下载按钮开始下载

2.下载完成后进入下载目录,双击.exe文件无脑安装即可

接下来,让我们一步步来实现这个跳动的爱心。首先,我们需要通过一系列的数学公式来定义爱心的形状,比如使用参数方程来描述爱心的轮廓。然后,我们可以使用C++的图形库来绘制出这个形状。当绘制好爱心后,就要想办法让它跳动起来了,这里我们可以使用C++的定时器功能,设置一个合适的时间间隔,让爱心在每个时间间隔内改变位置或大小,从而产生跳动的效果。

完整代码

#include <graphics.h>
#include <conio.h>
#include <ctime>
#include <cmath>
#include <cstdlib>

struct Point {
    double x, y;
    COLORREF color;
};

const int MAX_POINTS = 256;
const COLORREF colors[MAX_POINTS] = {
    RGB(255, 192, 203), // 浅粉色 (Light Pink)
    RGB(255, 182, 193), // 淡粉红 (LightPink)
    RGB(255, 105, 180), // 热粉红 (HotPink)
    RGB(255, 20, 147),  // 深粉色 (DeepPink)
    RGB(219, 112, 147), // 浓粉红 (PaleVioletRed)
    RGB(255, 174, 185), // 浅玫瑰红 (LightPink)
    RGB(255, 0, 144)    // 紫红色 (Crimson)
};
const int xScreen = GetSystemMetrics(SM_CXSCREEN);
const int yScreen = GetSystemMetrics(SM_CYSCREEN) - 100;
const double PI = 3.14159265359;
const double E = 2.71828;
const double AVG_DISTANCE = 0.162;
const int NUM_ORIGIN_POINTS = 506;
const int NUM_CIRCLES = 210;
const int NUM_FRAMES = 20;
const int COLOR_RANGE = 6;

Point origin_points[NUM_ORIGIN_POINTS];
Point points[NUM_CIRCLES * NUM_ORIGIN_POINTS];
IMAGE images[NUM_FRAMES];

int create_random(int min, int max) {
    return rand() % (max - min + 1) + min;
}

void create_data() {
    int index = 0;
    double x1 = 0, y1 = 0, x2 = 0, y2 = 0;

    // Generate origin points
    for (double radian = 0.1; radian <= 2 * PI; radian += 0.005) {
        x2 = 16 * pow(sin(radian), 3);
        y2 = 13 * cos(radian) - 5 * cos(2 * radian) - 2 * cos(3 * radian) - cos(4 * radian);
        double distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
        if (distance > AVG_DISTANCE) {
            x1 = x2, y1 = y2;
            origin_points[index].x = x2;
            origin_points[index++].y = y2;
        }
    }

    // Generate points
    index = 0;
    for (double size = 0.1, lightness = 1.5; size <= 20; size += 0.1) {
        double success_p = 1 / (1 + pow(E, 8 - size / 2));
        if (lightness > 1) lightness -= 0.0025;
        for (int i = 0; i < NUM_ORIGIN_POINTS; ++i) {
            if (success_p > create_random(0, 100) / 100.0) {
                COLORREF color = colors[create_random(0, COLOR_RANGE)];
                points[index].color = RGB(GetRValue(color) / lightness, GetGValue(color) / lightness, GetBValue(color) / lightness);
                points[index].x = size * origin_points[i].x + create_random(-4, 4);
                points[index++].y = size * origin_points[i].y + create_random(-4, 4);
            }
        }
    }
    int points_size = index;

    // Generate images
    for (int frame = 0; frame < NUM_FRAMES; ++frame) {
        images[frame] = IMAGE(xScreen, yScreen);
        SetWorkingImage(&images[frame]);
        setorigin(xScreen / 2, yScreen / 2);
        setaspectratio(1, -1);

        for (index = 0; index < points_size; ++index) {
            double x = points[index].x, y = points[index].y;
            double distance = sqrt(pow(x, 2) + pow(y, 2));
            double distance_increase = -0.0009 * distance * distance + 0.35714 * distance + 5;
            double x_increase = distance_increase * x / distance / NUM_FRAMES;
            double y_increase = distance_increase * y / distance / NUM_FRAMES;
            points[index].x += x_increase;
            points[index].y += y_increase;
            setfillcolor(points[index].color);
            solidcircle(points[index].x, points[index].y, 1);
        }

……

代码分析

这段代码使用了 C++ 中的图形库来生成一系列动画图像,并展示一个基于爱心形状的图案。下面将详细分析该代码的各个部分,包括结构体定义、常量声明、函数实现和程序的执行流程。

1. 引用的头文件

#include <graphics.h>
#include <conio.h>
#include <ctime>
#include <cmath>
#include <cstdlib>
  • graphics.h:是 C++ 中的图形处理库,提供了用于绘制图形和图像的函数。
  • conio.h:用于控制台输入输出,包括 _kbhit()(检测是否有按键输入)等功能。
  • ctime:用于获取系统时间,主要用于生成随机数。
  • cmath:提供数学运算函数,如 powsqrt 等。
  • cstdlib:用于生成随机数等操作。

2. 数据结构

struct Point {
    double x, y;
    COLORREF color;
};

定义了一个 Point 结构体,用来存储二维坐标点的 xy 值,以及一个 color 属性,代表该点的颜色。COLORREF 是一个颜色的结构,通常包含 RGB 颜色值。

3. 常量声明

const int MAX_POINTS = 256;
const COLORREF colors[MAX_POINTS] = {
    RGB(255, 192, 203), RGB(255, 182, 193), RGB(255, 105, 180),
    RGB(255, 20, 147), RGB(219, 112, 147), RGB(255, 174, 185), RGB(255, 0, 144)
};
const int xScreen = GetSystemMetrics(SM_CXSCREEN);
const int yScreen = GetSystemMetrics(SM_CYSCREEN) - 100;
const double PI = 3.14159265359;
const double E = 2.71828;
const double AVG_DISTANCE = 0.162;
const int NUM_ORIGIN_POINTS = 506;
const int NUM_CIRCLES = 210;
const int NUM_FRAMES = 20;
const int COLOR_RANGE = 6;
  • MAX_POINTS:最大点数,表示图像中最多可以包含 256 个点。
  • colors:存储了 7 种颜色的 RGB 值,表示动画中使用的颜色范围。
  • xScreen, yScreen:获取屏幕的宽度和高度,并为绘制图像留出一些空间。
  • PIE:圆周率和自然常数。
  • AVG_DISTANCE:用于计算点之间的平均距离。
  • NUM_ORIGIN_POINTS:原始数据点的数量。
  • NUM_CIRCLES:生成的圆形点的数量。
  • NUM_FRAMES:动画帧的数量。
  • COLOR_RANGE:颜色范围,用于选择颜色的随机数范围。

4. 全局变量

Point origin_points[NUM_ORIGIN_POINTS];
Point points[NUM_CIRCLES * NUM_ORIGIN_POINTS];
IMAGE images[NUM_FRAMES];
  • origin_points:存储原始的点数据,用于计算图案。
  • points:存储图形中每个点的数据,包括坐标和颜色。
  • images:存储每一帧生成的图像。

5. 创建随机数的辅助函数

int create_random(int min, int max) {
    return rand() % (max - min + 1) + min;
}

这个函数用来生成一个指定范围内的随机整数。通过 rand() 函数生成一个随机数,然后通过模运算限制其在给定的区间内。

6. create_data() 函数

该函数是整个程序的核心,负责生成原始点数据、计算点的位置,并生成动画的帧。

6.1 生成原始数据点

for (double radian = 0.1; radian <= 2 * PI; radian += 0.005) {
    x2 = 16 * pow(sin(radian), 3);
    y2 = 13 * cos(radian) - 5 * cos(2 * radian) - 2 * cos(3 * radian) - cos(4 * radian);
    double distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
    if (distance > AVG_DISTANCE) {
        x1 = x2, y1 = y2;
        origin_points[index].x = x2;
        origin_points[index++].y = y2;
    }
}

这段代码生成了一个心形曲线的原始数据点,使用了 parametric equations 来绘制心形。通过遍历角度 radian,计算 x2y2 的坐标,并根据距离过滤掉过于接近的点。

6.2 生成圆形点数据

这一部分通过变化 sizelightness,生成了不同大小、不同亮度的点。通过 success_p 来决定点是否应当被生成,最终生成的点被随机设置颜色,并加入到 points 数组中。

6.3 生成动画帧

这一段代码是核心部分,负责绘制和动画生成。

通过计算每个点的位置,绘制心形的各个点,并生成动态的效果。

7. 总结

这段代码实现了一个基于心形图案的动态生成动画,涉及到数学公式、图形绘制、随机数生成等多个方面的知识。它通过逐帧绘制来创建动画效果,并通过修改颜色、位置、大小等参数来实现动态展示。

写在后面

我是一只有趣的兔子,感谢你的喜欢!

<think>好的,用户现在想要了解如何用C/C++实现李峋同款的跳动爱心。之前用户已经询问过Qt串口通信,现在转向图形相关的爱心效果,可能用户对编程有较广泛的兴趣,或者在做某个项目需要结合硬件和图形界面。 首先,用户提到的“李峋同款跳动爱心”应该是指影视剧中的动态爱心效果,可能是一个在控制台或图形窗口中跳动爱心动画。需要确认用户的需求是控制台实现还是图形界面,比如使用OpenGL或者Qt的图形库。不过考虑到用户之前接触过Qt,可能更倾向于图形界面,但C/C++的控制台动画也是一种常见做法,尤其是使用ASCII字符来模拟动画。 接下来需要分析实现方法。控制台下的跳动爱心通常利用数学公式生成爱心的形状,结合颜色变化和动态缩放来模拟跳动效果。在Windows下可能需要使用Windows API来设置控制台颜色和光标位置,而Linux/macOS则可能使用ANSI转义码。 用户可能需要详细的步骤,包括爱心坐标的计算、控制台颜色的设置、动画循环的实现。同时需要代码示例,最好能跨平台或者注明不同系统的适配方法。另外,用户可能希望代码简洁,容易理解和修改。 考虑到用户可能没有图形库的经验,优先选择控制台实现,因为依赖较少,适合快速实现。但需要注意不同系统的兼容性,比如Windows和Unix-like系统在控制台处理上的差异。例如,Windows使用SetConsoleCursorPosition和SetConsoleTextAttribute,而其他系统使用ANSI转义码。 代码结构大致分为:初始化(隐藏光标、设置颜色)、计算爱心形状的坐标、动态调整爱心大小以实现跳动效果,以及循环刷新显示。可能需要用到数学公式,比如心形曲线的参数方程,或者使用预定义的字符矩阵来绘制爱心。 同时,需要处理用户的退出操作,比如检测按键事件来终止程序,或者在循环中设置退出条件。此外,动画的流畅性取决于刷新速率,可能需要使用睡眠函数来控制帧率。 最后,可能需要注意事项,比如编译时的平台相关代码处理,或者颜色不支持时的回退方案。用户可能还希望了解如何调整爱心的大小、颜色变化或跳动速度,所以代码中的参数应该易于修改。 总结来说,需要提供一个简洁的C/C++控制台程序,实现跳动爱心动画,包含跨平台处理,代码注释清晰,并解释关键步骤和数学原理,方便用户理解和自定义。</think>以下是一个用 C/C++ 实现的**控制台跳动爱心**代码(灵感来自《点燃我,温暖你》中李峋的爱心代码),结合数学公式与颜色动画效果,支持 Windows/Linux/macOS 平台: --- ### 代码实现 ```cpp #include <iostream> #include <cmath> #include <windows.h> // Windows 专用 API(Linux/macOS 可用 ANSI 转义码替代) // 设置控制台光标位置(跨平台建议使用 ncurses 库) void setCursorPos(int x, int y) { #ifdef _WIN32 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos = { (SHORT)x, (SHORT)y }; SetConsoleCursorPosition(hConsole, pos); #else std::cout << "\033[" << y + 1 << ";" << x + 1 << "H"; // ANSI 转义码 #endif } // 隐藏光标 void hideCursor() { #ifdef _WIN32 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cursorInfo; GetConsoleCursorInfo(hConsole, &cursorInfo); cursorInfo.bVisible = false; SetConsoleCursorInfo(hConsole, &cursorInfo); #else std::cout << "\033[?25l"; #endif } // 设置控制台颜色(示例仅 Windows,其他系统可用 ANSI) void setColor(int color) { #ifdef _WIN32 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, color); #else std::cout << "\033[38;5;" << color << "m"; #endif } // 爱心数学公式:笛卡尔心形线变形 bool heartShape(float x, float y, float scale) { x /= scale; y /= scale; float heart = pow(x*x + y*y - 1, 3) - x*x*y*y*y; return heart <= 0; } int main() { hideCursor(); float scale = 1.0; bool expanding = false; while (true) { // 清屏(简单模拟) system("cls"); // 动态缩放系数 scale += expanding ? 0.05 : -0.05; if (scale <= 0.5) expanding = true; if (scale >= 1.5) expanding = false; // 遍历坐标绘制爱心 for (float y = 1.5; y > -1.5; y -= 0.05) { for (float x = -1.5; x < 1.5; x += 0.025) { if (heartShape(x, y, scale)) { setColor(12); // 红色(Windows) std::cout << "*"; } else { std::cout << " "; } } std::cout << std::endl; } // 控制动画速度 Sleep(50); } return 0; } ``` --- ### 关键原理 1. **心形方程** 使用变形后的笛卡尔心形线公式: ```math (x^2 + y^2 - 1)^3 - x^2 y^3 \leq 0 ``` 当坐标点满足该不等式时,绘制爱心符号。 2. **动态缩放** 通过 `scale` 参数周期性变化(0.5~1.5),实现爱心的"跳动"效果。 3. **控制台动画** - 使用 `system("cls")` 清屏(实际项目建议用更高效方式) - 通过 `Sleep()` 控制帧率 - 隐藏光标避免闪烁 4. **颜色控制** Windows 使用 `SetConsoleTextAttribute`,其他系统可用 ANSI 转义码实现彩色输出。 --- ### 运行效果 - 控制台中会出现一个红色爱心,持续缩放跳动 - 类似影视剧中的终端动态效果(需调整参数优化动画流畅度) --- ### 跨平台适配建议 1. **Linux/macOS** - 安装 `ncurses` 库替代 Windows API - 使用 ANSI 转义码控制颜色和光标 - 将 `Sleep(50)` 改为 `usleep(50000)` 2. **增强效果** - 修改公式实现不同形状爱心 - 添加渐变颜色(如粉红到深红) - 增加随机粒子效果 如果需要完整跨平台版本或图形界面(如 OpenGL/Qt 实现),可以进一步补充说明!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Want595

感谢小伙伴的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值