后天就是老妈的生日了,我打算写一个简单的程序表白老妈子,来肉麻一下她。在实现的过程中,有不少我没学过的知识,这些知识我都会予以补充。
创建图形窗口
创建图形窗口要包头文件:
#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;
}