前言
你是否有这样的想法,把图片到入进c++里,亦或者能实时根据你发出的信息而做出回应的程序,graphics.h这个库完美满足了你的需求,那今天作者就给大家介绍一下这个库,并做一些运用。
何为graphics.h?
graphics.h是一个库,但一般的c++编译器中不含有,想要下载需要去easyx.
graphics.h基础语法
此库中含有的内容众多,此下分开介绍
绘图相关
绘图窗口
想要在graphics.h大显身手,一个输出工具是必须的,不同于只会输出字符的终端,绘图窗口顾名思义可以进行绘图,下面介绍两个函数关于绘图窗口:
initgraph
此函数可以新建一个绘图窗口,具体格式以下代码
HWND initgraph(
int width,
int height,
int flag = NULL//可省
);
width
绘图窗口的宽度。
height
绘图窗口的高度。
flag对于初学者来说不太能用上,这里不在赘述。
示例:
initgraph(114,514);
//此代码创建出了一个宽为114,高为514的绘图窗口
cleardevice
此函数的功能类似于清空当前绘图窗口,具体格式如下:
void cleardeice();
示例:
cleardeice();
//清空
图形绘制
接下来会给一张表,为重要的函数
函数 | 描述 |
---|---|
circle | 画无填充的圆 |
ellipse | 画无填充的椭圆 |
line | 画直线 |
pie | 画无填充的扇形 |
rectangle | 画无填充的矩形 |
soildcircle | 画填充圆 |
solidellipse | 画填充椭圆 |
solidpie | 画填充扇形 |
solidrectangle | 画填充矩形 |
solid/circle
格式:
void circle(
int x,
int y,
int radius
);
x
圆心的x坐标。
y
圆心的y坐标。
radius
圆的半径
solid/ellipse
格式:
void ellipse(
int left,
int top,
int right,
int bottom
);
left
椭圆外切矩形的左上角 x 坐标。
top
椭圆外切矩形的左上角 y 坐标。
right
椭圆外切矩形的右下角 x 坐标。
bottom
椭圆外切矩形的右下角 y 坐标。
line
格式:
void line(
int x1,
int y1,
int x2,
int y2
);
x1
直线的起始点的 x 坐标。
y1
直线的起始点的 y 坐标。
x2
直线的终止点的 x 坐标。
y2
直线的终止点的 y 坐标。
solid/rectangle
格式
void rectangle(
int left,
int top,
int right,
int bottom
);
left
矩形左部 x 坐标。
top
矩形顶部 y 坐标。
right
矩形右部 x 坐标。
bottom
矩形底部 y 坐标。
soild/pie
格式:
void pie(
int left,
int top,
int right,
int bottom,
double stangle,
double endangle
);
left
扇形所在椭圆的外切矩形的左上角 x 坐标。
top
扇形所在椭圆的外切矩形的左上角 y 坐标。
right
扇形所在椭圆的外切矩形的右下角 x 坐标。
bottom
扇形所在椭圆的外切矩形的右下角 y 坐标。
stangle
扇形的起始角的弧度。
endangle
扇形的终止角的弧度。
图片处理
图片处理是这个库中的重头戏,也正是他十分出名的原因,接下来我来为大家介绍
IMAGE
在c++中有许多数据类型,证书有int,long long,等等,浮点数有float,double,字符有char,布尔有bool,图片当然也要有他的数据类型,那就是IMAGE,注意不要忘记大写
格式:
class IMAGE(int width = 0, int height = 0);
int getwidth();
返回 IMAGE 对象的宽度,以像素为单位。
int getheight();
返回 IMAGE 对象的高度,以像素为单位。
loadimage
有了定义,没有输入怎么行呢,此函数的功能就类似于此,但不需要自己手动输入,而是输入文件地址,自动加载
格式:
void loadimage(
IMAGE* pDstImg, // 保存图像的 IMAGE 对象指针
LPCTSTR pImgFile, // 图片文件名
int nWidth = 0, // 图片的拉伸宽度,可省
int nHeight = 0, // 图片的拉伸高度,可省
bool bResize = false // 是否调整 IMAGE 的大小以适应图片,可省
);
pDstImg
保存图像的 IMAGE 对象指针。如果为 NULL,表示图片将读取至绘图窗口。
pImgFile
图片文件名。支持 bmp / gif / jpg / png / tif / emf / wmf / ico 格式的图片。
nWidth
图片的拉伸宽度。加载图片后,会拉伸至该宽度。如果为 0,表示使用原图的宽度。
nHeight
图片的拉伸高度。加载图片后,会拉伸至该高度。如果为 0,表示使用原图的高度。
bResize
是否调整 IMAGE 的大小以适应图片。
举个例子:
IMAGE img1;
loadimage(&img1, _T("test.jpg"));
这是定义完后,从test.jpg加载图片
putimage
有了输入,没有输出怎么能行呢?
格式:
void putimage(
int dstX, // 绘制位置的 x 坐标
int dstY, // 绘制位置的 y 坐标
IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针
DWORD dwRop = SRCCOPY // 三元光栅操作码,可省
);
举个例子
initgraph(500,500);
IMAGE img1;
loadimage(&img1, _T("test.jpg"));
putimage(300,300,&img);
这是创建窗口后,进行加载图片后,又将图片输出在300,300位置
消息处理
你有没有想过用代码编写一个小游戏,但苦于不能动态接受信息,这个模块将完美解决你的问题
ExMessage
这个类跟int一样是一个数据结构用来存储消息,例如鼠标的敲击或移动
格式:
struct ExMessage
{
USHORT message; // 消息标识
union
{
// 鼠标消息的数据
struct
{
bool ctrl :1; // Ctrl 键是否按下
bool shift :1; // Shift 键是否按下
bool lbutton :1; // 鼠标左键是否按下
bool mbutton :1; // 鼠标中键是否按下
bool rbutton :1; // 鼠标右键
short x; // 鼠标的 x 坐标
short y; // 鼠标的 y 坐标
short wheel; // 鼠标滚轮滚动值,为 120 的倍数
};
// 按键消息的数据
struct
{
BYTE vkcode; // 按键的虚拟键码
BYTE scancode; // 按键的扫描码(依赖于 OEM)
bool extended :1; // 按键是否是扩展键
bool prevdown :1; // 按键的前一个状态是否按下
};
// 字符消息的数据
TCHAR ch;
// 窗口消息的数据
struct
{
WPARAM wParam;
LPARAM lParam;
};
};
};
大家不要害怕有一大堆,其实真正用到的没几个(喜)
peekmessage
此函数的作用类似cin,但是他是类似动态的,输入消息的
bool peekmessage(ExMessage *msg, BYTE filter = -1//可省, bool removemsg = true//可省);
msg
指向消息结构体 ExMessage 的指针,用来保存获取到的消息。
filter
指定要获取的消息范围,默认 -1 获取所有类别的消息。可以用以下值或值的组合获取指定类别的消息:
EX_MOUSE 鼠标消息。
EX_KEY 按键消息。
EX_CHAR 字符消息。
EX_WINDOW 窗口消息。
removemsg
在 peekmessage 处理完消息后,是否将其从消息队列中移除。
举个例子
ExMessage msg;
while (peekmessage(&msg))//获得消息
{
if (msg.message == WM_KEYDOWN)//判断消息是否是由键盘发出
{
switch (msg.vkcode)//如果是方向键
{
case VK_UP://上
//具体行动
case VK_DOWN://下
//具体行动
case VK_LEFT://左
//具体行动
case VK_RIGHT://右
//具体行动
}
}
}
此代码实现了一个简单的小程序,通过动态输入而做出具体行动。
自己做的小游戏
很简陋,只能进行基础的移动,但经历了很多的优化
#include <graphics.h>
#include <Windows.h>
#include <string>
#include <iostream>
const int player_zs = 3;
const int player_vis = 3;
int dqzsy = 0;
IMAGE player_right[player_zs];
POINT player_pos = { 500,500 };
#pragma comment(lib,"MSIMG32.LIB")
inline void putimgage_alpha(int x, int y, IMAGE* img)
{
int w = img->getwidth();
int h = img->getheight();
AlphaBlend(GetImageHDC(NULL), x, y, w, h,
GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,255,AC_SRC_ALPHA });
}
void loadimg()
{
for (size_t i = 0; i < player_zs; i++)
{
std::wstring path = L"img/player_right_" + std::to_wstring(i) + L".png";
loadimage(&player_right[i], path.c_str());
}
}
int main()
{
std::cout << "由aqzjklo制作的小游戏" << std::endl;
system("pause");
std::cout << "感谢游玩,祝你有一个美好的一天";
initgraph(1280, 720);
bool running = true;
ExMessage msg;
IMAGE background;
bool moveup = 0, movedown = 0, moveright = 0, moveleft = 0;
loadimage(&background, _T("img/background.png"));
loadimg();
BeginBatchDraw();
while (running)
{
DWORD start_time = GetTickCount();
while (peekmessage(&msg))
{
if (msg.message == WM_KEYDOWN)
{
switch (msg.vkcode)
{
case VK_UP:
moveup = 1;
break;
case VK_DOWN:
movedown = 1;
break;
case VK_LEFT:
moveleft = 1;
break;
case VK_RIGHT:
moveright = 1;
break;
}
}
else if (msg.message == WM_KEYUP)
{
switch (msg.vkcode)
{
case VK_UP:
moveup = 0;
break;
case VK_DOWN:
movedown = 0;
break;
case VK_LEFT:
moveleft = 0;
break;
case VK_RIGHT:
moveright = 0;
break;
}
}
}
if (moveup)
{
player_pos.y -= player_vis;
}
if (movedown)
{
player_pos.y += player_vis;
}
if (moveleft)
{
player_pos.x -= player_vis;
}
if (moveright)
{
player_pos.x += player_vis;
}
static int counter = 0;
if (++counter % (player_zs-1) == 0)
{
dqzsy++;
}
dqzsy = dqzsy % player_zs;
cleardevice();
putimage(0, 0, &background);
putimgage_alpha(player_pos.x, player_pos.y, &player_right[dqzsy]);
FlushBatchDraw();
DWORD end_time = GetTickCount() - start_time;
if (end_time < 1000 / 60) Sleep(1000 / 60 - end_time);
}
EndBatchDraw();
}
后记
最后希望此帖子能对大家有一些帮助,谢谢
标签:int,IMAGE,bool,坐标,graphics,矩形,图片 From: https://blog.csdn.net/aqzjklo/article/details/141200565