浪漫七夕流星雨
- 实现文字的显示
- 实现小星星的绘制以及移动
- 实现流星雨的绘制以及移动
- 实现音乐的播放
#include <graphics.h> //图形库头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <mmsystem.h> //音频头文件
#pragma comment(lib,"winmm.lib") //音频接口静态库
#define STAR_NUM 520 //星星个数
#define METEOR_NUM 52 //流星个数
//小星星
struct Star {
int x; //x 坐标
int y; //y坐标
int r; //星星半径
int speed; //星星移动速度
COLORREF color; //星星颜色
};
//流星
struct Meteor {
int x; //x 坐标
int y; //y坐标
int speed; //流星移动速度
};
//图片
IMAGE bkimg; //背景图片
IMAGE meteor[2]; //流星图片
//星星
struct Star star[STAR_NUM];
//流星
struct Meteor meteors[METEOR_NUM];
//判断第一次文字是否显示完毕
bool flag = true;
//初始化星星
void initStar()
{
for (int i = 0; i < STAR_NUM; i++)
{
star[i].x = rand() % getwidth();
star[i].y = rand() % getheight() - 300;
star[i].r = rand() % 2 + 1;
star[i].speed = rand() % 1 + 1;
star[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
}
}
//绘制星星
void drawStar()
{
for (int i = 0; i < STAR_NUM; i++)
{
//设置星星填充颜色
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, star[i].r);
}
}
//星星移动
void moveStar()
{
for (int i = 0; i < STAR_NUM; i++)
{
star[i].x += star[i].speed;
if (star[i].x > getwidth())
{
star[i].x = 0;
}
}
}
//初始化流星
void initMeteor()
{
for (int i = 0; i < METEOR_NUM; i++)
{
meteors[i].x = rand() % (2 * getwidth()) - getwidth();
meteors[i].y = rand() % 20 - 200;
meteors[i].speed = rand() % 9 + 1;
}
}
//初始画指定流星,用于指定流星的坐标重置
void initMeteorToOne(int i)
{
meteors[i].x = rand() % (2 * getwidth()) - getwidth();
meteors[i].y = rand() % 20 - 200;
meteors[i].speed = rand() % 15 + 1;
}
//绘制流星
void drawMeteor()
{
for (int i = 0; i < METEOR_NUM; i++)
{
//SRCPAINT 防止后绘制的图遮盖前面绘制的图
putimage(meteors[i].x, meteors[i].y, meteor + rand() % 2, SRCPAINT);
}
}
//流星移动
void moveMeteor()
{
for (int i = 0; i < METEOR_NUM; i++)
{
meteors[i].x += meteors[i].speed;
meteors[i].y += meteors[i].speed;
//如果流星坐标超出范围则重新绘制
if (meteors[i].x >= getwidth() || meteors[i].y >= getheight() - 300)
{
initMeteorToOne(i);
}
}
}
//加载图片
void loadImg()
{
//加载背景图片
loadimage(&bkimg, L"./images/bk.png", getwidth(), getheight());
//加载流星一图片
loadimage(&meteor[0], L"./images/1.jpg", 50, 50);
//加载流星二图片
loadimage(&meteor[1], L"./images/2.jpg", 50, 50);
}
//绘制文字
void drawWriting(int x,int y,const wchar_t* str,int length)
{
//设置文字颜色
settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
//如果文字还未显示完毕,则设置文字颜色为白色
if (flag)
{
settextcolor(WHITE);
}
//实现单个字显示
for (int i = 0; i < length; i++)
{
int tx = 30;
outtextxy(x + i * tx, y, *str);
str++;
//文字未绘制完毕则延时0.2秒
if (flag)
{
Sleep(200);
}
}
}
//输出文字
void welcome()
{
//随机数种子
srand((unsigned int)time(NULL));
//音乐播放
mciSendString(_T("open ./images/浪漫空气.mp3 alias BGM"), NULL, NULL, NULL);
mciSendString(_T("play BGM"), NULL, NULL, NULL);
//设置背景模式(防止文字被后绘制的❤覆盖)
setbkmode(TRANSPARENT);
//设置文字样式
settextstyle(30, 0, L"华文行楷");
while (!_kbhit())
{
cleardevice();
putimage(0, 0, &bkimg); //背景输出
//输出文字
//找到文字居中横坐标(依情况左移200像素)
int tx = (getwidth() - textwidth(L"XXX我喜欢你")) / 2 - 200;
drawWriting(tx, 20, L"XXX我喜欢你",7);
drawWriting(tx, 100, L"血包我不要,我只要你",10);
drawWriting(tx, 150, L"我喜欢你,不计重力",9);
drawWriting(tx, 200, L"宝你就想cf里的源武器便宜但没人要",16);
drawWriting(tx, 250, L"春风十里,我只爱你",9);
drawWriting(tx, 300, L"我的程序只有你一个主函数",12);
drawWriting(tx, 350, L"孤单不是与生俱来,而是由你爱上一个人的那一刻开始",24);
drawWriting(tx, 400, L"如果奇迹有颜色,那一定是彩虹的颜色",17);
drawWriting(tx, 450, L"山有木兮木有枝,心悦君兮君不知",15);
drawWriting(tx, 500, L"我从不畅享未来,遇到了你以后我每天都在想",20);
drawWriting(tx, 550, L"------------ 爱你XXX",18);
//文字绘制完毕,将flag置为false
flag = false;
//绘制心
for (int i = 0; i < 10; i++)
{
drawWriting(rand() % getwidth(), rand() % getheight(), L"♥",1);
}
//延时1秒
Sleep(1000);
}
}
int main()
{
//EW_SHOWCONSOLE 控制台显示数据
initgraph(1200, 800); //初始化图形窗口宽高
loadImg(); //图片加载
initStar(); //初始化星星
initMeteor(); //初始化流星
cleardevice(); //清屏
welcome(); //文字绘制
BeginBatchDraw(); //双缓冲绘图防止卡顿
while (1)
{
cleardevice(); //清屏
putimage(0, 0, &bkimg); //背景输出
drawStar(); //绘制小星星
moveStar(); //小星星移动
drawMeteor(); //绘制流星
moveMeteor(); //流星移动
FlushBatchDraw();
}
EndBatchDraw();
system("pause"); //卡屏
closegraph(); //关闭当前窗口
return 0;
}
注意点:
- 因为需要绘制❤,因此必须使用UniCode字符集而不能使用多字节字符集
_T(“第一种处理方式”) L"第二种处理方式" - 设置背景模式(防止文字重叠出现的遮盖现象)
setbkmode(TRANSPARENT); - 防止流星图片之间的相互重叠现象
putimage(meteors[i].x, meteors[i].y, meteor + rand() % 2, SRCPAINT);