C++第五天

01. 动态数组的实现

tvector.h

#pragma once

#include <iostream>

// 编写类模板的时候,类的声明和函数的定义必须写在同一个文件中

// 命名空间: 解决作用域的二义性问题
namespace S
{
	// 动态数组类: 内部维护了一个可以动态增长的[数组]
	template <class T>
	class tvector
	{
	private:
		// 一个指针,指向了保存数据的空间
		T* m_Data = nullptr;

		// 数组当前能够保存的最大个数
		int m_MaxCount = 0;

		// 数组当前已经保存了的元素个数
		int m_CurrentCount = 0;

	private:
		// 提供一个新的大小,用于重新分配空间
		bool renew(int size);

	public:
		// 构造函数:参数是想要申请的缓冲区大小
		tvector(int size = 10);

		// 析构函数:释放申请的堆空间
		~tvector();

		// 在数组的指定位置添加一个元素
		bool insert(int index, T item);

		// 在数组的指定位置删除一个元素,并返回删除的元素
		T erase(int index);

		// 设置元素的值
		void set(int index, T item) { m_Data[index] = item; }

		// 获取元素的值
		T get(int index) { return m_Data[index]; }

		// 获取当前的元素个数
		int length() { return m_CurrentCount; }
	};

	// 构造函数的实现
	template <class T>
	tvector<T>::tvector(int size)
	{
		// 默认没有保存东西
		this->m_CurrentCount = 0;

		// 初始化最大能存储的个数
		this->m_MaxCount = size;

		// 堆空间的申请和指向,最好添加判断
		this->m_Data = new T[size];
	}

	// 析构函数:释放申请的堆空间
	template <class T>
	tvector<T>::~tvector()
	{
		// 如果指针不为空,就释放
		if (this->m_Data != nullptr)
			delete[] this->m_Data;
	}

	// 提供一个新的大小,用于重新分配空间
	template <class T>
	bool tvector<T>::renew(int size)
	{
		// 1. 申请出一块 size 大小的空间
		T* Temp = new T[size];

		// 2. 判断空间是否申请成功
		if (!Temp) return false;

		// 3. 将旧空间的内容拷贝到新空间
		memcpy(Temp, m_Data, m_MaxCount * sizeof(T));

		// 4. 释放旧的空间,并重新指向
		delete[] m_Data;
		m_Data = Temp;

		// 5. 重新设置大小并返回 true
		m_MaxCount = size; return true;
	}

	// 在数组的指定位置添加一个元素
	template <class T>
	bool tvector<T>::insert(int index, T item)
	{
		// 1. 判断添加数据的位置是否有效
		if (index < 0 || index > m_CurrentCount)
		{
			//  1 2 3 4 5 6 7
			// ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 
			return false;
		}

		// 2. 判断当前数组的最大容量是否足够
		if (m_CurrentCount == m_MaxCount)
		{
			// 2.1 如果不够就需要重新申请更大的空间
			if (!renew(m_MaxCount + 5))
				return false;
		}

		//  1 2   3 4 5 6 7
		//  1 2 X 3 4 5 6 7

		// 3. 通过循环,从后向前依次移动数组元素
		for (int i = m_CurrentCount - 1; i >= index; --i)
			m_Data[i + 1] = m_Data[i];

		// 4. 将想要添加的数据直接进行赋值
		m_Data[index] = item;

		// 5. 增加当前元素个数并返回 true
		m_CurrentCount++; return true;
	}

	// 在数组的指定位置删除一个元素,并返回删除的元素
	template <class T>
	T tvector<T>::erase(int index)
	{
		// 1. 判断传入的位置是否合理

		// 0 1 2 3 4 5
		// 0 2 3 4 5

		// 2. 保存被删除的元素
		T data = m_Data[index];

		// 3. 通过循环从前往后移动元素
		for (int i = index; i < m_CurrentCount - 1; ++i)
			m_Data[i] = m_Data[i + 1];

		// 4. 减少当前的元素个数并返回被删元素
		--m_CurrentCount; return data;
	}
}

以上是类模板,以下是实现动态数组中保存int型数据的程序
MyVector.h

// 防止头文件的重复包含,当前文件不管被包含多少次,
// 最终只会被编译一次,是由 VS 提供的,不跨平台。
#pragma once

// 命名空间: 解决作用域的二义性问题
namespace S
{
	// 动态数组类: 内部维护了一个可以动态增长的[数组]
	class vector
	{
	private:
		// 一个指针,指向了保存数据的空间
		int* m_Data = nullptr;

		// 数组当前能够保存的最大个数
		int m_MaxCount = 0;

		// 数组当前已经保存了的元素个数
		int m_CurrentCount = 0;

	private:
		// 提供一个新的大小,用于重新分配空间
		bool renew(int size);

	public:
		// 构造函数:参数是想要申请的缓冲区大小
		vector(int size = 10);

		// 析构函数:释放申请的堆空间
		~vector();

		// 在数组的指定位置添加一个元素
		bool insert(int index, int item);

		// 在数组的指定位置删除一个元素,并返回删除的元素
		int erase(int index);

		// 设置元素的值
		void set(int index, int item) { m_Data[index] = item; }

		// 获取元素的值
		int get(int index) { return m_Data[index]; }

		// 获取当前的元素个数
		int length() { return m_CurrentCount; }
	};
}


MyVector.cpp

#include "MyVector.h"
#include <iostream>

// 所有成员函数的实现也必须在同一个命名空间中
namespace S
{
	// 构造函数的实现
	vector::vector(int size)
	{
		// 默认没有保存东西
		this->m_CurrentCount = 0;

		// 初始化最大能存储的个数
		this->m_MaxCount = size;

		// 堆空间的申请和指向,最好添加判断
		this->m_Data = new int[size];
	}

	// 析构函数:释放申请的堆空间
	vector::~vector()
	{
		// 如果指针不为空,就释放
		if (this->m_Data != nullptr)
			delete[] this->m_Data;
	}

	// 提供一个新的大小,用于重新分配空间
	bool vector::renew(int size)
	{
		// 1. 申请出一块 size 大小的空间
		int* Temp = new int[size];

		// 2. 判断空间是否申请成功
		if (!Temp) return false;

		// 3. 将旧空间的内容拷贝到新空间
		memcpy(Temp, m_Data, m_MaxCount * sizeof(int));

		// 4. 释放旧的空间,并重新指向
		delete[] m_Data;
		m_Data = Temp;

		// 5. 重新设置大小并返回 true
		m_MaxCount = size; return true;
	}

	// 在数组的指定位置添加一个元素
	bool vector::insert(int index, int item)
	{
		// 1. 判断添加数据的位置是否有效
		if (index < 0 || index > m_CurrentCount)
		{
			//  1 2 3 4 5 6 7
			// ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 
			return false;
		}

		// 2. 判断当前数组的最大容量是否足够
		if (m_CurrentCount == m_MaxCount)
		{
			// 2.1 如果不够就需要重新申请更大的空间
			if (!renew(m_MaxCount + 5))
				return false;
		}

		//  1 2   3 4 5 6 7
		//  1 2 X 3 4 5 6 7

		// 3. 通过循环,从后向前依次移动数组元素
		for (int i = m_CurrentCount - 1; i >= index; --i)
			m_Data[i + 1] = m_Data[i];

		// 4. 将想要添加的数据直接进行赋值
		m_Data[index] = item;

		// 5. 增加当前元素个数并返回 true
		m_CurrentCount++; return true;
	}

	// 在数组的指定位置删除一个元素,并返回删除的元素
	int vector::erase(int index)
	{
		// 1. 判断传入的位置是否合理

		// 0 1 2 3 4 5
		// 0 2 3 4 5

		// 2. 保存被删除的元素
		int data = m_Data[index];

		// 3. 通过循环从前往后移动元素
		for (int i = index; i < m_CurrentCount - 1; ++i)
			m_Data[i] = m_Data[i + 1];

		// 4. 减少当前的元素个数并返回被删元素
		--m_CurrentCount; return data;
	}
}

main.cpp

#include <iostream>
#include "tvector.h"
#include "MyVector.h"
using namespace std;

int main()
{
	S::tvector<double> vec(1);		// 分配一字节大小

	for (int i = 10; i >= 0; --i)
		vec.insert(0, i*1.1);

	for (int i = 0; i < vec.length(); ++i)
		cout << vec.get(i) << " ";
	printf("\n");

	vec.erase(4);
	for (int i = 0; i < vec.length(); ++i)
		cout << vec.get(i) << " ";
	printf("\n");

	return 0;
}

02. vector 容器的使用

// 1. 包含容器对应的头文件,并使用名称空间
#include <vector>
using namespace std;

#include <iostream>

int main()
{
	// 2. 因为是一个模板,所以需要在实例化时指定类型
	vector<int> vec1(10);					// 初始化 10 个元素大小
	vector<int> vec2(10, 2);				// 初始化 10 个 2 
	vector<int> vec3 = { 1, 2, 3, 4, 5 };	// 使用后面的值进行初始化
	vector<int> vec4(vec3);					// 拷贝构造函数

	// 3. 增加容器的元素
	vec3.push_back(10);						// 在末尾添加元素
	vec3.insert(vec3.begin(), 1);			// 在开头位置添加元素

	// 4. 删除元素
	vec3.pop_back();						// 删除结尾的元素
	vec3.erase(vec3.begin() + 3);			// 删除第二个元素

	// 5. 如何查看和修改元素
	vec3[0] = 100;							// 使用下标修改
	vec3.front() = 200;						// 修改首元素的值
	vec3.back() = 300;						// 修改尾元素的值
	vec3.at(1) = 400;						// 获取对应位置的元素,但是会判断是否越界
 
	// 6. 遍历容器的几种方式

	// 1. 常规遍历,用下标
	// 这个方式一般只用于显示和修改元素数据(不增加或删除)
	for (int i = 0; i < vec3.size(); ++i)
		printf("%d ", vec3[i]);
	printf("\n");

	// 2. 常规遍历,用迭代器 auto 自动类型识别
	for (auto i = vec3.begin(); i != vec3.end(); ++i)
		printf("%d ", *i);
	printf("\n");

	// 3. 使用列表循环,将 vec3 的所有元素依次赋值给 i
	// 不添加引用就是值拷贝,不能修改原来的数据
	// 这个方式一般只用于显示和修改元素数据(不增加或删除)
	for (auto & i : vec3)
		printf("%d ", i);
	printf("\n");

	// 4. 使用 while 的方式进行遍历
	auto begin = vec3.begin();
	while (begin != vec3.end())
	{
		printf("%d ", *begin);
		++begin;
	}
	printf("\n");

	// 在循环的过程中,不能随意的增加和删除元素
	// 会导致迭代器无效,使程序崩溃
	for (auto i = vec3.begin(); i != vec3.end(); ++i)
	{
		// 删除时需要接收返回的新迭代器
		i = vec3.insert(vec3.begin(), 10);
	}

	// 1 2 3 4 5 6 7
	// b             e
	// end 迭代器不能用于解引用

	return 0;
}

03. 在控制台打印一个点

// 1. 添加 windows.h 头文件使用其中的函数
#include <windows.h>
#include <iostream>

// 在控制台中,高度和宽度的比是 2:1,所以设置控制台光标位置的
//	时候,需要将宽度*2。在使用数组处理逻辑的时候, x 代表的是
//	行数,y代表的是列数,但是在控制台中,x代表的是列数,y代表
//	的是行数。在具体的使用过程中,为了让数组和控制台的显示对应,
//	通常需要调换 x 和 y 的位置。

/*       数组             控制台
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
	0 * * * * * 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
*/

// 在指定的坐标使用指定的颜色打印指定的字符
void WriteChar(short x, short y, WORD color, const char* s)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 通过函数的调用实现移动光标到指定位置
	//  1: 想要修改的是哪一个输出缓冲区的光标位置
	//	2: 想要将光标移动到控制台的哪一个位置
	SetConsoleCursorPosition(OutputHandle, { y * 2, x });

	// 为接下来需要打印的文字提供颜色,可以使用 RGB 搭配出一些简单
	// 的颜色,不要使用较暗的颜色,应该选用亮色(黄色、绿色、白的)
	SetConsoleTextAttribute(OutputHandle, color);

	// 打印指定的图形
	printf(s);
}

// 隐藏光标
void HindCursor(bool Hide = true)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 定义结构体,用于保存光标的信息,参数二表示是否显示
	CONSOLE_CURSOR_INFO Cursor = { 1, !Hide };

	// 调用函数设置光标的属性
	SetConsoleCursorInfo(OutputHandle, &Cursor);
}

int main()
{
	HindCursor(false);

	WriteChar(1, 1, 0xF, "■");
	WriteChar(1, 2, 0x1 | 8, "□");
	WriteChar(1, 3, 0x2 | 8, "●");
	WriteChar(1, 4, 0x4 | 8, "●");

	return 0;
}

04. 打印一个会自动移动的点

// 1. 添加 windows.h 头文件使用其中的函数
#include <windows.h>
#include <iostream>

// 在控制台中,高度和宽度的比是 2:1,所以设置控制台光标位置的
//	时候,需要将宽度*2。在使用数组处理逻辑的时候, x 代表的是
//	行数,y代表的是列数,但是在控制台中,x代表的是列数,y代表
//	的是行数。在具体的使用过程中,为了让数组和控制台的显示对应,
//	通常需要调换 x 和 y 的位置。

/*       数组             控制台
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
	0 * * * * * 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
*/

// 在指定的坐标使用指定的颜色打印指定的字符
void WriteChar(short x, short y, WORD color, const char* s)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 通过函数的调用实现移动光标到指定位置
	//  1: 想要修改的是哪一个输出缓冲区的光标位置
	//	2: 想要将光标移动到控制台的哪一个位置
	SetConsoleCursorPosition(OutputHandle, { y * 2, x });

	// 为接下来需要打印的文字提供颜色,可以使用 RGB 搭配出一些简单
	// 的颜色,不要使用较暗的颜色,应该选用亮色(黄色、绿色、白的)
	SetConsoleTextAttribute(OutputHandle, color);

	// 打印指定的图形
	printf(s);
}

// 隐藏光标
void HindCursor(bool Hide = true)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 定义结构体,用于保存光标的信息,参数二表示是否显示
	CONSOLE_CURSOR_INFO Cursor = { 1, !Hide };

	// 调用函数设置光标的属性
	SetConsoleCursorInfo(OutputHandle, &Cursor);
}

int main()
{
	HindCursor(false);

	for (int i = 0; i < 10; ++i)
	{
		// 擦除之前的痕迹,绘制移动后的图形
		WriteChar(1, i - 1, 0xF, "  ");

		// 在第二行移动,方向为右边
		WriteChar(1, i, 0xF, "■");

		// 通过函数暂停程序达到停顿的效果, 0.1s
		Sleep(100);
	}

	return 0;
}

05. 一个受控的点

// 1. 添加 windows.h 头文件使用其中的函数
#include <windows.h>
#include <iostream>
#include <conio.h>

// 在控制台中,高度和宽度的比是 2:1,所以设置控制台光标位置的
//	时候,需要将宽度*2。在使用数组处理逻辑的时候, x 代表的是
//	行数,y代表的是列数,但是在控制台中,x代表的是列数,y代表
//	的是行数。在具体的使用过程中,为了让数组和控制台的显示对应,
//	通常需要调换 x 和 y 的位置。

/*       数组             控制台
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
	0 * * * * * 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
*/

// 在指定的坐标使用指定的颜色打印指定的字符
void WriteChar(short x, short y, WORD color, const char* s)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 通过函数的调用实现移动光标到指定位置
	//  1: 想要修改的是哪一个输出缓冲区的光标位置
	//	2: 想要将光标移动到控制台的哪一个位置
	SetConsoleCursorPosition(OutputHandle, { y * 2, x });

	// 为接下来需要打印的文字提供颜色,可以使用 RGB 搭配出一些简单
	// 的颜色,不要使用较暗的颜色,应该选用亮色(黄色、绿色、白的)
	SetConsoleTextAttribute(OutputHandle, color);

	// 打印指定的图形
	printf(s);
}

// 隐藏光标
void HindCursor(bool Hide = true)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 定义结构体,用于保存光标的信息,参数二表示是否显示
	CONSOLE_CURSOR_INFO Cursor = { 1, !Hide };

	// 调用函数设置光标的属性
	SetConsoleCursorInfo(OutputHandle, &Cursor);
}

// 标识方向
#define 上 0
#define 下 1
#define 左 2
#define 右 3


// 点要保存自己的坐标,所以需要定义变量,点的移动是
// 根据用户设置的方向决定的,所以还需要保存方向。
COORD Coord = { 1, 1 };
int Dir =;				// 方向默认为右

// 获取用户的输入,修改方向
void GetDir()
{
	// 游戏本身不能被阻塞,所以使用过的函数不能是阻塞函数
	if (_kbhit())
	{
		// 这是一个非阻塞函数,一旦按下任何按键,返回 true
		// _getch 是无回显输入,不能使用带回显的函数
		switch (_getch())
		{
		case 'w': Dir =; break;
		case 's': Dir =; break;
		case 'a': Dir =; break;
		case 'd': Dir =; break;
		}
	}
}

int main()
{
	HindCursor(false);

	while (true)
	{
		// 获取用户的输入
		GetDir();

		// 清除之前的内容
		WriteChar(Coord.X, Coord.Y, 0xF, "  ");

		// 根据点的方向移动点的位置
		switch (Dir)
		{
		case: Coord.X--; break;
		case: Coord.X++; break;
		case: Coord.Y--; break;
		case: Coord.Y++; break;
		}

		// 回值移动之后的内容
		WriteChar(Coord.X, Coord.Y, 0xF, "■");

		// 通过函数暂停程序达到停顿的效果, 0.1s
		Sleep(100);
	}

	return 0;
}

06. 控制台的鼠标事件

// 1. 添加 windows.h 头文件使用其中的函数
#include <windows.h>
#include <iostream>

// 在控制台中,高度和宽度的比是 2:1,所以设置控制台光标位置的
//	时候,需要将宽度*2。在使用数组处理逻辑的时候, x 代表的是
//	行数,y代表的是列数,但是在控制台中,x代表的是列数,y代表
//	的是行数。在具体的使用过程中,为了让数组和控制台的显示对应,
//	通常需要调换 x 和 y 的位置。

/*       数组             控制台
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
	0 * * * * * 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 * 0 0 0 0 0
	0 0 0 0 0 0 0	 0 0 0 0 0 0 0
*/

// 在指定的坐标使用指定的颜色打印指定的字符
void WriteChar(short x, short y, WORD color, const char* s)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 通过函数的调用实现移动光标到指定位置
	//  1: 想要修改的是哪一个输出缓冲区的光标位置
	//	2: 想要将光标移动到控制台的哪一个位置
	SetConsoleCursorPosition(OutputHandle, { y * 2, x });

	// 为接下来需要打印的文字提供颜色,可以使用 RGB 搭配出一些简单
	// 的颜色,不要使用较暗的颜色,应该选用亮色(黄色、绿色、白的)
	SetConsoleTextAttribute(OutputHandle, color);

	// 打印指定的图形
	printf(s);
}

// 隐藏光标
void HindCursor(bool Hide = true)
{
	// 句柄: 在windwos中句柄用于标识某一种东西,这个例子中,句柄
	//	被用于标识当前控制台的输出缓冲区,用于显示具体的内同
	HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	// 定义结构体,用于保存光标的信息,参数二表示是否显示
	CONSOLE_CURSOR_INFO Cursor = { 1, !Hide };

	// 调用函数设置光标的属性
	SetConsoleCursorInfo(OutputHandle, &Cursor);
}

int main()
{
	HindCursor();		// 隐藏光标

	// 获取控制台输入缓冲区的句柄
	HANDLE InputHandle = GetStdHandle(STD_INPUT_HANDLE);

	// 开启鼠标事件的接受: ENABLE_MOUSE_INPUT
	SetConsoleMode(InputHandle, ENABLE_MOUSE_INPUT);

	DWORD Number = 0;
	// 用于保存读取到的事件
	INPUT_RECORD InputRecord = { 0 };

	// 编写一个循环,不断的获取当前鼠标的事件
	//	- 1: 想要读取哪一个控制台的输入事件
	//	- 2: 一个结构体,保存了获取到的输入事件
	//	- 3: 数量,表示提供的结构体有几个(1)
	//	- 4: 当前读取到了几个事件
	while (ReadConsoleInput(InputHandle, &InputRecord, 1, &Number))
	{
		// 接受的事件不止有鼠标类型,所以需要进行判断
		if (InputRecord.EventType == MOUSE_EVENT)
		{
			// 获取到鼠标的坐标
			COORD MouseCoord = InputRecord.Event.MouseEvent.dwMousePosition;

			// 为所有的鼠标事件进行输出坐标的处理
			CHAR Buffer[0x100] = { 0 };
			// printf 将格式化后的内容填充控制台输出中
			// 将格式化后的内容填充到提供的缓冲区中
			sprintf_s(Buffer, "(%3d, %3d)", MouseCoord.X, MouseCoord.Y);
			// 始终打印在屏幕的 0,0位置
			WriteChar(0, 0, 0xF, Buffer);


			// 通常来讲,鼠标的绘制应该直接反映在与绘图相关的数组中,
			// 数组在游戏中扮演的地图,绘制的图形可以是障碍物或者事物。

			// 鼠标事件有非常多,我们可以单独响应某一个事件
			if (InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
			{
				// 鼠标的左键按下了,就执行这里
				WriteChar(MouseCoord.Y, MouseCoord.X / 2, 0xF, "●");
			}
			else if (InputRecord.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
			{
				// 鼠标的左键按下了,就执行这里
				WriteChar(MouseCoord.Y, MouseCoord.X / 2, 0xF, "  ");
			}

		}
	}

	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	// 如果控制台无法接收到鼠标事件,就进行设置: 控制台标题右键 -> 属性 ->
	// 选项 -> 取消快速编辑模式的勾选。
	// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值