目录
文章目录
前言
EasyX 是针对 C/C++ 的图形库,可以帮助使用C/C++语言的程序员快速上手图形和游戏编程。
比如,可以用 VC + EasyX 很快的用几何图形画一个房子,或者一辆移动的小车,可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏,可以练习图形学的各种算法,等等。
一、操作集合
1.头文件
代码如下:
#include<stdio.h>
//包含图形库头文件
#include<graphics.h>
#include<conio.h> //使用getch()
#include<mmsystem.h> //包含多媒体设备接口头文件
#pragma comment(lib,"winmm.lib")//加载静态库
2.BGM函数
代码如下:
void BGM()
{
//打开音乐
mciSendString("open MP3文件路径 alis BGM",0,0,0);//alis取别名
mciSendString("play BGM repeat",0,0,0);//repeat循环播放
if(0)//关闭音乐
{
mciSendString("close BGM",0,0,0);
}
}
3.获取句柄与设置窗口标题
代码如下:
void change()
{
HWND hnd=GetHWnd();//获取句柄
SetWindowsText(hnd,"easyx");//设置窗口标题
int isok=MessageBox(hnd,"多喝烧碱","提示",MB_OKCANCEL);
if(isok==IDOK){
printf("你点击了ok\n");
}else if(IDCANCEL==isok){
printf("你点击了取消\n");
}
}
MessageBox(窗口句柄,窗口文本,窗口标题,窗口按钮);
如果窗口句柄选择了NULL,那么就可以与图像窗口同时运行,不存在优先级;
但是选择了窗口句柄,那么就强制性先完成弹窗信息才能返回图像窗口进行下一步操作;
窗口按钮则是确实或者取消,有不同模式进行调用选择;
4.窗口操作,图形操作,绘制文字,输出图片
代码如下:
//创建一个窗口,确定窗口大小,类型(默认为NULL)
initgraph(640,480,NOMINIMIZE | NOCLOSE | SHOWCONSOLE);
closegraph()//关闭绘图窗口 cleardevice()//清空绘图设备
//两步设置背景颜色
setbkcolor(WHITE);//第一步且设置为白色
cleardevice();//清屏
//画画
setlinestyle(PS_SOLID,5);//设置线条样式为实心且大小为5
setfillcolor(YELLOW);//设置填充颜色
setlinecolor(BLUE);//设置线条颜色
circle(50,50,50);
fillcircle(50,150,50);
soildcircle(50,250,50);
cicle 画圆 ellipse 画椭圆 pie 画扇形 polygon 画多边形 rectangle 画矩形
roundrect 画圆角矩形 line 画线 putpixel 画点
circle() 无填充 fillcircle() 有边框填充 solidcircle() 无边框填充
设置填充颜色setfillcolor(颜色) 设置线条颜色 setlinecolor(BLUE) 设置线条样式setlinestyle(高度,宽度,字体)
以画圆为例:void circle(int x,int y,int r);需要提供圆心坐标,及其半径;
1.无填充仅仅只会显示一个圆形边框;
2.有边框填充,边框里面可以有颜色实心圆;
3.无边框填充,只有实心圆没用边框;
其他图形同理加前缀就好了
文字绘制函数用于在窗口绘制文字
int set()
{
settextcolor(RED);//设置文字颜色为红色
settextstyle(20,0,"楷体");//设置文字样式,大小,字体
setbkmode(TRANSPARENT);//设置背景模式 trans parent 透明
outtxtxy(50,50,"我好喜欢你");//打印文字
//outtextxy(int x,int y,LPCTSTR str);在指定位置输出字符串
//settextcolor(COLORREF color);设置当前文字颜色
//settextstyle(int nHeight,int nWidth,LPCTSTR lpszFace)设置字体样式
//nHeight指定高度 nWidth字符的平均宽度,如果为0,则比列自适应 lpszFace字体名称
//textheight(LPCTSTR str);获取字符串实际占用的像素高度
//textwidth(LPCTSTR str);获取字符串实际占用的像素宽度
//把文字居中操作
fillrectangle(200,50,500,100);//宽度 300 高度50
settextcolor(RGB(173,0,13));
char arr[]="居中显示";
int width=300/2-textwidth(arr)/2;
int height=50/2-textheight(arr)/2;
outtextxy(width+200,height+50,arr);
}
输出图片
IMAGE img;//定义一个(变量)对象
//加载图片
//相对路径:./表示当前文件下,../当前文件的上一级目录 ./00.jpg
//绝对路径:C:\Users\Administrator\Desktop\10 EaxyX图形编程\easyx基础\easyx基础\oo.jpg
//loadimage(&img,"C:\\Users\\Administrator\\Desktop\\\"10 EaxyX图形编程\"\\easyx基础\\easyx基础\oo.jpg");
loadimage(&img, "./oo.jpg", 250, 250);
putimage(0, 0, &img);
getchar();
closegraph();
/*loadimage(IMAGE* pDstlmg,LPCTSTR plmgFile,int nWidth=0,int nHeight=0,bool bResize=false)
pDstlmg 保存图像的IMAGE对象指针 plmgFile 图片文件名 nWidth 图片的拉伸宽度
nHeight 图片的拉伸高度 bResize 是否调整IMAGE的大小适应图片
putimage(int dstX,int dstY,IMAGE *pSrclmg,DWORD dwRop=SRCCOPY);在当前设备上绘制指定图像
dstX 绘制位置x坐标 dstY 绘制位置y坐标 pSrclmg 要绘制的IMAGE对象指针
dwRop=SRCCOPY 三元光栅操作码*/
5.鼠标信息1.0
鼠标消息需要使用MOUSEMSG类型 比如:MOUSEMSG msg;
用MousHit()判断是否有鼠标消息(左键,右键,中间,移动)
如果有鼠标消息就可以接受鼠标消息msg=GetMouseMsg();
鼠标消息的主要成员:uMsg;当前鼠标信息 x;当前鼠标x坐标 y;当前鼠标y坐标
uMsg可以用来判断当前鼠标信息是什么信息:WM_LBUTTONDOWN鼠标左键信息
WM_RBUTTONDOWM鼠标右键信息
while(1)
{
if(MouseHit())
{
MOUSEMSG msg=GetMouseMsg();
//printf("鼠标坐标(%d %d)",msg.x,msg.y);在控制台显示鼠标坐标位置
//消息分发
swith(msg.uMsg){
case WM_LBUTTONDOWN:
if (msg.x > 200 && msg.x < 500 && msg.y>50 && msg.y < 100)
{
printf("阿巴阿巴\n");
}
outtextxy(400, 400, "鼠标左键按下");
printf("zuobiao1(%d,%d)\n", msg.x, msg.y);
break;
case WM_RBUTTONDOWN:
if (msg.x > 200 && msg.x < 500 && msg.y>50 && msg.y < 100)
{
printf("阿布阿布\n");
}
outtextxy(400, 400, "鼠标右键按下");
printf("坐标(%d,%d)\n", msg.x, msg.y);
break;
}
}
}
6.鼠标消息2.0
初始化调用文件头不再使用#include<graphics.h>,选择调用#include<easyx.h>,这存在版本里面封装函数的区别,grahpics里面的函数比较老;
2.0鼠标结构体数据类型名为ExMessage,这是eastx头文件定义的结构体:
#include<stdio.h>
#include<easyx.h>
void button(int x,int y,int w,int h,const char*text)
{
setbkmode(TRANSPARENT);
setfillcolor(BROWN);
fillroundrect(x,y,x+w,y+h,10,10);
settextstyle(30,0,"黑体");
char text_[50]="button";
strcpy(text_,text);
int tx=x+(w-textwidth(text))/2;
int ty=y+(h-textheight(text))/2;
outtextxy(tx,ty,text);
}
int main()
{
initgraph(640,480,EW_SHOWCONSOLE);
button(50,50,150,50,"按钮");
ExMessage msg; //ExMessage替代MOUSEMSG,不过范围更大
while(true)
{
if(peekmessage(&msg,EM_MOUSE)) //有鼠标消息返回ture没有返回false
{
switch(msg.message)
{
case WM_LBUTTONDOWN:
if (msg.x>=50&&msg.x<=50+150&&msg.y>=50&&msg.y<=50+50)
{
printf("我是按钮,我被点击了\n");
}
break;
default:
break;
}
}
}
}
7.键盘操作与物体移动1.0
用于获取鼠标消息的函数有两个:1.getch(); 需要头文件conio.h
2.GetAsyncKeyState(键值); 需要头文件windows.h ,但是由于EasyX包含windows头文件,所以无需自己包含(其他需要windows头文件的函数也一样,但是需要在graphics.h下方包括:比如播放音乐的头文件mmsystem.h)
getch(); 需要使用返回值来判断:1.与非ASCII表字符的按键比较,需要使用虚拟按键{ 上:72 下 : 80 左 : 75 右 : 77 } 2.如果是与字母比较直接写字母,比如'A'
GetAsyncKeyState(键值);需要传入一个键值,如果按下返回真{上:VK_UP 下:VK_DOWN 左:VK_LEFT 右:VK_RIGHT }
使用_getch();接受键盘读入值;后续在case里面放入要变化的逻辑,在这里就举一个wasd移动的例子://_getch();是一个阻塞函数;如果不输入就一直死卡那里。
while(1)
{
char key=_getch();
printf("%d,%c\n",key,key);
switch(key)
{
case 72;
case 'w';
casw 'W';
printf("上键\n");
break;
case 80;
case 's';
casw 'S';
printf("下键\n");
break;
case 75;
case 'a';
casw 'A';
printf("左键\n");
break;
case 77;
case 'd';
casw 'D';
printf("右键\n");
break;
}
}
可以添加图形,并改变图形位置重新打印实现移动操作;这里画一个实心边框圆为例子:
setfillcolor(BROWN);
fillcircle(x, y, 20);
if (_kbhit()) //判断有没有键盘按下
{
char key = _getch(); //阻塞函数,不输入一直呆在这里
printf("%d,%c\n", key, key);
switch (key)
{
case 72:
case 'w':
case 'W':
y -= 5;
printf("上键\n");
break;
case 80:
case 's':
case 'S':
y += 5;
printf("下键\n");
break;
case 75:
case 'a':
case 'A':
x -= 5;
printf("左键\n");
break;
case 77:
case 'd':
case 'D':
x += 5;
printf("右键\n");
break;
}
在控制台输入wasd就会实现移动,但是移动存在移动痕迹,因为我们的移动只是每次进行位置打印,如果不想看见上一次打印痕迹就要在循环开始增加一个cleardevice();函数每次进行清屏重新打印;但是清屏会把之前所有打印操作都清除,想保留之前的操作那么循环的开始就得在最开始打印进行循坏;
这种操作只是利用计算机运行速度快,产生的视觉效果,人们看不见被清除,再重新打印,只能看见重新打印后的画面,所以也会出现bug,插入图片,在图片上移动 清屏打印是会出现闪屏的情况的,要避免闪屏看接下来的操作:
BeginBatchDraw();开始批量生产 中间放置绘图代码 EndBatchDraw();结束批量绘图
这样循坏图片就不会出现闪屏效果,消除闪屏效果;
原理:不使用函数是直接在图像窗口进行刷新打印,每一步都立即完成立即刷新,但是使用完函数后是在一个缓冲区内部进行图像的绘画,无论你进行什么操作,进行多少次操作都没关系,都不会体现在图像窗口中,只有缓冲区图像绘画完成再一次性打印到图像窗口,所以就避免了频繁闪屏的情况
我们只需要在if语句前面加上EndBatchDraw();在·main绘画之前加上BeginBatchDraw();就可以了。
8.键盘操作与物体移动操作2.0
只需要把1.0中的if语句改成如下代码即可:
if(GetAsyncKeyState(VK_UP))
{
y-=5;
}
if(GetAsyncKeyState(VK_DOWN))
{
y+=5;
}
if(GetAsyncKeyState(VK_LEFT))
{
x-=5;
}
if(GetAsyncKeyState(VK_RIGHT))
{
x+=5;
}
总结
easyx是一个不错的工具帮助我们的项目跳出了控制台的单调无味