C/C++跳动的爱心

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++闪烁的爱心
15C/C++哆啦A梦
16C/C++简单圣诞树
17C/C++小宇宙
18C/C++冰墩墩
19C/C++七彩花朵
20C/C++玫瑰花
21C/C++小猪佩奇
22C/C++简易爱心

写在前面

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

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

技术需求

  • 图形库(Graphics Library):利用 graphics.h 提供的图形功能绘制点、圆形、文字等元素。通过 setfillcolorsolidcircleouttextxy 等函数精确控制图形的颜色、形状和位置。
  • 数学运算与公式:代码采用数学公式生成心形曲线的点坐标,特别是结合 sincos 函数及参数方程绘制心形曲线。同时使用 sqrt(pow(x, 2) + pow(y, 2)) 计算点间距离,有效处理点的关系。
  • 随机数生成:使用 rand() 函数生成随机数,随机化图形的颜色、大小和位置,增强动画效果的动感和变化性。随机数还用于决定每个点是否生成,增加视觉趣味性。
  • 动画生成:通过逐帧生成图像并利用 saveimageloadimage 函数保存加载每一帧,实现流畅的动画效果。每帧点的位置随时间变化,形成动态视觉效果。
  • 图像处理:通过 setoriginsetaspectratio 调整图形坐标系,确保图形适应不同屏幕分辨率和显示效果,提升视觉体验。
  • 文本绘制:使用 outtextxy 将文本如“我爱你”绘制到图形上,增强表现力和情感表达。
  • 内存与性能管理:通过 images[frame] 数组存储每一帧图像数据,确保独立处理和保存每一帧,优化内存使用和性能表现。

环境搭建

环境:C/C++

软件:Visual Studio 2022

  1. EasyX简介

EasyX 是专为 C++ 初学者和爱好者设计的图形库,以简洁易用、功能实用为目标,封装了 Windows GDI 接口,显著降低了 C++ 图形界面设计的复杂度,便于快速实现各类图形图像处理任务。

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

总之,EasyX 以其友好的学习曲线和高效的图形处理能力,激发 C++ 初学者对计算机图形学的兴趣,广泛应用于编程入门和教育领域。

  1. EasyX 下载安装
  • 访问 EasyX 官网,点击下载按钮开始下载。
  • 下载完成后进入目录,双击 .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:提供绘制图形和图像的功能。
  • conio.h:包含 _kbhit() 等控制台输入输出功能。
  • ctime:用于获取系统时间以生成随机数。
  • cmath:提供数学运算函数,如 powsqrt
  • cstdlib:用于生成随机数等操作。

2. 数据结构

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

定义了 Point 结构体,存储二维坐标点的 xy 值及颜色属性。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;
}

生成指定范围内的随机整数。

6. create_data() 函数

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

6.1 生成原始数据点

for (double radian = 0.1; radian <= 2 * PI; radian += 0.005) {
    double x2 = 16 * pow(sin(radian), 3);
    double 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;
    }
}

使用参数方程生成心形曲线的原始数据点,通过遍历角度 radian 计算坐标,并过滤过于接近的点。

6.2 生成圆形点数据

通过变化 sizelightness,生成不同大小和亮度的点,决定点是否生成,并随机设置颜色加入 points 数组。

6.3 生成动画帧

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

7. 总结

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

写在后面

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

Read more

C++高性能游戏渲染优化实践(减少CPU-GPU等待时间的4种方法)

第一章:C++高性能游戏渲染优化概述 在现代游戏开发中,C++ 依然是构建高性能图形引擎的核心语言。其对底层硬件的直接控制能力、零成本抽象机制以及高效的运行时性能,使其成为实现复杂渲染管线和实时视觉效果的首选工具。随着玩家对画质与帧率要求的不断提升,如何在有限的硬件资源下最大化渲染效率,已成为游戏引擎开发的关键挑战。 渲染性能的核心瓶颈 游戏渲染性能通常受限于多个环节,包括 CPU 到 GPU 的数据传输、绘制调用(Draw Call)频率、着色器复杂度以及内存带宽使用。频繁的状态切换和小批量绘制会显著降低 GPU 利用率。为缓解这些问题,开发者常采用批处理、实例化渲染和减少材质切换等策略。 关键优化技术手段 * 使用对象池管理动态资源,避免运行时频繁内存分配 * 通过多线程渲染将场景准备与命令列表生成并行化 * 采用基于 ECS(实体-组件-系统)架构提升数据局部性 * 利用 GPU 查询(GPU Queries)分析瓶颈并指导优化方向 典型优化前后性能对比 指标优化前优化后平均帧时间36 ms18 msDraw Calls120090GPU 利用率54%

【数据结构与算法】汉诺塔问题(C++)

【数据结构与算法】汉诺塔问题(C++)

目录 一、汉诺塔问题基础定义 1. 问题描述 2. 核心规律 3. 问题分解思想(递归核心) 二、递归实现汉诺塔(简洁优雅,易理解) 1. 递归思路 2. 完整递归代码(带步骤打印 ) 三、非递归实现汉诺塔 非递归思路: 1. 非递归思路 2.代码实现: 四、写在最后 汉诺塔(Hanoi Tower)是经典的递归算法入门问题,源于古印度的数学传说,其核心是通过有限次移动,将一根柱子上的所有圆盘按 “小圆盘在上、大圆盘在下” 的规则移到另一根柱子,且移动过程中始终遵守 “一次仅移一个圆盘、大圆盘不能压小圆盘” 的规则。本文将从问题原理出发,详细讲解汉诺塔的递归实现(核心思路,简洁优雅)和非递归实现(基于栈模拟,深入理解递归本质),并提供完整可运行的

Visual C++运行库完整安装指南:解决“缺少DLL文件“问题

Visual C++运行库完整安装指南:解决"缺少DLL文件"问题 【免费下载链接】vcredistAIO Repack for latest Microsoft Visual C++ Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 当您打开游戏或专业软件时,是否遇到过"缺少MSVCP140.dll"、"VCRUNTIME140_1.dll丢失"等错误提示?这些问题通常是由于Visual C++ Redistributable运行库缺失或损坏导致的。本指南将为您提供从自动安装到手动修复的全套解决方案。 问题分析:为什么会出现DLL缺失错误 Visual C++运行库是Windows系统运行C++程序的基础组件,不同年份的软件需要对应版本的运行库支持。常见问题场景包括:

【c++】STL容器——使用红黑树模拟实现map和set(由浅入深逐步完善3w字详解)

【c++】STL容器——使用红黑树模拟实现map和set(由浅入深逐步完善3w字详解)

小编个人主页详情<—请点击 小编个人gitee代码仓库<—请点击 c++系列专栏<—请点击 倘若命中无此运,孤身亦可登昆仑,送给屏幕面前的读者朋友们和小编自己! 目录 * 前言 * 一、了解STL库中的map/set的底层 * 二、红黑树的迭代器 * 三、红黑树的插入 * 四、map/set的封装 * set的封装 * map的封装 * 五、测试 * 测试一 * 测试二 * 六、学习STL库中的实现 * set如何保证key不被修改 * map如何保证key不被修改 * 八、set的改进 * 红黑树的const迭代器 * 改进set * 测试一 * 测试二 * 九、map的改进 * 测试一 * 测试二 * operator[] * Insert * 继续完善operaotr[] * 测试一 * 十、

阿里云全品类 8 折券限时领,建站 / AI / 存储通用 立即领取