using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using NAudio.Wave; /// /// The ModelingMusic namespace contains classes and methods for modeling and manipulating musical data. /// namespace Debug.ModelingMusic; public class MusicFrom { // 导入kernel32.dll中的SetConsoleMode函数 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); // 导入kernel32.dll中的GetStdHandle函数 [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr GetStdHandle(int nStdHandle); // 定义控制台模式常量 private const uint ENABLE_ECHO_INPUT = 0x0004; private const uint ENABLE_LINE_INPUT = 0x0002; private const uint ENABLE_PROCESSED_INPUT = 0x0001; // 导入kernel32.dll中的GetConsoleMode函数 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); // 定义标准输入句柄 private const int STD_INPUT_HANDLE = -10; private long time = 0; readonly int MaxX; readonly int MaxY; public MusicFrom() { MaxX = Program.chars.GetLength(1); MaxY = Program.chars.GetLength(0); SetCharArry(); new Thread(PrintCharArray).Start(); new Thread(KeyboardMapping).Start(); new Thread(Run).Start(); // 恢复控制台输入模式 // mode |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; // SetConsoleMode(hStdin, mode); } public void Run() { Thread.Sleep(500); while (Program.IsWhile) { // 随机数 int random = Program.random.Next(0, 7); switch (random) { case 0: DownKey('D', 3); break; case 1: DownKey('F', 10); break; case 2: DownKey('G', 17); break; case 3: // DownKey('M', 24); return; case 4: DownKey('J', 31); break; case 5: DownKey('K', 38); break; case 6: DownKey('L', 45); break; default: break; } Thread.Sleep(1000); } } class ZIFUKEY { public char key; public bool isDown;//是否被按下 } public void DownKey(char key, int x) { new Thread(() => { var zIFUKEY = new ZIFUKEY() { key = key, isDown = false }; for (int i = 0; i < MaxY; i++) { Program.chars[i, x].Char = zIFUKEY.key; Thread.Sleep(260); Program.chars[i, x].Char = ' '; if (zIFUKEY.isDown) { break; } } }).Start(); } readonly char[] jianpan = ['D', 'F', 'G', ' ', 'J', 'K', 'L']; public void PrintCharArray() { // 获取标准输入句柄 IntPtr hStdin = GetStdHandle(STD_INPUT_HANDLE); // 获取当前控制台输入模式 if (!GetConsoleMode(hStdin, out uint mode)) { Console.WriteLine("无法获取控制台输入模式"); return; } // 禁用回显和行输入 mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); if (!SetConsoleMode(hStdin, mode)) { Console.WriteLine("无法设置控制台输入模式"); return; } var stopwatch = new Stopwatch(); int frameCount = 0; double totalTime = 0; int i; int j; var buffer = new StringBuilder(); while (Program.IsWhile) { stopwatch.Restart(); Console.SetCursorPosition(0, 0);// 设定光标位置 Console.Clear(); buffer.Clear(); for (i = 0; i < MaxY; i++) { for (j = 0; j < MaxX; j++) { buffer.Append(Program.chars[i, j].Char); time++; if (time > 100000) { GC.Collect(); time = 0; } } buffer.AppendLine(); } Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write(buffer.ToString()); buffer.Clear(); for (i = 0; i < MaxX; i++) { buffer.Append('-'); } // 打印ASDF HJKL buffer.AppendLine(); Console.Write(buffer); buffer.Clear(); // int totalLength = 50; int totalAs = jianpan.Length; int spaceBetweenAs = (MaxX - totalAs) / (totalAs - 1); for (i = 0; i < totalAs; i++) { buffer.Clear(); for (j = 0; j < spaceBetweenAs / 2; j++) { buffer.Append(' '); } buffer.Append(jianpan[i]); if (isDown[i]) { Console.ForegroundColor = ConsoleColor.Red; // 设置颜色为红色 } else { Console.ForegroundColor = ConsoleColor.Blue; // 设置颜色为白色 } for (j = 0; j < spaceBetweenAs / 2; j++) { buffer.Append(' '); } Console.Write(buffer); } // 停止计时并计算本帧的处理时间 stopwatch.Stop(); double elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; totalTime += elapsedMilliseconds; frameCount++; // 计算帧率 double fps = frameCount / (totalTime / 1000.0); // Console.ResetColor(); Console.ForegroundColor = ConsoleColor.White; buffer.Clear(); buffer.Append($" {fps:0} FPS "); Console.WriteLine(buffer); buffer.Clear(); buffer.Append($" {score.ToString("D10")} "); Console.SetCursorPosition(49, 0); Console.Write(buffer); // 保持每秒约16.67ms(即大约60 FPS)的间隔 // Thread.Sleep(Math.Max(0, 60 - (int)elapsedMilliseconds)); //这样闪烁不会太严重 Thread.Sleep(50); } // 恢复控制台输入模式 mode |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; SetConsoleMode(hStdin, mode); } private void SetCharArry() { for (int i = 0; i < Program.chars.GetLength(0); i++) { for (int j = 0; j < Program.chars.GetLength(1); j++) { Program.chars[i, j] = new Point(); // 初始化每个元素 } } } //分数long 000000000 private long score = 0; readonly bool[] isDown = new bool[7]; // 导入user32.dll中的GetAsyncKeyState函数 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern short GetAsyncKeyState(int vkey); // 定义虚拟键码 const int VK_D = 0x44; // D键 const int VK_F = 0x46; // F键 const int VK_G = 0x47; // G键 const int VK_J = 0x4A; // J键 const int VK_K = 0x4B; // K键 const int VK_L = 0x4C; // L键 const int VK_SPACE = 0x20; // 空格键 const int VK_ENTER = 0x0D; // Enter键 const int VK_ESCAPE = 0x1B; // ESC键 /// /// 键盘监听方法 /// public void KeyboardMapping() { // 创建一个字典来跟踪每个按键的前一次状态 var keyStates = new Dictionary { { VK_D, false }, { VK_F, false }, { VK_G, false }, { VK_J, false }, { VK_K, false }, { VK_L, false }, { VK_SPACE, false }, { VK_ENTER, false }, { VK_ESCAPE, false } }; while (true) { // ConsoleKeyInfo keyInfo = Console.ReadKey(true); // true表示不显示输入的字符 // 检查并处理所有监控的按键状态变化 foreach (var kvp in keyStates) { int vkey = kvp.Key; bool wasPressed = kvp.Value; // 检查当前按键的状态 short keyState = GetAsyncKeyState(vkey); bool isKeyPressed = (keyState & 0x8000) != 0; if (isKeyPressed && !wasPressed) { // 按下时触发 HandleKeyPress(vkey); } else if (!isKeyPressed && wasPressed) { // 松开时触发 HandleKeyRelease(vkey); } // 更新按键状态 keyStates[vkey] = isKeyPressed; } // 避免CPU占用过高 Thread.Sleep(50); } } void HandleKeyPress(int vkey) { switch (vkey) { case VK_ESCAPE: if (Program.IsWhile) { Program.IsWhile = false; Console.SetCursorPosition(60, 5); Console.Write("暂停状态 再次按下ESC退出游戏/按回车键继续"); } else { Console.Clear(); Environment.Exit(0); } // 处理ESC键被按下的逻辑 break; case VK_ENTER: if (!Program.IsWhile) { Program.IsWhile = true; new Thread(PrintCharArray).Start(); } // 处理Enter键被按下的逻辑 break; case VK_D: isDown[0] = true; // 处理D键被按下的逻辑 if (Program.chars[8, 3].Char == 'D' || Program.chars[9, 3].Char == 'D') { score += 100; } break; case VK_F: isDown[1] = true; // 处理F键被按下的逻辑 if (Program.chars[8, 10].Char == 'F' || Program.chars[9, 10].Char == 'F') { score += 100; } break; case VK_G: isDown[2] = true; // 处理G键被按下的逻辑 if (Program.chars[8, 17].Char == 'G' || Program.chars[9, 17].Char == 'G') { score += 100; } break; case VK_SPACE: isDown[3] = true; // 处理空格键被按下的逻辑 break; case VK_J: isDown[4] = true; // 处理J键被按下的逻辑 if (Program.chars[8, 31].Char == 'J' || Program.chars[9, 31].Char == 'J') { score += 100; } break; case VK_K: isDown[5] = true; // 处理K键被按下的逻辑 if (Program.chars[8, 38].Char == 'K' || Program.chars[9, 38].Char == 'K') { score += 100; } break; case VK_L: isDown[6] = true; // 处理L键被按下的逻辑 if (Program.chars[8, 45].Char == 'L' || Program.chars[9, 45].Char == 'L') { score += 100; } break; } } void HandleKeyRelease(int vkey) { switch (vkey) { case VK_D: isDown[0] = false; // 处理D键被释放的逻辑 break; case VK_F: isDown[1] = false; // 处理F键被释放的逻辑 break; case VK_G: isDown[2] = false; // 处理G键被释放的逻辑 break; case VK_SPACE: isDown[3] = false; // 处理空格键被释放的逻辑 break; case VK_J: isDown[4] = false; // 处理J键被释放的逻辑 break; case VK_K: isDown[5] = false; // 处理K键被释放的逻辑 break; case VK_L: isDown[6] = false; // 处理L键被释放的逻辑 break; } } }