前言:
许多人学习编程都是从c语言入门的,但目前现状是:
1.Easyx库
首先Easyx是针对C++的图形库,可以帮组C/C++初学者快速上手图形和游戏编程,比如可以基于Easyx图形库画一个房子,或者一辆移动 的小车,可以编程俄罗斯方块,贪吃蛇,和白棋等小游戏。详情见文档链接Easyx帮助文档
基于Windows图形编程,将Windows下的复杂程序过程进行封装,将windows下的编程过程隐藏,给用户提供一个简单熟悉的接口(函数),用户对于图像库中函数的调用,最终都会由Windows的底层API(函数)实现。
void initgraph(int width,int height,int flag=NULL)
1. width指创建窗口的宽度
2.height指创建窗口的高度
3.flag指创建窗口的样式,默认为NULL
#define SHOWCONSOLE 1 // 创建图形窗口时,保留控制台的显示
#define NOCLOSE 2 // 没有关闭功能
#define NOMINIMIZE 4 // 没有最小化功能
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(1024,480);
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
需要注意的是此时的窗口没有滚动条,也就是说该窗口不是控制台,而是由窗口创建函数创建的一个绘制窗口( •̀ ω •́ )✧
此函数是与窗口创建函数搭配使用的函数,关闭窗口
void circle(int x,int y,int R)
x是纵坐标,y是横坐标,R是圆的半径(窗口原点坐标默认为在左上角)
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(640, 480);
//例如画一个原点在(50.50),半径为50的圆
circle(50,50,50);
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
与上一个函数用法一致,但圆有边框填充
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(640, 480);
//例如画一个原点在(50.50),半径为50的圆
setfillcolor(YELLOW);//圆的填充颜色函数
setlinecolor(BLUE);//边框线条颜色函数
setlinestyle(PS_SOLID, 10);//边框线条形式函数
//circle(50,50,50); //无填充
fillcircle(50, 50, 50);//有边框填充
//solidcircle(50, 250, 50);//无边框填充
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
与上一个函数用法一致,但圆无边框填充
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(640, 480);
//例如画一个原点在(50.50),半径为50的圆
setfillcolor(YELLOW);//圆的填充颜色函数
setlinecolor(BLUE);//边框线条颜色函数
setlinestyle(PS_SOLID, 10);//边框线条形式函数
//circle(50,50,50); //无填充
//fillcircle(50, 50, 50);//有边框填充
solidcircle(50, 50, 50);//无边框填充
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400,480);
setbkcolor(RED);
cleardevice();
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
***正如上方setbkcolor()函数的用法,cleardevice()函数必须在设置完新的背景颜色后才清楚上一个背景颜色***
void outtextxy(int x,int y,char*str);
(x,y)窗口坐标,str为要输入的字符数组名或字符串
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480);
outtextxy(100, 100,L"我是帅比");
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
注意:为什么要在字符串前面加一个L呢?,其实是由于字符集导致的,解决方案就是在字符串前面加上L,或者在项目->属性->常规->字符集改为多字符集即可。
还有一个问题就是有的小伙伴认为既然是输出字符串那为什么不直接scanf函数打印呢,原因其实是有的同学在这里把控制台和这里的项目窗口搞混淆了,scanf函数的字符串输出只能打印在控制台窗口上,而项目窗口是不能直接用scanf函数读入,并用printf函数打印的
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480,NOMINIMIZE);
settextcolor(RED);//设置文字颜色
outtextxy(100, 100,L"我是帅比");//指定位置打印字符串
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
void settextstyle(int nHeight,int nWidth,LPCTSTR lpszFace);
nHeight 指定高度(逻辑单位)
nWidth 字符的平均宽度(逻辑单位)。如果为 0,则比例自适应
lpszFace字体名称。
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480,NOMINIMIZE);
settextstyle(20,0,L"楷体");//设置字体形式(高度,宽度,字体)
setbkmode(TRANSPARENT);//考虑到文字背景也有默认颜色,可能发生遮挡,所以将文字背景改为透明
outtextxy(100, 100,L"我是帅比");//指定位置打印字符串
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
注意:区分这里的文字背景透明的setbkmode函数与上方讲窗口背景颜色设置中的cleardevice函数的区别
计算字符串的像素高度
计算字符串的像素宽度
***与前面直接使用的函数不同的是:在使用图像之前,需要定义一个变量,然后把图片加载进变量才能使用。Easyx为我们提供了了变量类型IMAGE,如IMAGE img。***
// 从资源文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
IMAGE* pDstImg, // 保存图像的 IMAGE 对象指针
LPCTSTR pResType, // 资源类型
LPCTSTR pResName, // 资源名称
int nWidth = 0, // 图片的拉伸宽度
int nHeight = 0, // 图片的拉伸高度
bool bResize = false // 是否调整 IMAGE 的大小以适应图片
);
// 绘制图像(指定宽高和起始位置)
void putimage(
int dstX, // 绘制位置的 x 坐标
int dstY, // 绘制位置的 y 坐标
int dstWidth, // 绘制的宽度
int dstHeight, // 绘制的高度
IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针
int srcX, // 绘制内容在 IMAGE 对象中的左上角 x 坐标
int srcY, // 绘制内容在 IMAGE 对象中的左上角 y 坐标
DWORD dwRop = SRCCOPY // 三元光栅操作码
);
//两函数组合使用如下
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480,NOMINIMIZE);
IMAGE img;//创建一个加载图像的变量
loadimage(&img, "./mm.jpg",400,480);//加载图像
putimage(0, 0, &img);//在窗口中打印图像
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
***与窗口图像处理函数相同,在使用鼠标处理函数之前也要先定义一个鼠标信息结构体变量即类型为ExMessege,因为我们是初学者,所以先学习结构体中的成员变量,成员变量一message:其中包括(鼠标左键信息,鼠标右键信息,滚轮,),成员变量二,X:鼠标当前横坐标,成员变量三,Y:鼠标当前纵坐标***
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480, EW_SHOWCONSOLE);
solidcircle(0, 0, 50);//无边框填充画圆
while (true)
{
ExMessage msg = { 0 };
if (peekmessage(&msg, EM_MOUSE));//检测鼠标信息
{
switch (msg.message)//筛选鼠标信息类型
{
case WM_LBUTTONDOWN://左键信息
if (msg.x >= 0 && msg.x <= 50 && msg.y >= 0 && msg.y <= 50)
{
printf("左键激活\n");
}
break;
default:
break;
}
}
}
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
getch()函数需要引用头文件conio.h,GetAsyncKeyState(键值)需要引头文件windows.h,但是由于Easyx包含了windows.h,所以无需自己包含。
getch()需要使用返回值来判断
1. 与非ASCLL表字符的按键比较,需要使用虚拟键值(上:72,下:80,左:75,右:77)
2.如果是与字母比较直接写字母如‘A’
GetAsyncKeyState(键值):
1.需要传入一个键值,如果按下返回(上:VK_UP,下:VK_DOWN,左:VK_LEFT,右:VK_RIGHT)
为了防止控制物体移动打印时窗口发生频闪,我们可以使用双缓冲绘图避免频闪,即在绘画代码块前后分别加上FlushBatchDraw()和EndBatchDraw()
#include
#include
#include
//#include//包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480, EW_SHOWCONSOLE);
int x=50;
int y=50;
while (true)
{
cleardevice();//清除上一次绘画的图形防止发生重叠
solidcircle(x, y, 50);//无边框填充画圆
char input;
input=_getch();
switch (input)
{
//case 119:
case 'w':
case 'W':
y -= 3;
printf("向上移动\n");
break;
//case 115:
case 's':
case 'S':
y += 3;
printf("向下移动\n");
break;
//case 97:
case 'a':
case 'A':
x -= 3;
printf("向左移动\n");
break;
//case 100:
case 'd':
case 'D':
x += 3;
printf("向右移动\n");
break;
}
}
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
这里由于不能发本地视频,所以大家可以拷贝代码在vs上试一试,查看效果
如果你尝试之后就可以发现,这种方式只能让图形直线移动,并不能像游戏角色可以斜着移动,那我们紧接着学习下一个函数
#include
#include
//#include//包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(650, 650, EW_SHOWCONSOLE);
int x = 10;
int y = 10;
while (true)
{
FlushBatchDraw();
cleardevice();//清除上一次绘画的图形防止发生重叠
solidcircle(x, y, 10);//无边框填充画圆
EndBatchDraw();
if (GetAsyncKeyState(VK_UP))
{
y -= 1;
printf("向上运动");
}
if (GetAsyncKeyState(VK_DOWN))
{
y += 1;
printf("向下运动");
}
if (GetAsyncKeyState(VK_LEFT))
{
x -= 1;
printf("向左运动");
}
if (GetAsyncKeyState(VK_RIGHT))
{
x += 1;
printf("向右运动");
}
}
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
这里由于不能发本地视频,所以大家可以拷贝代码在vs上试一试,查看效果
如果你尝试之后就可以发现,这种方式不仅能让图形直线移动,还可以像游戏角色可以斜着移动,
***首先什么是消息框呢,我举个简单的例子,当我们在玩某个小游戏的过程中,游戏可能需要弹出一个承载是否继续或退出选项的消息框,这时我们就必须了解下列函数的联合使用***
#include
#include //包含图像库头文件,仅仅适用于C++
int main()
{
//创建一个窗口,initgraph();
initgraph(400, 480);
HWND hn = GetHWnd();//获取窗口句柄函数;
SetWindowText(hn, "冰墩墩");//修改窗口名字函数
MessageBox(hn, "我是消息框", "提示", MB_OKCANCEL);//消息框弹出设置函数
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
没有什么是一首音乐解决不了的,如果有的话,那就两首,接下来让我们为窗口配上动听的音乐吧
#include
#include
#include //包含多媒体设备接口头文件
#pragma comment(lib,"winmm.lib")//加载静态库
void BGM()
{
mciSendString("open ./纯音乐.mp3", 0, 0, 0);
mciSendString("play ./纯音乐.mp3", 0, 0, 0);
}
int main()
{
//创建一个窗口,initgraph();
initgraph(400,480);
BGM();
getchar();
//关闭窗口,closegraph();
closegraph();
return 0;
}
由于我的知识学习有限,其实跟前面的窗口图像设置有很多相似之处,在播放音乐环节这里就不解释了,如果大家感兴趣的话,就在这里查询
好啦恭喜你已经掌握了Easyx库的基本使用,快拿去让你的代码动起来吧