目录
需要包含的头文件
图片素材的路径
初始化背景图片
报错怎么解决?
初始化流星雨
放置流星雨图片
让流星雨动起来
总不能让流星砸到地面吧
是不是应该再来一点背景音乐?
所有代码
需要包含的头文件
IMAGE img;//创建流星雨的图片变量
void load()
{
loadimage(&img, "./1.jpg", 40, 40);//加载流星雨的图片,大小为40*40
}
在此之前,我们需要包含一些头文件才能正常使程序运行起来
下面是需要的头文件
#include <stdio.h>//不用多说,肯定需要
#include <time.h>//随机函数需要用到
#include <easyx.h>//这是一个图形用户界面,流星雨的展示就依靠这个头文件
#include <conio.h>//这是一个控制台的头文件,不一定需要,但可以根据用户按下的按键来决定程序是否继续运行
在这些头文件中,easyx的头文件不一定所有人的电脑上都会有,所以如果没有的可以去官网下载一个,下面是官网的链接:
EasyX Graphics Library for C++
进去之后,我们点击下载按钮
然后跟着步骤安装就好了
图片素材的路径
这里所有图片素材都是相对路径,如果运行没有画面请检查路径是否正确!!
初始化背景图片
在此之前我们可以先加载一个漂亮的背景图片
就像这样:
IMAGE img_bk;//创建一个名为img_bk的图片变量
int main()
{
initgraph(1100, 700,1);//初始化一个1100*700的窗口,1表示需要带有控制台
cleardevice();//防止闪屏
loadimage(&img_bk, "./bk.jpg", getwidth(), getheight());//加载图片
putimage(0, 0, &img_bk);//放置图片
system("pause");
return 0;
}
报错怎么解决?
也许你的VS会在写loadimage和putimage的时候报错,此时不要慌,如下是解决办法:
点击项目->最后一个属性,然后出现以下界面
这样子设置就不会报错了,当然改为未设置也是可以的
所有工作完成之后就可以来运行看看效果了
此时我们已经成功添加了背景图片
初始化流星雨
定义一个流星雨首先明确数据类型是一个结构体类型
然后是流星雨的坐标,流星雨的速度
所以我们如下定义并初始化一个流星雨
struct meteor
{
int x;
int y;
int speed;
};
void init(meteor* ps,int x,int y,int speed)
{
ps->x = x;
ps->y = y;
ps->speed = speed;//x,y,speed均是需要传进来的参数
}
void draw(meteor* ps)
{
putimage(ps->x, ps->y, &img, SRCPAINT);//放置流星雨的图片,格式为SRCPAINT
}
放置流星雨图片
下面我们先来初始化并放置一个流星的图片看看效果
int main()
{
initgraph(1100, 700,1);//初始化一个1100*700的窗口,1表示需要带有控制台
cleardevice();//防止闪屏
load();
loadimage(&img_bk, "./bk.jpg", getwidth(), getheight());//加载图片
putimage(0, 0, &img_bk);//放置图片
meteor m;
init(&m, 0, 0, 5);
draw(&m);
system("pause");
return 0;
}
这样一个流星雨就放置完成了,不过一个肯定不够,我们可以刚开始就初始化多一点,而且我们可以让其初始化的位置随机
为了让流星雨不要出现得太突兀,我们可以把初始化的坐标放在坐标轴的负半轴,就像这样:
#define NUM 30
for (int i = 0; i < NUM; i++)
{
init(m+i, rand() % 1100 - 300, rand() % 30 - 20, rand() % 5 + 1);//x和y随机,速度也随机初始化
}
for (int i = 0; i < NUM; i++)
{
draw(m+i);
}
这样我们就初始化并放置了30个流星雨的图片,当然这样我们是看不见的,因为大部分流星雨都在屏幕外面,外面还需要让流星雨动起来
让流星雨动起来
下面我们就让流星雨动起来
void move(meteor* ps)
{
ps->x += ps->speed;
ps->y += ps->speed;//让两个坐标轴分别加上速度的偏移量就可以使流星雨向斜下方运动了
}
while (1)//需要一个循环来使图片不停放置和移动,每循环一次可以理解为一帧动画
{
cleardevice();
BeginBatchDraw();
putimage(0, 0, &img_bk);//放置图片
for (int i = 0; i < NUM; i++)
{
draw(m+i);
move(m+i);
}
Sleep(100);//睡眠100毫秒,防止流星雨太快
EndBatchDraw();//使用双缓冲画图,防止闪屏
}
总不能让流星砸到地面吧
我们可以让流星雨的y坐标达到一定值时把流星再重新初始化一下,就可以让流星雨不停地下落了
void move(meteor* ps)
{
ps->x += ps->speed;
ps->y += ps->speed;//让两个坐标轴分别加上速度的偏移量就可以使流星雨向斜下方运动了
if (ps->y > 430)
{
ps->x = rand() % 1100 - 300;
ps->y = rand() % 30 - 20;//当流星雨的y坐标超过430的时候,我们将其重新初始化
}
}
是不是应该再来一点背景音乐?
mciSendString("open ./1.mp3", 0, 0, 0);//加载音乐
mciSendString("play ./1.mp3 repeat", 0, 0, 0);//循环播放音乐
所有代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>//不用多说,肯定需要
#include <time.h>//随机函数需要用到
#include <easyx.h>//这是一个图形用户界面,流星雨的展示就依靠这个头文件
#include <conio.h>//这是一个控制台的头文件,不一定需要,但可以根据用户按下的按键来决定程序是否继续运行
IMAGE img_bk;//创建一个名为img_bk的图片变量
IMAGE img;//创建流星雨的图片变量
#define NUM 30
void load()
{
loadimage(&img, "./1.jpg", 40, 40);//加载流星雨的图片,大小为40*40
}
struct meteor
{
int x;
int y;
int speed;
};
void init(meteor* ps,int x,int y,int speed)
{
ps->x = x;
ps->y = y;
ps->speed = speed;//x,y,speed均是需要传进来的参数
}
void draw(meteor* ps)
{
putimage(ps->x, ps->y, &img, SRCPAINT);//放置流星雨的图片,格式为SRCPAINT
}
void move(meteor* ps)
{
ps->x += ps->speed;
ps->y += ps->speed;//让两个坐标轴分别加上速度的偏移量就可以使流星雨向斜下方运动了
if (ps->y > 430)
{
ps->x = rand() % 1100 - 300;
ps->y = rand() % 30 - 20;//当流星雨的y坐标超过430的时候,我们将其重新初始化
}
}
int main()
{
srand(time(NULL));//随机时间函数
initgraph(1100, 700,1);//初始化一个1100*700的窗口,1表示需要带有控制台
cleardevice();//防止闪屏
load();
loadimage(&img_bk, "./bk.jpg", getwidth(), getheight());//加载图片
putimage(0, 0, &img_bk);//放置图片
meteor m[NUM];
mciSendString("open ./1.mp3", 0, 0, 0);//加载音乐
mciSendString("play ./1.mp3 repeat", 0, 0, 0);//循环播放音乐
for (int i = 0; i < NUM; i++)
{
init(m+i, rand() % 1100 - 300, rand() % 30 - 20, rand() % 5 + 1);//x和y随机,速度也随机初始化
}
while (1)//需要一个循环来使图片不停放置和移动,每循环一次可以理解为一帧动画
{
cleardevice();
BeginBatchDraw();
putimage(0, 0, &img_bk);//放置图片
for (int i = 0; i < NUM; i++)
{
draw(m+i);
move(m+i);
}
Sleep(60);//睡眠60毫秒,防止流星雨太快
EndBatchDraw();//使用双缓冲画图,防止闪屏
}
system("pause");
return 0;
}
运行一下看看效果怎么样呢?