C+实现爱心代码

c++实现爱心代码
代码如下

#include<graphics.h>
#include <conio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
#include <string.h>


//爱心点结构体
struct Point {
	double x, y;     //坐标
	COLORREF color;  //颜色
};

//颜色数组
COLORREF colors[7] = {
	RGB(255, 200, 220),   // 柔和樱花粉
	RGB(255, 220, 240),   // 淡雅桃粉
	RGB(255, 180, 200),   // 桃花粉
	RGB(255, 150, 180),   // 樱花淡粉
	RGB(255, 120, 160),   // 水蜜桃粉
	RGB(255, 240, 250),   // 云朵粉
	RGB(255, 230, 245)    // 粉水晶
};
//COLORREF colors[7] = { RGB(55,132,83),RGB(252,222,250) ,RGB(25,120,130) ,RGB(25,230,40) ,RGB(25,24,112) ,RGB(255,230,128) ,RGB(25,5,215) };


const int xScreen = 1200;				  //屏幕宽度
const int yScreen = 800;				  //屏幕高度
const double PI = 3.1426535159;         //圆周率
const double e = 2.71828;				  //自然数e
const double averag_distance = 0.162;    //弧度以0.01增长时,原始参数方程每个点的平均距离
const int quantity = 506;				  //一个完整爱心所需点的数量
const int circles = 210;				  //组成爱心主体的爱心个数(每个爱心会乘以不同系数)
const int frames = 20;					  //爱心扩张一次的帧数
Point  origin_points[quantity];			  //创建一个保存原始爱心数据的数组
Point  points[circles * quantity];      //创建一个保存所有爱心数据的数组
IMAGE images[frames];					  //创建图片数组

//坐标转换函数
double screen_x(double x)
{
	x += xScreen / 2;
	return x;
}
//坐标转换函数
double screen_y(double y)
{
	y = -y + yScreen / 2;
	return y;
}

//创建x1-x2的随机数的函数
int creat_random(int x1, int x2)
{
	if (x2 > x1)
		return  rand() % (x2 - x1 + 1) + x1;
	else
		return 0;
}

//创建爱心扩张一次的全部数据,并绘制成20张图片保存
// 1 用参数方程计算出一个爱心的所有坐标并保存在 origin_points 中
// 2 重复对 origin_points 的所有坐标乘上不同的系数获得一个完整的爱心坐标数据,并保存在 points 中
// 3 通过一些数学逻辑计算 points 中所有点扩张后的坐标并绘制,并覆盖掉原来的数据(循环20次)
// 4 计算圆的外层那些闪动的点,不保存这些点的数据(循环20次)
void creat_data()
{

	int index = 0;

	//保存相邻的坐标信息以便用于计算距离
	double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
	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);

		//计算两点之间的距离 开根号((x1-x2)平方 + (y1-y1)平方)
		double distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));

		//只有当两点之间的距离大于平均距离才保存这个点,否则跳过这个点
		if (distance > averag_distance)
		{
			//x1和y1保留当前数据
			//x2和y2将在下一次迭代获得下一个点的坐标
			x1 = x2, y1 = y2;
			origin_points[index].x = x2;
			origin_points[index++].y = y2;
		}
	}

	index = 0;
	for (double size = 0.1; size <= 20; size += 0.1)
	{
		//用sigmoid函数计算当前系数的成功概率
		//用个例子说明一下,假设有100个点成功概率为 90%,那么就可能会有90个点经过筛选保留下来
		//					假设有100个点成功概率为 20%,那么就可能会有20个点经过筛选保留下来
		double success_p = 1 / (1 + pow(e, 8 - size / 2));

		//遍历所有原始数据
		for (int i = 0; i < quantity; ++i)
		{
			//用概率进行筛选
			if (success_p > creat_random(0, 100) / 100.0)
			{
				//从颜色数组随机获得一个颜色
				points[index].color = colors[creat_random(0, 6)];

				//对原始数据乘上系数保存在points中
				points[index].x = size * origin_points[i].x + creat_random(-4, 4);
				points[index++].y = size * origin_points[i].y + creat_random(-4, 4);
			}
		}
	}

	//index当前值就是points中保存了结构体的数量
	int points_size = index;

	for (int frame = 0; frame < frames; ++frame)
	{
		//初始化每张图片宽xScreen,高yScreen
		images[frame] = IMAGE(xScreen, yScreen);

		//把第frame张图像设为当前工作图片
		SetWorkingImage(&images[frame]);

		//计算爱心跳动的坐标
		for (index = 0; index < points_size; ++index)
		{

			double x = points[index].x, y = points[index].y;                              //把当前值赋值给x和y
			double distance = sqrt(pow(x, 2) + pow(y, 2));										//计算当前点与原点的距离
			double diatance_increase = -0.0009 * distance * distance + 0.35714 * distance + 5;	//把当前距离代入方程获得该点的增长距离

			//根据增长距离计算x轴方向的增长距离 x_increase = diatance_increase * cos(当前角度)
			//cos(当前角度)= x / distance
			double x_increase = diatance_increase * x / distance / frames;
			//根据增长距离计算x轴方向的增长距离 x_increase = diatance_increase * sin(当前角度)
			//sin(当前角度)= y / distance
			double y_increase = diatance_increase * y / distance / frames;

			//因为以上计算得到的是一整个过程的增长距离,而整个过程持续20帧,因此要除20


			//用新的数据覆盖原来的数据
			points[index].x += x_increase;
			points[index].y += y_increase;

			//提取当前点的颜色设置为绘画颜色
			setfillcolor(points[index].color);
			//注意,因为以上所有坐标是基于数学坐标的
			//因此绘制到屏幕是就要转换为屏幕坐标
			solidcircle(screen_x(points[index].x), screen_y(points[index].y), 1);
		}

		//产生外围闪动的点
		for (double size = 17; size < 23; size += 0.3)
		{
			for (index = 0; index < quantity; ++index)
			{
				//当系数大于等于20,通过概率为百分之四十,当系数小于20,通过概率为百分之五
				//20作为关键值是因为爱心主体的最大系数就是20
				if ((creat_random(0, 100) / 100.0 > 0.6 && size >= 20) || (size < 20 && creat_random(0, 100) / 100.0 > 0.95))
				{
					double x, y;
					if (size >= 20)
					{
						//用frame的平方的正负值作为上下限并加减15产生随机数
						//用frame的平方的好处是frame越大,外围闪动的点运动范围越大
						x = origin_points[index].x * size + creat_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
						y = origin_points[index].y * size + creat_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
					}
					else
					{
						//对于系数小于20的处理与爱心点一样
						x = origin_points[index].x * size + creat_random(-5, 5);
						y = origin_points[index].y * size + creat_random(-5, 5);
					}


					//随机获取颜色并设置为当前绘图颜色
					setfillcolor(colors[creat_random(0, 6)]);
					//把数学坐标转换为屏幕坐标再进行绘制
					solidcircle(screen_x(x), screen_y(y), 1);
					//需要注意的是,我并没有保存这些点,因为这些点不需要前一帧的坐标数据
					//只需要当前系数就可绘制出来,因此没 必要保存
				}
			}
		}
	}
}


int main()
{
	initgraph(xScreen, yScreen);  // 创建 1200×800 窗口
	BeginBatchDraw();           // 启用批量绘图(防闪烁)
	srand((unsigned int)time(0)); // 初始化随机种子
	creat_data();               // 生成 20 帧爱心动画图像
	SetWorkingImage();          // 切回窗口为绘图目标

	// ✅ 修复:直接使用固定行高 48px(24号字体×2行)
	settextstyle(24, 0, _T("微软雅黑"));
	int textWidth = textwidth(_T("送给小静的爱心"));
	int txtX = xScreen - textWidth - 10;           // 右侧留 10px
	int txtY = yScreen - 10 - 48;                  // ✅ 上移两行 = 48px

	bool extend = true, shrink = false;
	for (int frame = 0; !_kbhit();)
	{
		putimage(0, 0, &images[frame]); // 播放当前帧

		// ✅ 文字绘制(带描边,清晰度满分)
		setcolor(BLACK);
		outtextxy(txtX - 1, txtY - 1, _T("送给xx的爱心"));
		outtextxy(txtX + 1, txtY - 1, _T("送给xx的爱心"));
		outtextxy(txtX - 1, txtY + 1, _T("送给xx的爱心"));
		outtextxy(txtX + 1, txtY + 1, _T("送给xx的爱心"));
		setcolor(WHITE);
		outtextxy(txtX, txtY, _T("送给xx的爱心"));

		FlushBatchDraw();
		Sleep(20);
		cleardevice();

		// ❤️ 爱心呼吸控制(逻辑不变)
		if (extend) {
			if (frame == 19) {
				extend = false;
				shrink = true;
			}
			else {
				++frame;
			}
		}
		else {
			if (frame == 0) {
				extend = true;
				shrink = false;
			}
			else {
				--frame;
			}
		}
	}

	EndBatchDraw();
	closegraph();
	return 0;
}

演示结果:
在这里插入图片描述
注意:1.需要下载easyx库2.需要对方电脑运行,最好加一个C++的dll库

### 回答1: 你好!谢谢你选择与我交流。 Visual C++ 是 Microsoft 公司推出的一款编程语言开发环境,适用于 Windows 平台的应用程序开发。它支持 C++、C 和 C++/CLI 语言,可以开发桌面应用程序、游戏、驱动程序、组件对象模型(COM)组件等。 对于很多程序员来说,Visual C++ 是一个非常强大的工具,可以用来开发高性能的 Windows 应用程序。Visual C++ 通过提供丰富的库和工具来简化开发过程,使程序员能够更快速地实现功能。 如果你想学习 Visual C++,可以先掌握 C++ 的基础知识,然后再深入学习 Visual C++ 的相关知识。你可以通过网上的教程、书籍、课程等途径进行学习。 希望我的回答能够帮助到你,如果你还有其他问题,请随时提出。 ### 回答2: Visual C++ 爱心代码是一段用于绘制爱心形状的代码。在 Visual C++ 中,我们可以使用 Graphics 组件来绘制图形。下面是一个使用 Visual C++ 绘制爱心的简单示例代码: ```cpp #include <iostream> #include <Windows.h> #include <cmath> using namespace std; int main() { HDC hDC = GetDC(NULL); int width = GetSystemMetrics(SM_CXSCREEN); int height = GetSystemMetrics(SM_CYSCREEN); int xCenter = width / 2; int yCenter = height / 2; int radius = 100; int numPoints = 100; for (int i = 0; i < numPoints; i++) { double x = radius * sin(2 * M_PI * i / numPoints); double y = radius * cos(2 * M_PI * i / numPoints); SetPixel(hDC, xCenter + x, yCenter - y, RGB(255, 0, 0)); } ReleaseDC(NULL, hDC); return 0; } ``` 这段代码使用 Windows.h 头文件中的函数和数据类型来获得屏幕的宽度和高度,并计算出绘制爱心的中心点和半径。然后使用 sin 和 cos 函数来计算每个点的坐标,并使用 SetPixel 函数来在屏幕上绘制红色的像素点,形成一个爱心形状。 这只是一个简单的爱心绘制示例,实际上可以根据需要进行更复杂的绘制,例如添加颜色渐变、动画效果等。同时,Visual C++ 还提供了更强大的绘图功能,如 GDI+、Direct2D 等,可以实现更复杂的图形绘制操作。 ### 回答3: 爱心代码是一种绘图代码,可以通过编程语言在屏幕上绘制出一个形状像爱心的图案。其中,Visual C是一种编程环境,可以使用C语言或C++语言进行编程。 编写爱心代码的过程大致如下: 1. 首先,在Visual C中创建一个新的C++项目。 2. 引入所需的绘图库,例如Windows.h。 3. 在代码中定义所需的变量,如窗口句柄、画笔、画刷等。 4. 在窗口的绘图函数中,使用画笔和画刷,调用绘图函数绘制爱心的各个部分。 5. 最后,在主函数中调用窗口函数,创建并显示窗口。 具体的绘图代码如下: ``` #include <Windows.h> LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (uMsg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // 设置画笔颜色和画刷颜色 HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0)); SelectObject(hdc, hPen); SelectObject(hdc, hBrush); // 绘制爱心的左侧部分 MoveToEx(hdc, 100, 200, NULL); CurveTo(hdc, 150, 150, 250, 150, 300, 200); // 绘制爱心的右侧部分 CurveTo(hdc, 350, 150, 450, 150, 500, 200); LineTo(hdc, 400, 350); LineTo(hdc, 300, 400); LineTo(hdc, 200, 350); LineTo(hdc, 100, 200); DeleteObject(hPen); DeleteObject(hBrush); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { const wchar_t CLASS_NAME[] = L"爱心窗口"; HWND hwnd; MSG msg; // 注册窗口类 WNDCLASS wc = {}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; RegisterClass(&wc); // 创建窗口 hwnd = CreateWindowEx(0, CLASS_NAME, L"爱心", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 600, 600, NULL, NULL, hInstance, NULL); if (hwnd == NULL) { return 0; } ShowWindow(hwnd, nCmdShow); // 消息循环 while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } ``` 以上是一个简单的使用Visual C编写爱心代码的示例,通过绘制线段和曲线,利用画笔和画刷设置颜色来实现爱心图案的绘制。通过这段代码,我们可以在屏幕上看到一个形状像爱心的图案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值