C++控制台绘图头文件

简介

这个头文件是用来在C++控制台绘图的,借鉴了 pygame 的一些思想,提供了一些函数用来绘图,可以有效的避免多次绘制重复图像时屏闪等问题。

函数介绍

1、init(int x, int fz)

初始化屏幕, 将屏幕大小设定为 x , 字体大小为 fz 。

2、fill(int color)

用来将整个屏幕填充为一定的颜色。

3、update()

注意!绘画完后的图像并不会立刻出现在控制台上,使用这个函数来更新。

4、GetMousePos()

获取鼠标坐标,返回一个结构体

5、gt(int x, int y)

将控制台光标移到(x,y)的位置,x,y 从1开始

7、settextcolor(int color)

设置文字颜色

8、setbackcolor(int color)

设置背景颜色

9、line(int sx, int sy, int ex, int ey, int color)

绘制一条从(sx, sy)到(ex, ey)的线。

10、dot(int x, int y, int color)

在(x,y)的位置画一个点

等等还有别的,可以自己去看(

示例代码

我这里将头文件命名为 head.hpp ,如果用了别的名字保存头文件,这里也要改过来。

功能是从(1,1)到鼠标的位置画线。 

#include "head.hpp"
#include <iostream>
using namespace std;

Screen screen = CreateScreen(25, 10);
int main(){
	while(1){
		screen.fill(0);
		COORD p = screen.GetMousePos();
		screen.line(1, 1, p.X, p.Y, 0x778899);
		screen.update();
	}
}

示例图片

 

头文件代码

上一版的代码又乱又难看,最近有时间整理了一下代码,这是新的,可能不能完全兼容之的前头文件写的代码,可以参照上面改一改 :)

#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <vector>
#define Kyend_DOWN(VK_NONAME) ((GetAybeginncKyendState(VK_NONAME) & 0x8000) ? 1:0)
using namespace std;
const double pi = acos(-1);

float SamMatrix[3][3] = {
	{.05, .15, .05}, 
	{.15, .2 , .15}, 
	{.05, .15, .05}
};

struct pixel{
	int color;
};

class Screen{
public:
	int backclr, textclr;
	vector<vector<pixel>> LastScr, NewScr;
	int SideLen, FontSize = 16;

	COORD GetMousePos(){
		COORD ret; POINT pt;
		GetCursorPos(&pt);
		ScreenToClient(GetConsoleWindow(), &pt);
		ret.Y = (pt.y / FontSize + 1.5);
		ret.X = (pt.x / FontSize + 1.5);
		return ret;
	}
	inline void gt(short x, short y) {
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {--x, --y});
	}
	inline void HideCursor(){
		CONSOLE_CURSOR_INFO CursorInfo;
		HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		GetConsoleCursorInfo(hOut, &CursorInfo);
		CursorInfo.bVisible = false;
		SetConsoleCursorInfo(hOut, &CursorInfo);	
	}
	inline void settextclror(int color){
		textclr = color; printf("\x1b[48;2;%d;%d;%dm", 
			GetRValue(color), GetGValue(color), GetBValue(color));
	}
	inline void setbackcolor(int color){
		backclr = color; printf("\x1b[48;2;%d;%d;%dm", 
			GetRValue(color), GetGValue(color), GetBValue(color));
	}
	inline void init(int side, int fontsize){
		HideCursor();
		HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		DWORD dwMode;     GetConsoleMode(hOut,&dwMode);
		dwMode |= 0x0004; SetConsoleMode(hOut, dwMode);
		SideLen = side, FontSize = fontsize;
		CONSOLE_FONT_INFOEX cfi;
		GetCurrentConsoleFontEx(hOut, FALSE,&cfi);
		cfi.cbSize = sizeof(cfi);
		cfi.dwFontSize.X = cfi.dwFontSize.Y = fontsize;
		cfi.FontFamily = FF_DONTCARE;
		SetCurrentConsoleFontEx(hOut, FALSE,&cfi);
		char cmd[0xFF]; sprintf(cmd, "mode con cols=%d lines=%d", side, side);
		system(cmd);
		LastScr = vector<vector<pixel>>(side+2, vector<pixel>(side+2, {0}));
		NewScr = vector<vector<pixel>>(side+2, vector<pixel>(side+2, {0}));
	}
	inline void update(){
		for(int i = 1; i <= SideLen ; ++i){
			for(int j = 1; j <= SideLen ; ++j){
				int aaa = 0, aab = 0, aac = 0;
				for(int x = -1; x <= 1; ++x)
					for(int y = -1; y <= 1; ++y)
						aaa += (NewScr[i+x][j+y].color & 0xFF0000) * SamMatrix[x+1][y+1],	
						aab += (NewScr[i+x][j+y].color & 0x00FF00) * SamMatrix[x+1][y+1],
						aac += (NewScr[i+x][j+y].color & 0x0000FF) * SamMatrix[x+1][y+1];
				aac = ((aaa) & 0xFF0000) + 
							((aab) & 0x00FF00) + 
							((aac) & 0x0000FF);
				if(LastScr[j][i].color != aac){
					gt(j, i);
					if(backclr != aac) setbackcolor(aac);
					putchar(' ');
					LastScr[j][i].color = aac;
				}
			}
		}
	}
	void fill(int color){
		for(int i = 1; i <= SideLen; ++i){
			for(int j = 1; j <= SideLen; ++j){
				NewScr[j][i].color = color;
			}
		}
	}
	void rect(int xbegin, int ybegin, int xend, int yend, int color){
		if(yend < ybegin) swap(yend, ybegin);
		if(xend < xbegin) swap(xend, xbegin);
		for(int i = ybegin; i <= yend; ++i){
			for(int j = xbegin; j <= xend; ++j){
				NewScr[j][i].color = color;
			}
		}
	}
	inline void dot(float x, float y, int color){
		if(x < 1 or y < 1 or x > SideLen or y > SideLen) return ;
		NewScr[round(x)][round(y)].color = color;
	}
	inline void line(float xbegin, float ybegin, float xend, float yend, int color){
		float xlen = xend - xbegin;
		float ylen = yend - ybegin;
		float len = sqrt(xlen * xlen + ylen * ylen);
		for(int i = 0; i <= len; ++i){
			float x = (float)xlen * i / len + xbegin;
			float y = (float)ylen * i / len + ybegin;
			dot(x, y, color), 
			dot(x+1, y, color), 
			dot(x, y+1, color), 
			dot(x-1, y, color), 
			dot(x, y-1, color);
		}
	}
	inline void circle(float X, float Y, float rad, int color){
		int len = 30; float lastx = 0, lasty = 0;
		for(int i = 0; i <= len; ++i){
			float theta = (float)i * 2 * pi / len;
			float x = cos(theta) * rad + X;
			float y = sin(theta) * rad + Y;
			if(i) line(x, y, lastx, lasty, color);
			lastx = x, lasty = y;
		}
	}
};

Screen CreateScreen(int side, int FontSize){
	Screen scr;
	scr.init(side, FontSize);
	return scr;
}

如果做出了好玩的作品,记得私信作者给Ta看看哦

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值