/// <summary> /// 构建控制台 /// </summary> /// <param name="consoleType">控制台类型</param> /// <param name="bold">字体粗细</param> /// <param name="maximum">最大化</param> /// <param name="width">宽度</param> /// <param name="height">高度</param> /// <param name="title">标题</param> /// <returns>是否成功</returns> public static void Construct(ConsoleType consoleType, bool bold, bool maximum, short width, short height, string title = "Destroy") { SetConsoleSetting(title); switch (consoleType) { case ConsoleType.Default: SetFontAndWindow("Consolas", bold, 16, 16, maximum, width, height); break; case ConsoleType.Chinese: SetFontAndWindow("新宋体", bold, 16, 16, maximum, width, height); break; case ConsoleType.Pixel: SetFontAndWindow("Terminal", bold, 8, 8, maximum, width, height); break; case ConsoleType.HignQuality: SetFontAndWindow("MS Gothic", bold, 1, 1, maximum, width, height); break; } if (maximum) { KERNEL.SET_WINDOW_POS(0, 0); } else { CONSOLE.CenterConsoleWindowPosition(); } CONSOLE.CursorVisible = false; }
/// <summary> /// 播放MadeWithDestroy的动画 /// </summary> /// <param name="center">是否居中显示</param> /// <param name="x">横向坐标</param> /// <param name="y">纵向坐标</param> /// <param name="consoleKey">按键</param> public static void MadeWithDestroy(bool center, short x, short y, ConsoleKey consoleKey = ConsoleKey.Enter) { string logo = "Made with Destroy"; if (center) { x = (short)(CONSOLE.WindowWidth / 2); x -= (short)(logo.Length / 2); y = (short)(CONSOLE.WindowHeight / 2); } CONSOLE.SetCursorPosition(x, y); CONSOLE.ForegroundColor = Colour.Black; CONSOLE.BackgroundColor = Colour.White; CONSOLE.Write(logo); CONSOLE.ResetColor(); CONSOLE.SetCursorPosition(0, 0); //窗口透明度渐变 for (int i = 0; i < 256; i++) { //按下回车键直接恢复透明度并且退出渐变阶段 if (CONSOLE.GetKey(consoleKey)) { KERNEL.SET_WINDOW_ALPHA(255); break; } KERNEL.SET_WINDOW_ALPHA((byte)i); KERNEL.SLEEP(10); } KERNEL.SLEEP(1000); CONSOLE.Clear(); }
/// <summary> /// 渲染(渲染的区域不能小于屏幕缓冲区, 否则渲染区域会被截断) /// </summary> /// <param name="x">横向坐标</param> /// <param name="y">纵向坐标</param> public void Render(short x = 0, short y = 0) { //控制台现在最多只能打印双宽字符, 不能打印三宽以上的字符(比如部分阿拉伯文), 并且不支持大部分表情与特殊符号。 //可以只使用一个CHAR_INFO只打印一个中文的左半部分, 如果要打印一个完整的中文字符则需要两个CHAR_INFO, 并且必须保证第一个CHAR_INFO与第二个CHAR_INFO前景色与背景色一致, 第一个CHAR_INFO保存中文, 第二个CHAR_INFO保存'\0'空字符。 //一旦第一个CHAR_INFO的中文被覆盖意味着这个中文字符无法显示。 //一个中文的右半部分可以被隐去, 并且右半部分可以是一个英文或者空字符甚至可以是一个另外的中文的左半部分。 //一个中文无法单独显示右半部分。 KERNEL.WRITE_CONSOLE_OUTPUT(CONSOLE.OutputHandle, infos, x, y, (short)(Width * (int)CharWidth), Height); }
/// <summary> /// 构建控制台 /// </summary> /// <param name="fontName">字体名字</param> /// <param name="bold">字体粗细</param> /// <param name="fontWidth">字体宽度</param> /// <param name="fontHeight">字体高度</param> /// <param name="maximum">最大化</param> /// <param name="width">宽度</param> /// <param name="height">高度</param> /// <param name="title">标题</param> public static void Construct(string fontName, bool bold, short fontWidth, short fontHeight, bool maximum, short width, short height, string title = "Destroy") { SetConsoleSetting(title); SetFontAndWindow(fontName, bold, fontWidth, fontHeight, maximum, width, height); if (maximum) { KERNEL.SET_WINDOW_POS(0, 0); } else { CONSOLE.CenterConsoleWindowPosition(); } CONSOLE.CursorVisible = false; }
/// <summary> /// 开始游戏 /// </summary> public static void Start(Action onStart, Action onUpdate, Action onDestroy, int fps) { run = true; //这一帧距离上一帧的时间(单位:秒) float deltaTime = 0; //每帧应该使用的时间(单位:毫秒) long tickTime = 1000 / fps; //代码一帧运行花费的时间(单位:毫秒) long timeCost = 0; //初始化游戏 onStart?.Invoke(); while (run) { KERNEL.START_TIMING(out long freq, out long start); //每帧执行一次, 防止控制台窗口大小变化时光标再次出现 KERNEL.SET_CONSOLE_CURSOR_INFO(CONSOLE.OutputHandle, false, 1); Time.DeltaTime = deltaTime; //赋值DeltaTime Time.TotalTime += Time.DeltaTime; //赋值TotalTime Input.CheckMouseState(); //检测鼠标状态 onUpdate?.Invoke(); //每帧更新游戏 Input.CheckKeyboardState(); //检测键盘状态 KERNEL.END_TIMING(freq, start, out timeCost); while (timeCost < tickTime) { KERNEL.SLEEP(0); //短暂让出线程防止死循环 KERNEL.END_TIMING(freq, start, out timeCost); } deltaTime = (float)timeCost / 1000; } //结束游戏 onDestroy?.Invoke(); }
internal static void CheckMouseState() { bool r = KERNEL.READ_CONSOLE_INPUT(CONSOLE.InputHandle, out short cursorPosX, out short cursorPosY); if (r) { CursorPosition = new Vector2(cursorPosX, cursorPosY); } KERNEL.GET_CURSOR_POS(out int mousePosX, out int mousePosY); MousePosition = new Vector2(mousePosX, mousePosY); ConsoleInFocus = KERNEL.GET_WINDOW_IN_FOCUS(); //判断鼠标是否则在控制台窗口内 KERNEL.GET_WINDOW_POS(out int windowPosX, out int windowPosY); KERNEL.GET_WINDOW_SIZE(out int width, out int height); if (mousePosX >= windowPosX && mousePosX < windowPosX + width && mousePosY >= windowPosY && mousePosY < windowPosY + height) { MouseInConsole = true; } else { MouseInConsole = false; } //鼠标坐标=>控制台坐标 if (MouseInConsole) { KERNEL.SCREEN_TO_CLIENT(CONSOLE.ConsoleWindowHandle, ref mousePosX, ref mousePosY); CONSOLE.GetConsoleFont(CONSOLE.OutputHandle, out bool bold, out short fontWidth, out short fontHeight, out string fontName); MousePositionInConsole = new Vector2(mousePosX / fontWidth, mousePosY / fontHeight); } }
public static void SetFontAndWindow(string fontName, bool bold, short fontWidth, short fontHeight, bool maximum, short width, short height) { CONSOLE.SetConsoleFont(CONSOLE.OutputHandle, bold, fontWidth, fontHeight, fontName); KERNEL.GET_LARGEST_CONSOLE_WINDOW_SIZE(CONSOLE.OutputHandle, out short largestWidth, out short largestHeight); if (maximum) { width = largestWidth; height = largestHeight; } else if (width > largestWidth || height > largestHeight) { Error.Pop("specific width/height is too big!"); } //如果发生报错, 尝试使用或禁用下面这行代码 KERNEL.SET_CONSOLE_WINDOW_SIZE(CONSOLE.OutputHandle, 1, 1); CONSOLE.BufferWidth = width; CONSOLE.WindowWidth = width; CONSOLE.BufferHeight = height; CONSOLE.WindowHeight = height; }