如果想要在windows控制台上制作一款软件,我们通常都想到用OpenGL或者
Qt 等等一些图形库新开窗口来导入图片。而提到windows的控制台窗口我们通常都是用来处理一些字符操作,而不是图形化。
然而其实控制台也可以构建2D引擎导入图片(虽然画质很渣)。
下面介绍如何从零构建一个winsdows控制台2D引擎。
首先将控制台的字符转化为像素点
第一步将控制台字符变小
我知道的将字符块变小的方法有两种
手动右键点击控制台窗口
遗憾的是这样调节字符,最小只能将字符调整到3个屏幕像素宽和7个屏幕像素高,并且手动调节非常的麻烦
代码调节
void SetCellSize(short length, short width, short thick) //thick range from 100~1000, 400 is normal while >400 is bold
{
CONSOLE_FONT_INFOEX fontInfo = { 0 };
GetCurrentConsoleFontEx(hout, FALSE, &fontInfo);
fontInfo.cbSize = sizeof(fontInfo);
fontInfo.dwFontSize = { length,width };
fontInfo.FontWeight = thick;//字体的重量
SetCurrentConsoleFontEx(hout, FALSE, &fontInfo);
}
其中length是字符块的长度,width是字符块的宽度。
我们可以通过
SetCellSize(1,1, 400);
来将字符块的大小设置为1*1
就这样将字符变小的操作就完成了。
第二步我们需要为像素点添加颜色
一般来说我们通常使用RGB(256,256,256)来描述字符的颜色
但是控制台窗口是做不到这么多种颜色混合的。
我们可以通过一种很巧妙的方式来模拟出许多种颜色。
首先介绍两个概念:前景色和后景色
#define FOREGROUND_BLUE 0x0001 // text color contains blue.
#define FOREGROUND_GREEN 0x0002 // text color contains green.
#define FOREGROUND_RED 0x0004 // text color contains red.
#define FOREGROUND_INTENSITY 0x0008 // text color is intensified.
#define BACKGROUND_BLUE 0x0010 // background color contains blue.
#define BACKGROUND_GREEN 0x0020 // background color contains green.
#define BACKGROUND_RED 0x0040 // background color contains red.
#define BACKGROUND_INTENSITY 0x0080 // background color is intensified.
前景色:控制台字符的颜色
SetConsoleTextAttribute(hout, FOREGROUND_RED);
cout << "redfeeffeeeee" << endl;
后景色:字符的背景
SetConsoleTextAttribute(hout, BACKGROUND_RED);
cout << "redfeeffeeeee" << endl;
思路如下:利用前景色和后景色的混合模拟RGB
其实控制台一共有16种前景色,16种后景色
{ COLOR3(0,0,0), NULL },
{ COLOR3(0.5f,0,0), FOREGROUND_RED },
{ COLOR3(0,0.5f,0), FOREGROUND_GREEN },
{ COLOR3(0,0,0.5f), FOREGROUND_BLUE },
{ COLOR3(0.5f,0.5f,0), FOREGROUND_RED | FOREGROUND_GREEN },
{ COLOR3(0,0.5f,0.5f), FOREGROUND_GREEN | FOREGROUND_BLUE },
{ COLOR3(0.5f,0,0.5f), FOREGROUND_RED | FOREGROUND_BLUE },
{ COLOR3(0.5f,0.5f,0.5f), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE },
{ COLOR3(1.0f,0,0), FOREGROUND_RED | FOREGROUND_INTENSITY },
{ COLOR3(0,1.0f,0), FOREGROUND_GREEN | FOREGROUND_INTENSITY },
{ COLOR3(0,0,1.0f), FOREGROUND_BLUE | FOREGROUND_INTENSITY },
{ COLOR3(0,1.0f,1.0f), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
{ COLOR3(1.0f,0,1.0f), FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
{ COLOR3(1.0f,1.0f,0), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY },
{ COLOR3(1.0f,1.0f,1.0f), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
{ COLOR3(0,0,0), NULL },
{ COLOR3(0.5f,0,0), BACKGROUND_RED },
{ COLOR3(0,0.5f,0), BACKGROUND_GREEN },
{ COLOR3(0,0,0.5f), BACKGROUND_BLUE },
{ COLOR3(0.5f,0.5f,0), BACKGROUND_RED | BACKGROUND_GREEN },
{ COLOR3(0,0.5f,0.5f), BACKGROUND_GREEN | BACKGROUND_BLUE },
{ COLOR3(0.5f,0,0.5f), BACKGROUND_RED | BACKGROUND_BLUE },
{ COLOR3(0.5f,0.5f,0.5f), BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE },
{ COLOR3(1.0f,0,0), BACKGROUND_RED | BACKGROUND_INTENSITY },
{ COLOR3(0,1.0f,0), BACKGROUND_GREEN | BACKGROUND_INTENSITY },
{ COLOR3(0,0,1.0f), BACKGROUND_BLUE | BACKGROUND_INTENSITY },
{ COLOR3(0,1.0f,1.0f), BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY },
{ COLOR3(1.0f,0,1.0f), BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY },
{ COLOR3(1.0f,1.0f,0), BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY },
{ COLOR3(1.0f,1.0f,1.0f), BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY },
那么如何将前景色和后景色结合起来呢?
我们其实可以控制字符占整个像素块的大小。
char byte[] ={ ' ', '.' , '=' ,'&' ,'#' ,'@'};
例如 ’ ’ 前景色占比为0,’@'前景色占比为1,我们可以通过控制字符的大小来控制前景色的比例。
就这样我们制作了一个
16
∗
16
∗
6
16*16*6
16∗16∗6的一个控制台调色板了。