用C++写个简单的程序表白老妈

后天就是老妈的生日了,我打算写一个简单的程序表白老妈子,来肉麻一下她。在实现的过程中,有不少我没学过的知识,这些知识我都会予以补充。

创建图形窗口

创建图形窗口要包头文件:

#include<easyx.h>

这是简单的图形库,只要会写c语言就能用。

注意:只有先去官网下载这个图形库,再包才会生效!下载方法c站一搜就有。

包了这个图形库,我们以前运行程序出现的那个黑框窗口,就被图形窗口所取代了。

ok,现在要怎么创建图形窗口呢?用initgraph函数:初始化图形窗口。

#include<iostream>
#include<easyx.h>
​
int main() {
    initgraph(1000, 800);  //两个参数分别是 
    while(1)
    {}
    return 0;
}

这里的while(1){}只是为了让图形窗口停留,不然它会一闪而过。

创建出来的图形窗口:

🚩补充:initgraph函数

initgraph(w,h,f);

用于初始化图形窗口。

三个参数分别为: width 绘图环境的宽度 height 绘图环境高度 flag 绘图环境样式(可省略)

播放音乐

🚩这里要介绍一个用于播放音乐的函数mciSendString(),它是用来播放多媒体文件的API指令,可以播放mp3、wma、wav、mid等文件。

我先来介绍一下函数名,帮助大家理解。mci媒体控制接口:media control interface

mciSendString可以理解为:向mci发送命令字符串

它在使用时一般按这个格式写:

mciSendString("open XX.mp3",NULL,0,NULL);

如果这样写编译不过去,就用这个格式:

mciSendString(_T("open XX.mp3"),NULL,0,NULL);   //注意XX.mp3要写明它的路径

只需要记忆第一个参数,后面三个就按照格式的来。

第一个参数重点记忆三个:open、play、close,分别对应打开、播放、关闭。

使用mciSendString()前要包含头文件:#include<mmsystem.h>

并导入库:#pragma comment<lib."winmm.lib">

实现:

#include<iostream>
#include<easyx.h>
#include<mmsystem.h>  
#pragma comment(lib,"winmm.lib")  
​
void Display() {
    //播放背景音乐   
    mciSendString(_T("open ./source/别看我只是一只羊.mp3 alias bgm "), NULL,0, NULL);   //alias给文件取别名,叫bgm,便于后续操作
    mciSendString(_T("play bgm "), NULL, 0, NULL);
}
int main() {
    initgraph(1000, 800);
    Display(); 
    while(1)
    {}
    return 0;
}

输出文字

🚩补充:

1.设置字体样式settextstyle()

我们在vs下是能看到这个函数的参数的,分别为:高度、宽度、样式。

2.设置字体颜色settextcolor()

settextcolor(BLUE);  //将字体设为蓝色
settextcolor(RGB(223,234,100));   //自选字体颜色

如何自选字体颜色?

打开画图软件,选择你喜欢的颜色,然后记住这三个参数:

因为所有颜色都是由红绿蓝(RGB) 三原色合成的,所以输入这三个参数就可以合成对应的颜色。

3.输出文字outtextxy()

outtextxy()函数,可以这样理解:out text x y,在坐标(x,y)输出文本信息。它是C++中的一个绘图函数,可以在屏幕上输出文本信息。它使用起来也很简单:

void outtextxy(int x,int y,const char* str);  //前两个参数是坐标信息,第三个参数是要输出的文本

图形窗口中的坐标轴,原点在左上角,x轴向右,y轴向下。

实现:

void Display() {
    mciSendString(_T("open ./source/别看我只是一只羊.mp3 alias bgm "), NULL,0, NULL);
    mciSendString(_T("play bgm "), NULL, 0, NULL);
​
    //设置字体样式
    settextstyle(40, 20, _T("仿宋"));
    //设置颜色
    settextcolor(RGB(100,216,234));
    //输出文字
    outtextxy(50, 50, _T("妈妈,我是宝宝!"));
    outtextxy(50, 100, _T("明天就是你的生日了,"));
    outtextxy(50, 150, _T("祝你生日快乐!"));
    outtextxy(50, 200, _T("我写了首诗,献给你:"));
    outtextxy(50, 250, _T("“鹅鹅鹅,红掌拨清波”"));
}

emmmm,挺丑的。现在我们来把它变好看一点。

如何做出颜色闪动效果

刚刚的颜色太单调了,只有一种。我们想要的效果是,每过几秒,它就能随机变幻颜色。要想生成随机值,就用rand()。

让颜色随机

🚩生成随机数rand():

rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。

如果你要产生0~99这100个整数中的一个随机整数,可以表达为:int num = rand() %100; 这样,num的值就是一个0~99中的一个随机数了。

而RGB的参数值范围是0~255,所以就用rand()%256。

在用rand()的过程中,我遇到的几个问题:

1.连续生成的颜色都比较相近,不够随机!

这是因为没有设置种子。什么是种子?请听我说~

rand()产生的是 伪随机数,并不是真正的随机数。这个伪随机数 是根据种子推导得到的。

所谓种子,就是初值。打个比方,我给的初值是100,那这个100作为种子,推出的伪随机数是99。这个99再作为种子,推出的伪随机数是102。102再作为种子,……

现在,你能知道为啥rand()连续产生的数值都比较相近了吧!

只有初值变化,伪随机数才变。如果不涉及密码学,那用时间来当种子完全够了,因为时间是时时刻刻在变化的。

在rand()之前,用srand()播种:

srand((unsigned)time(NULL));   //用srand()设置种子,叫“播种”。以时间作为种子

但要注意:srand不能写在循环里,因为循环一次的时间间隔太短了,time十分相近,产生的种子就是相同的了。

srand写在循环外(前面),只设置一次就可以了。

对了,记得引头文件<time.h>

2.闪动得太快了!一秒变好几个颜色。

要想延迟,用Sleep()函数,注意S大写。

Sleep(1000);  //延迟1000ms

实现:

#include<iostream>
#include<easyx.h>
#include<time.h>
#include<mmsystem.h>   
#pragma comment(lib,"winmm.lib")  
​
void Display() {
    //每次循环开始前,要清屏
    cleardevice(); 
    //播放背景音乐  
    mciSendString(_T("open ./source/别看我只是一只羊.mp3 alias bgm "), NULL,0, NULL);
    mciSendString(_T("play bgm "), NULL, 0, NULL);
​
    //设置字体样式
    settextstyle(40, 29, _T("仿宋"));
    //设置文字颜色
    //srand((unsigned)time(NULL));
    settextcolor(RGB(rand()%256, rand() % 256, rand() % 256));
    //输出文字
    outtextxy(50, 50, _T("妈妈,我是宝宝!"));
    outtextxy(50, 100, _T("明天就是你的生日了,"));
    outtextxy(50, 150, _T("祝你生日快乐!"));
    outtextxy(50, 200, _T("我写了首诗,献给你:"));
    outtextxy(50, 250, _T("“鹅鹅鹅,红掌拨清波”"));
    //再插入点图案
    for (int i = 0; i < 8; i++) {      
        settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
        outtextxy(rand() % 1001, rand() % 651, _T("🤍"));
        outtextxy(rand() % 1001, rand() % 651, _T("🎈"));
    }
    Sleep(1000);
}
int main() {
    //创建图形窗口
    initgraph(1000, 650);
    srand((unsigned)time(NULL));
    while (1) {
        Display();
    }
    return 0;
}

让图案背景透明

但此时,我们会发现,字被图案遮挡了:

 

这是因为,图案的背景被填充上了颜色,这种颜色是不透明的。而此时我们希望透过图案背景看到下面的字。

这就需要我们在输出文字之前,设置背景为透明。

setbkmode函数(设置背景模式):

setbkmode(TRANSPARENT);

来看效果:

最终效果:

插入背景图

流程是这样的:

Step1.先创建一个IMAGE类型的数组,将你准备的几张背景图按个放进数组。

Step2.在Display函数中,选一张图片插入图形窗口。

🚩补充:

1.从图片文件获取图像loadimage

void loadimage(
IMAGE* p,     // 保存图像的 IMAGE 对象指针
LPCTSTR pImgFile,     // 图片文件名
int nWidth = 0,    // 图片的拉伸宽度
int nHeight = 0,     // 图片的拉伸高度
bool bResize = false     // 是否调整 IMAGE 的大小以适应图片
);

2.输出图像putimage(int left,int right,void*buf,int ops);

参数(left,top)为输出屏幕图像的左上角,即输出图像的起始位置。buf指向要输出的内存中图像。参数ops控制图像以何种方式输出到屏幕上(可省略)。

实现:

IMAGE img[2];   //创建全局的数组。注:IMAGE是一个类型
​
int main() {
    //创建图形窗口
    initgraph(1000, 650);
    //将图片放进数组
    loadimage(img, _T("./source/1.jpg"), 1000, 650);
    loadimage(img+1, _T("./source/2.png"), 1000, 650);
​
    //展示效果
    srand((unsigned)time(NULL));
    while (1) {
        Display();
    }
    return 0;
}
oid Display() {
    //每次循环开始前,要清屏
    cleardevice();
    //插入背景
    putimage(0, 0, img+1);
    //播放背景音乐 
    mciSendString(_T("open ./source/别看我只是一只羊.mp3 alias bgm "), NULL,0, NULL);
    mciSendString(_T("play bgm "), NULL, 0, NULL);
    ……
}

效果:

如果没看到效果,那可能是你图片的格式不行,我一开始那张图是.webp,不行。后来改属性变成.jpg或者.png,就可以了。

按任意键退出

为了展示效果,我们当前把程序写成了死循环。现在,我要达到 按任意键就能退出页面 的效果。这要用到函数_kbhit()。

包头文件:

#include<conio.h>

_kbhit()是用来检测有没有按键的,没有按键返回假。

那我们这样写,就可以让程序顺利运行,按键退出:

int main() {
    //创建图形窗口
    initgraph(1000, 650);
    //将图片放进数组
    loadimage(img, _T("./source/1.jpg"), 1000, 650);
    loadimage(img+1, _T("./source/2.png"), 1000, 650);
​
    //展示效果
    srand((unsigned)time(NULL));
    while (!_kbhit()) {     //没有按键返回真
        Display();
    }
    return 0;
}

那么最终效果呈现为:

(此处有bgm)

总代码

#include<iostream>
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<mmsystem.h>   
#pragma comment(lib,"winmm.lib")  
​
IMAGE img[2];
​
void Display() {
    //每次循环开始前,要清屏
    cleardevice();
    //插入背景
    putimage(0, 0, img+1);
    //播放背景音乐 
    mciSendString(_T("open ./source/别看我只是一只羊.mp3 alias bgm "), NULL,0, NULL);
    mciSendString(_T("play bgm "), NULL, 0, NULL);
​
    //设置字体样式
    settextstyle(40, 29, _T("仿宋"));
    //设置文字颜色
    settextcolor(RGB(rand()%256, rand() % 256, rand() % 256));
    //设置背景为透明
    setbkmode(TRANSPARENT);
    //输出文字
    outtextxy(50, 50, _T("妈妈,我是宝宝!"));
    outtextxy(50, 100, _T("明天就是你的生日了,"));
    outtextxy(50, 150, _T("祝你生日快乐!"));
    outtextxy(50, 200, _T("我写了首诗,献给你:"));
    outtextxy(50, 250, _T("“鹅鹅鹅,红掌拨清波”"));
​
    for (int i = 0; i < 8; i++) {
        settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));
        outtextxy(rand() % 1001, rand() % 651, _T("🤍"));
        outtextxy(rand() % 1001, rand() % 651, _T("🎈"));
    }
    Sleep(1000);
}
int main() {
    //创建图形窗口
    initgraph(1000, 650);
    //将图片放进数组
    loadimage(img, _T("./source/1.jpg"), 1000, 650);
    loadimage(img+1, _T("./source/2.png"), 1000, 650);
​
    //展示效果
    srand((unsigned)time(NULL));
    while (!_kbhit()) {
        Display();
    }
    return 0;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值