哈喽,大家好,昨天是七夕节,不知道大家是成双入对还是孤苦伶仃呢?考略到很多同学可能还是一个人吃饭一个人睡,所以这期内容本来是昨天准备出的,直接贴心的为大家打包部署好,直接拿走就能用,但是问题就出在打包部署上,由于路径问题,搞到昨天晚上11点多也是没有打包成功,音乐和贴图加载不出来。没有办法,只能放弃上传,因为这个程序涉及资源文件的引用,所以如果是没有接触过打包部署的同学是不太容易拿去表白用哒。
然后今天捣鼓了一上午,终于是完成了制作,虽然七夕已过,但是大家拿来当个教材学习学习代码也是不赖的嘛,涉及贴图和音乐等的制作值得好好学习一下呦,等到下一个七夕,就可以自己直接做一个啦!
然后先给大家看看效果,然后是原代码分享和程序包附件。因为是源码篇,就不讲解了,代码找中有大量我写的注释,应该比较容易懂,如果要是后期有时间,可能也会出一期讲解。
声明:本制作来源于B站视频《C/C++表白项目:浪漫流星雨。谁说程序员不浪漫,马上教你写一个浪漫又深情的表白程》@爱编程的柚子。然后也是加入了很多我自己的改动,例如什么星空范围,移动方式等,加之考略到有的同学会直接用,所以也不涉及具体的人名,改成了通用的话术,也就是说你可以下载下来同时发个很多人(狗头+手动滑稽)。OK,话不多说上才艺!
额,本来是想发个小视频的,录完了发现发不了啊,那就来几张图片吧,效果都是动态的,有背景音乐
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <easyx.h> //第三方图形库
#include <time.h>
#include <conio.h> //涉及按键暂停功能
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
#define Heart_NUM (int)52.0
#define STAR_NUM 1314
#define METEOR_NUM (int)99.9
/*@背景*/
//定义并加载图片
IMAGE bk[2];
void loadImgbk()
{
loadimage(bk+0, _T("3.jpg"), getwidth(), getheight());
loadimage(bk+1, _T("4.jpg"), getwidth(), getheight());
}
/*@开局*/
void welcome()
{
//播放音乐
mciSendString(_T("open 浪漫空气.mp3"), NULL, 0, NULL);
mciSendString(_T("play 浪漫空气.mp3"), NULL, 0, NULL);
//设置背景
setbkmode(TRANSPARENT);
//设置内容
//按任意键结束循环,检测按键函数_kbhit,来自于库函数conin.h,有按键返回真,没有返回假
while (!_kbhit())
{
cleardevice();
//背景显示
putimage(0, 0, bk+1);
//设置标题格式
settextstyle(40, 0, _T("华文行楷"));
int tx = (getwidth()-textwidth(_T("因为有你,星河璀璨!"))) / 2;
outtextxy(tx, 20, _T("因为有你,星河璀璨!"));
//主体
settextcolor(RGB(rand()%156+100, rand()%156+100, rand()%156+100));
settextstyle(22, 0, _T("隶书"));
outtextxy(30, 100, _T("身在远方的你还好吧!我有很多的话想说给你听,但是我不知道怎么样说出口!好好保重自己!"));
outtextxy(30, 160, _T("寂寞的夜因你失眠,我失去了做梦的心情,但并非从此就没有梦,而是梦里依然有你!"));
outtextxy(30, 220, _T("傻瓜!每次听到你说不要去喜欢你之类的话,我都会心酸!不管怎么样我只知道我已经深深的爱上你了!"));
outtextxy(30, 280, _T("我想在你的心里盖一间小屋,高兴了在那里挥拳欢呼,伤心了躲着放声痛哭。"));
outtextxy(30, 340, _T("我一生中最幸运的两件事:一件是时间终于将我对你的爱消耗殆尽;一件是很久很久以前有一天,我遇见你。"));
outtextxy(30, 400, _T("温馨的风,快乐的云,长久的天,永恒的地,注定的缘,难舍的情,旧的短信,新的心愿!永远不变的真情!"));
outtextxy(30, 460, _T("此情无计可消除。才下眉头,却上心头。"));
outtextxy(30, 520, _T("时常想你在心里,日日想你在哪里,总不忍心打扰你,今天只是太想你,发个信息告诉你,我在这里很想你。"));
outtextxy(30, 580, _T("人说相思苦,离人心上苦缠绵。我说相思难,山高路远难相见。一点愁感慨万千,红豆应无言。"));
outtextxy(1000, 750, _T("——守护月亮的星光"));
for (int i = 0; i < Heart_NUM; i++)
{
settextcolor(RGB(rand()%156+100, rand()%156+100, rand()%156+100));
outtextxy(rand()%getwidth(), rand()%getheight(), _T("♥"));
}
Sleep(800);
}
}
/*@星星*/
//星星结构体
struct Star
{
int x;
int y;
int speed;
int size;
int moveway;
COLORREF color;
};
//创建结构体数组定义所有星星
struct Star star[STAR_NUM];
//初始化星星
void initStar(int i)
{
star[i].x = rand() % getwidth();
if (star[i].x <= getwidth()/2)
{
star[i].y = rand()%getheight() - 350;
}
else
{
star[i].y = rand()%getheight() - 350 + (star[i].x - getwidth()/2)/2;
}
star[i].size = rand() % 100;
star[i].speed = rand() % 2;
if (star[i].size >= 80 && star[i].size < 99 && star[i].y != 0)
{
star[i].speed = rand() % 2;
if (star[i].speed == 1)
{
star[i].speed = rand() % 2;
if (star[i].speed == 1)
{
star[i].speed = rand() % 3;
}
}
}
else
{
star[i].speed = 0;
}
star[i].moveway = rand() % 3;
star[i].color = RGB(rand()%256, rand()%256, rand()%256);
}
//绘制星星
void drwaStar()
{
for (int i = 0; i < STAR_NUM; i++)
{
if(star[i].size < 80)
{
putpixel(star[i].x, star[i].y, star[i].color);
/*putpixel(star[i].x+1, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y+1, star[i].color);
putpixel(star[i].x-1, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y-1, star[i].color);*/
}
else if (star[i].size < 95)
{
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, 1);
}
else if (star[i].size < 99)
{
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, 2);
/*putpixel(star[i].x, star[i].y, star[i].color);
putpixel(star[i].x+1, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y+1, star[i].color);
putpixel(star[i].x-1, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y-1, star[i].color);
putpixel(star[i].x+1, star[i].y+1, star[i].color);
putpixel(star[i].x+1, star[i].y-1, star[i].color);
putpixel(star[i].x-1, star[i].y+1, star[i].color);
putpixel(star[i].x-1, star[i].y-1, star[i].color);
putpixel(star[i].x+2, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y+2, star[i].color);
putpixel(star[i].x-2, star[i].y, star[i].color);
putpixel(star[i].x, star[i].y-2, star[i].color);*/
}
else
{
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, 3);
}
// /*putpixel(star[i].x, star[i].y, star[i].color);
// putpixel(star[i].x+1, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y+1, star[i].color);
// putpixel(star[i].x-1, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y-1, star[i].color);
// putpixel(star[i].x+1, star[i].y+1, star[i].color);
// putpixel(star[i].x+1, star[i].y-1, star[i].color);
// putpixel(star[i].x-1, star[i].y+1, star[i].color);
// putpixel(star[i].x-1, star[i].y-1, star[i].color);
// putpixel(star[i].x+2, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y+2, star[i].color);
// putpixel(star[i].x-2, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y-2, star[i].color);
// putpixel(star[i].x+2, star[i].y+1, star[i].color);
// putpixel(star[i].x+2, star[i].y-1, star[i].color);
// putpixel(star[i].x-2, star[i].y+1, star[i].color);
// putpixel(star[i].x-2, star[i].y-1, star[i].color);
// putpixel(star[i].x+1, star[i].y+2, star[i].color);
// putpixel(star[i].x+1, star[i].y-2, star[i].color);
// putpixel(star[i].x-1, star[i].y+2, star[i].color);
// putpixel(star[i].x-1, star[i].y-2, star[i].color);
// putpixel(star[i].x+3, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y+3, star[i].color);
// putpixel(star[i].x-3, star[i].y, star[i].color);
// putpixel(star[i].x, star[i].y-3, star[i].color);*/
//}
}
}
//移动星星
void moveStar()
{
for (int i = 0; i < STAR_NUM; i++)
{
if (star[i].moveway == 0)
{
star[i].x += star[i].speed;
}
else if (star[i].moveway == 1)
{
star[i].y += star[i].speed;
}
else if (star[i].moveway == 2)
{
star[i].x += star[i].speed;
star[i].y += star[i].speed;
}
if (star[i].x > getwidth())
{
star[i].x = rand()%(getwidth()-10)+5;
int before = star[i].moveway;
do
{
star[i].moveway = rand()%3;
} while (star[i].moveway == before);
}
if (star[i].x > getwidth()/2 && star[i].y > getheight()-200)
{
star[i].y = rand()%(getheight()-10)+5;
int before = star[i].moveway;
do
{
star[i].moveway = rand()%3;
} while (star[i].moveway == before);
}
else if (star[i].x < getwidth()/2 && star[i].y > getheight()-350)
{
star[i].y = rand()%(getheight()-10)+5;
int before = star[i].moveway;
do
{
star[i].moveway = rand()%3;
} while (star[i].moveway == before);
}
}
}
/*@流星*/
//定义数组加载图片
IMAGE img[2];
void loadImg()
{
loadimage(img+0, _T("1.jpg"), 50, 50);
loadimage(img+1, _T("2.jpg"), 50, 50);
}
//流星结构体
struct Meteor
{
int x;
int y;
int speed;
int sel;
};
//创建结构体数组定义所有流星
struct Meteor meteor[METEOR_NUM];
//初始化流星
void initMeteor(int i)
{
meteor[i].x = rand()%(2*getwidth()) - getwidth();//-1200~1200
meteor[i].y = rand()%50 - 100;
meteor[i].speed = rand()%7 + 1;
meteor[i].sel = rand()%2;
}
//绘制流星
void drawMeteor()
{
for (int i = 0; i < METEOR_NUM; i++)
{
putimage(meteor[i].x, meteor[i].y, img+meteor[i].sel, SRCPAINT);
}
}
//移动流星
void moveMeteor()
{
for (int i = 0; i < METEOR_NUM; i++)
{
meteor[i].x += meteor[i].speed;
meteor[i].y += meteor[i].speed;
if (meteor[i].x>=getwidth() || meteor[i].y>=getheight())
{
initMeteor(i);
}
}
}
星星线程
//DWORD WINAPI stars(LPVOID IpParam)
//{
// //双缓冲绘图
// BeginBatchDraw();
// while (true)
// {
// //cleardevice();
// //putimage(0, 0, bk+0);
// Sleep(10);
// moveStar();
// FlushBatchDraw();
// }
// EndBatchDraw();
// return 0;
//}
流星线程
//DWORD WINAPI meteors(LPVOID IpParam)
//{
// //双缓冲绘图
// BeginBatchDraw();
// while (true)
// {
// cleardevice();
// //putimage(0, 0, bk+0);
// drwaStar();
// drawMeteor();
// moveMeteor();
// Sleep(10);
// FlushBatchDraw();
// }
// EndBatchDraw();
// return 0;
//}
int main()
{
//创建窗口
initgraph(1200, 800);
//设置随机种子
srand((unsigned)time(NULL));
//加载背景图
loadImgbk();
//加载流星贴图
loadImg();
//初始化星星
for (int i = 0; i < STAR_NUM; i++)
{
initStar(i);
}
//初始化流星
for (int j = 0; j < METEOR_NUM; j++)
{
initMeteor(j);
}
//开局界面
welcome();
定义句柄handle1为创建线程Producer
//HANDLE handle1 = CreateThread(NULL, 0, stars, NULL, 0, NULL);
定义句柄handle2为创建线程Producer
//HANDLE handle2 = CreateThread(NULL, 0, meteors, NULL, 0, NULL);
定义句柄组handle包括句柄handle1和handle1
//HANDLE handle[2] = {handle1, handle2};
调用函数WaitForMultipleObjects等待句柄组handle中的线程都结束
//WaitForMultipleObjects(2, handle,TRUE,INFINITE);
//双缓冲绘图
BeginBatchDraw();
while (_kbhit())
{
cleardevice();
putimage(0, 0, bk+0);
drwaStar();
moveStar();
drawMeteor();
moveMeteor();
Sleep(10);
FlushBatchDraw();
}
EndBatchDraw();
getchar();
return 0;
}
发代码是为了大家学习和自定义修改一些东西哈。
靠了,我发现CSDN也没有上传附件的功能......那就给大家两种方式吧
百度网盘:https://pan.baidu.com/s/1_uOw27OR0-wcg09zDTIEMQ?pwd=9999 提取码: 9999
CSDN资源:https://download.csdn.net/download/qq_63435549/86338825
这个在CSDN下东东西要积分啊,不知道用不用花钱,不是很懂,如果不用前钱希望大家从CSDN下,给我点积分(不知道有啥用,搞排名的吗?)花钱的话就去网盘吧。
然后这个资源有两种,一个是压缩包,解压点击exe就能运行,另一个是打包好的exe安装程序,会安装一个软件,在桌面生成快捷方式,可以直接从桌面启动(逼格一下子高起来了有木有!)