c++流星雨

一.深蓝色的天空中布满了璀璨的星星,突然天空滑过一颗流星,流星拖着长长的尾巴,悄无声息地落在空旷的原野中,之后,许多流星飞快地从眼前划过

二.我们应该如何用c++写一场流星雨呢?

一颗颗流星飞下,我们把它抽象一下,把流星作为一个对象;

同理,一闪一闪的星星,我们把星星也作为一个对象。

在此之前我们需要创建一个窗口(1200,700)(窗口的大小随意,合适就好)

流星在黑窗口下不断滑过,似乎欠缺了什么,那我们加入一个背景

好了,我们现在有了流星和星星两个对象,那它们分别应该具有什么属性?

首先是流星:

  1. 流星要有一张图,我们准备两张,交替出现,到达闪烁的效果。

2.流星要能移动,而且是斜着移动,那我们给它x,y,speed三个属性,

每次移动时让x和y都加上speed。

3.那流星该在哪里出现呢?如果全出现在窗口中好像会有点突兀,

那我们把x初始成负数,y也初始成负数,speed初始成正数,

这样这个流星有从高处滑下的效果。

4.那流星滑到右下角,出了窗口怎么办?要析构掉它吗?

不不不,我们给这个流星重新初始化,让它重新滑。

5.流星速度太快了该怎么办?用Sleep这个函数睡一会吗?

那可不行,程序会卡在那。那我们就再给流星一个属性meteor_move_stay=0,

每次绘制流星时meteor_move_stay++,当绘制了五次流星时再移动流星,然后重置meteor_move_stay。

6.流星雨,应该有很多流星,那我们就构建一个流星数组,这个数组该有多大呢?

我取的是128个流星,另外每个流星的每个属性在一定范围内随机。

接下来就是星星:

  1. 星星该有什么属性呀?动态的和静态的相比哪个更好看?

我觉得还是动态的好看,那就先给星星x,y,speed这三个属性。

  1. 星星以什么形式输出到窗口上?

星星在远处看就是一个点,那我们要怎么表示这个点呢?

输出一个像素点吗,这样好像太小了;那我们调用solidcicle这个函数画填充⚪,

再给星星加个属性r。五颜六色的星星似乎更好看,那我们再给星星加个属性color,

再画填充⚪前调用setfillcolor,给它上色。

  1. 星星该怎么移动呢?

每次星星移动时,让x+speed就好了,纵向再移动就显得有些乱了。

4.星星移动地太快怎么办

那我们再给他加个属性star_move_stay,参考上面流星。

5.有多少星星呢?

我们构建一个星星数组,每个星星的每个属性在一定范围内随机,我取的大小是666,感觉吉利。

我们总结一下:

流星和星星它们分别都需要三个成员函数,构造函数来初始化,一个函数来绘制,一个函数来移动。

好像还有最后一个问题,流星和星星不断移动靠的是把图片输出到窗口上,下次移动是需要擦除

上次输出的图片,那我们调用cleardevice清屏,再把流星和星星的绘制和移动放到一个循环中。

不过这又产生了一个问题,闪屏太严重了,那我们就调用BeginBatchDraw, FlushBatchDraw,EndBatchDraw这三个专门解决闪屏问题的函数。

三.流星雨写好了,我们再加个前言引出它会不会更好

首先我们再找一个背景图,

然后调用outtextxy,settextcolor,settextstyle, setbkmode这些函数在窗口上输出文字,

最后过了一定时间就切换到流星雨。

四.下面是具体的代码,我们遵循模块化编程的思想,将一定功能的代码封装成一个函数
#include<iostream>
#include<easyx.h>
#include<conio.h>
#pragma comment(lib,"winmm.lib")
#define STAR_NUM 666
#define METEOR_NUM 128
#define WIDTH 1200//窗口宽度
#define HEIGHT 700//窗口高度
using namespace std;
IMAGE bk[2];//背景图片
IMAGE Meteor[2];//流星图片

class STAR
{
public:
    int x, y, r, speed, star_move_stay;
    COLORREF color;
    STAR()
    {
        x = rand() % WIDTH;
        y = rand() % HEIGHT;
        r = rand() % 1 + 1;
        speed = rand() % 4 + 1;
        color = RGB(rand() % 256, rand() % 256, rand() % 256);
        star_move_stay = 0;
    }
    void DrawStar()
    {
        setfillcolor(color);
        solidcircle(x, y, r);
        star_move_stay++;
    }
    void MoveStar()
    {
        star_move_stay = 0;
        x += speed;
        if (x > WIDTH)
            x = 0;
    }
}star[STAR_NUM];
class METEOR
{
public:
    int x, y, speed,meteor_move_stay;
    METEOR()
    {
        x = rand() % (WIDTH*2) - WIDTH;//-1200~1200
        y = 20 - 200;
        speed = rand() % 10 + 1;
    }
    void DrawMeteor()
    {
        putimage(x, y, &Meteor[rand() % 2], SRCPAINT);
        meteor_move_stay++;
    }
    void MoveMeteor()
    {
        meteor_move_stay = 0;
        x += speed;
        y += speed;
        if ((x >= WIDTH) || (y >= HEIGHT))
        {
            x = rand() % (2 * WIDTH) - WIDTH;//-1200~1200
            y = 20 - 200;
            speed = rand() % 15 + 1;
        }
    }
}meteor[METEOR_NUM];

void Init();
void Introduce();
void Move();

int main()
{
    initgraph(1200, 700);
    Init();
    Introduce();
    Move();
}

void Init()
{
    loadimage(&Meteor[0], "./star1.jpg", 50, 50);
    loadimage(&Meteor[1], "./star2.jpg", 50, 50);
    loadimage(&bk[0], "./bk.jpg", WIDTH, HEIGHT);
    loadimage(&bk[1], "./star_sky.jpeg", WIDTH, HEIGHT);
}
void Introduce()
{
    putimage(0, 0, &bk[0]);
    srand(time(0));
    setbkmode(TRANSPARENT);
    BeginBatchDraw();
    while (true)
    {
        settextstyle(200, 0, "宋体");
        settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
        outtextxy(200, 66, "新年快乐");
        settextstyle(100, 0, "宋体");
        settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
        outtextxy(66, 286, "让我们一起看场流星雨吧");
        settextstyle(88, 0, "宋体");
        settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
        outtextxy(888, 450, "-水镜Q");
        Sleep(500);
        if (clock() < 1000)
            outtextxy(128, 456, "6");
        else if ((clock() < 2000) && (clock() > 1000))
            outtextxy(208, 456, "5");
        else if ((clock() < 3000) && (clock() > 2000))
            outtextxy(288, 456, "4");
        else if ((clock() < 4000) && (clock() > 3000))
            outtextxy(368, 456, "3");
        else if ((clock() < 5000) && (clock() > 4000))
            outtextxy(448, 456, "2");
        else if ((clock() < 6000) && (clock() > 5000))
            outtextxy(528, 456, "1");
        else if (clock() > 6000)
            break;
        FlushBatchDraw();
    }
    EndBatchDraw();
}
void Move()
{
    BeginBatchDraw();
        while (!_kbhit())
        {//任意键结束
            cleardevice();
            putimage(0, 0, &bk[1]);
            for (size_t i = 0; i < STAR_NUM; i++)
            {
                star[i].DrawStar();
                if (star[i].star_move_stay >= 5)
                    star[i].MoveStar();
            }
            for (size_t i = 0; i < METEOR_NUM; i++)
            {
                meteor[i].DrawMeteor();
                if (meteor[i].meteor_move_stay >= 5)
                    meteor[i].MoveMeteor();
            }
            FlushBatchDraw();
        }
        EndBatchDraw();
}

里面还可以加音乐,大家自己操作,最后祝大家新年快乐

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水镜Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值