C语言.表白神器.爱你之心之闪耀

该文介绍了一个使用C语言编程实现的爱心动画程序,通过极坐标公式创建爱心图形,利用粒子发射原理模拟爱心放大消失的效果。程序还整合了音乐播放功能,为情人节等场合营造氛围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

爱你之心之闪耀,这个名字比较沙雕哈哈哈。。。

C语言.爱你之心之闪耀

爱心函数的选取

Webdings和Webdings字符码对应表
在这里插入图片描述

字符Y就对应爱心,有兴趣的可以打印其它特殊字符。

爱心函数1

r = a*(1+sin(θ));

a控制爱心的大小

效果:
在这里插入图片描述

爱心函数2

在这里插入图片描述
效果:
在这里插入图片描述

需要说明的是上面都是极坐标公式,vs中是直角坐标系需要转换。

在这里插入图片描述

第二个爱心公式转后成直角坐标系时,y需要变成-y整个图形才能向上面一样。

未变成-y的图形:
在这里插入图片描述

还需要说明的是,第二个爱心极坐标公式转换后还需要乘上一个基础值才能使爱心放大。因为r(p)的取值范围使[0,1]

简单爱心

需要用到Easyx,不会的函数自己得查文档
EasyX

#define PI 3.1415926
int main()
{
	initgraph(600, 480);
	double r = 0;//0...1
	double angle = 0;
	int x = 0;
	int y = 0;
	int R = 80;//放大80倍
	settextcolor(RED);
	for (angle = 0; angle < PI * 2; angle += 0.1)
	{
		r = sin(angle) * sqrt(fabs(cos(angle))) / (sin(angle) + sqrt(2)) - 2 * sin(angle) + 2;
		y = -R * r * sin(angle) + 300;
		x = R * r * cos(angle) + 300;
		settextstyle(10, 0, L"webdings");
		setbkmode(TRANSPARENT);//图案背景设置成透明的
		outtextxy(x + 20, y + 20, 'Y');//打印爱心
	}
	system("pause");
	closegraph();
	return 0;
}

粒子发射原理

在这里插入图片描述

这里的height是下图函数中的参数,文字的高度,你可以理解为大小。

在这里插入图片描述

若干(我一开始设置的是20)个爱心一开始基础框架结构从R = 60, height = 10图(我设置的)开始,每次循环,R++,height++,结果小爱心变大,整体爱心向外延申(放大过程),当到R增加到一定程度爱心会消失。
还要明确爱心总共的个数设置多一点效果会好一些,我是这样设置:一开始初始化的爱心是20个,放大20次(R会增加20次),总共爱心为20*20。
整个结果是:所有被初始化过的爱心都在变大消失,变大消失…
在加上死循环,效果就会像视频那样。

整体思路就是上述的粒子发射原理。你可以像我一样设置音乐,下面也会讲。

爱心结构

typedef struct Love
{
	int x;//x,y即极坐标转换后的坐标
	int y;//x,y为什么是int,因为outtextxy()函数是int
	int height;//爱心的高度
	double r;//极坐标中的r
	double angle;//极坐标的角度
	int R;//爱心图形的基础大小。
}Love;
extern Love loves[HEARTNUMS * BIGGERTIMES];//总共的爱心,是一个全局变量

一些宏

涉及到数字的大部分我都设置成了宏

#define PI 3.1415926  
#define HEARTNUMS  20  //刚开始初始化爱心的个数
#define BIGGERTIMES 20 //放大的次数
#define TRUE_R 60   //基础值,即扩大的倍数

初始化

init

void init()
{
	initgraph(640, 480);//窗口大小
	srand((unsigned int)time(NULL));//随机种子
	memset(loves, 0, sizeof(loves));//所有爱心中的所有变量初始化为0
}

创建若干爱心并初始化

setHeart

//设置随机的角度
void getRandAg(Love loves[])
{
	for (int i = 0; i < HEARTNUMS; i++)
	{
		//随机值只能取整 angle [0,2*PI] 因为sin、cos周期性变化所以取模1000没事
		int angle = rand() % 314 * 2 * 2;
		loves[i].angle = angle * 0.01;

		//避免爱心角度一样
		for (int j = 0; j <= i; j++)
		{
			while (loves[j].angle == loves[i].angle)
			{
				int angle = rand() % 1000;
				loves[i].angle = angle * 0.01;
			}
		}
	}
}
//函数功能,随机设置 HEARTSNUM 个爱心
void setHeart()
{
	int k = 0;
	//找到没有设置的爱心
	for (k = 0; k < HEARTNUMS * BIGGERTIMES && loves[k].R > 0; k++);

	getRandAg(&loves[k]);//得到随机的角度

	for (int i = k; i < k + HEARTNUMS; i++)
	{
		loves[i].height = 0;//刚开始爱心的高度为0
		loves[i].R = TRUE_R;
		loves[i].r = sin(loves[i].angle) * sqrt(fabs(cos(loves[i].angle))) / (sin(loves[i].angle) + sqrt(2)) -
			2 * sin(loves[i].angle) + 2;//极坐标公式
		loves[i].y = -loves[i].R * loves[i].r * sin(loves[i].angle) + 80;// 80 ,300是偏移量,使爱心放到适当的位置
		loves[i].x = loves[i].R * loves[i].r * cos(loves[i].angle) + 300;
	}
}

展示爱心

展示的是所有被初始化过的爱心(R > 0)

showHeart

void showHeart()
{
    //BeginBatchDraw()、EndBatchDraw()批量绘制图片需要使用的函数
	BeginBatchDraw();
	cleardevice();//清空屏幕
	settextcolor(RED);//设置颜色
	//for (int i = k; i < k + HEARTNUMS; i++)
	for (int i = 0; i < BIGGERTIMES * HEARTNUMS; i++)
	{
		if (loves[i].R == 0)
			continue;
		//设置字体样式
		settextstyle(loves[i].height + 10, 0, L"webdings");
		setbkmode(TRANSPARENT);//图案设置成透明的
		outtextxy(loves[i].x + 20, loves[i].y + 20, 'Y');//打印爱心
	}
	EndBatchDraw();
}

爱心变大

所有被初始化过的爱心变大

modifyHeart

void modifyHeart()
{
	for (int i = 0; i < BIGGERTIMES * HEARTNUMS; i++)
	{
		if (loves[i].R == 0)
			continue;
		loves[i].R++;
		if (loves[i].R > TRUE_R + BIGGERTIMES)
		{
			memset(&loves[i], 0, sizeof(Love));
		}
		loves[i].height++;
		loves[i].y = -loves[i].R * loves[i].r * sin(loves[i].angle) + 80;
		loves[i].x = loves[i].R * loves[i].r * cos(loves[i].angle) + 300;
	}
}

设置音乐

要用的头文件、预处理指令

#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

两个函数 open打开音乐play播放,./music.mp3./这个意思是当前路径下,music.mp3是音乐的名字和后缀。""前要加上L,是字符集的原因

在这里插入图片描述

		mciSendString(L"open  ./music.mp3", 0, 0, 0);
		mciSendString(L"play  ./music.mp3  repeat", 0, 0, 0);

音乐的格式一定要是mp3格式的,可以去QQ音乐下载。放在哪看下面图片

在这里插入图片描述

你只要看你的Love.cpp即源文件在哪,你的音乐就放在哪。

主函数

int main()
{
	init();//初识化设置
	while (1)
	{
		setHeart();//初始设置爱心
		showHeart();//绘制爱心
		modifyHeart();//爱心闪耀(修改)
		mciSendString(L"open  ./music.mp3", 0, 0, 0);
		mciSendString(L"play  ./music.mp3  repeat", 0, 0, 0);
		Sleep(30);//等待30毫秒
	}
	closegraph();
	return 0;
}

Love.h

#pragma once
#include <graphics.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")

#define PI 3.1415926  
#define HEARTNUMS  20  //刚开始初始化爱心的个数
#define BIGGERTIMES 20 //放大的次数
#define TRUE_R 60   //基础值,即扩大的倍数

typedef struct Love
{
	int x;
	int y;
	int height;//爱心的高度
	double r;//极坐标中的r
	double angle;//极坐标的角度
	int R;//爱心图形的基础大小。
}Love;
extern Love loves[HEARTNUMS * BIGGERTIMES];

Love.cpp

#include"Love.h"

Love loves[HEARTNUMS * BIGGERTIMES];


void init()
{
	initgraph(640, 480);
	srand((unsigned int)time(NULL));
	memset(loves, 0, sizeof(loves));
}

void getRandAg(Love loves[])
{
	for (int i = 0; i < HEARTNUMS; i++)
	{
		//设置随机的爱心
		//随机值只能取整 angle 0~PI 因为sin、cos周期性变化所以取模1000没事
		int angle = rand() % 314 * 2 * 2;
		loves[i].angle = angle * 0.01;

		//避免爱心角度一样
		for (int j = 0; j < i; j++)
		{
			while (loves[j].angle == loves[i].angle)
			{
				int angle = rand() % 1000;
				loves[i].angle = angle * 0.01;
			}
		}
	}
}
//函数功能,随机设置 HEARTSNUM 个爱心
void setHeart()
{
	int k = 0;
	//找到没有设置的爱心
	for (k = 0; k < HEARTNUMS * BIGGERTIMES && loves[k].R > 0; k++);

	getRandAg(&loves[k]);//得到随机的角度

	for (int i = k; i < k + HEARTNUMS; i++)
	{
		loves[i].height = 0;//刚开始爱心的高度为0
		loves[i].R = TRUE_R;
		loves[i].r = sin(loves[i].angle) * sqrt(fabs(cos(loves[i].angle))) / (sin(loves[i].angle) + sqrt(2)) -
			2 * sin(loves[i].angle) + 2;
		loves[i].y = -loves[i].R * loves[i].r * sin(loves[i].angle) + 80;
		loves[i].x = loves[i].R * loves[i].r * cos(loves[i].angle) + 300;
	}
}

void showHeart()
{
	BeginBatchDraw();
	cleardevice();//清空屏幕
	settextcolor(RED);
	//for (int i = k; i < k + HEARTNUMS; i++)
	for (int i = 0; i < BIGGERTIMES * HEARTNUMS; i++)
	{
		if (loves[i].R == 0)
			continue;
		//设置字体样式
		settextstyle(loves[i].height + 10, 0, L"webdings");
		setbkmode(TRANSPARENT);//图形设置成透明的
		outtextxy(loves[i].x + 20, loves[i].y + 20, 'Y');//打印爱心
	}
	EndBatchDraw();
}

void modifyHeart()
{
	for (int i = 0; i < BIGGERTIMES * HEARTNUMS; i++)
	{
		if (loves[i].R == 0)
			continue;
		loves[i].R++;
		if (loves[i].R > TRUE_R + BIGGERTIMES)
		{
			memset(&loves[i], 0, sizeof(Love));
		}
		loves[i].height++;
		loves[i].y = -loves[i].R * loves[i].r * sin(loves[i].angle) + 80;
		loves[i].x = loves[i].R * loves[i].r * cos(loves[i].angle) + 300;
	}
}

int main()
{
	init();//初识化设置
	while (1)
	{
		setHeart();//初始设置爱心
		showHeart();//绘制爱心
		modifyHeart();//爱心变大
		mciSendString(L"open  ./music.mp3", 0, 0, 0);
		mciSendString(L"play  ./music.mp3  repeat", 0, 0, 0);
		Sleep(30);//等待30毫秒
	}
	closegraph();
	return 0;
}


祝有情人,终成眷属

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值