using System.Diagnostics; namespace Debug.ModelingMusic; public class Music { //选择的模式 public static int mode = 0; public Music() { Console.Clear(); do { Program.printfLine("模拟音游 1.0 by "); Program.printfLine("1.启动 2.测试下落 3.指定字符串 4.随机指定字符串下落 5.扬声器节奏 0.退出"); var v = Console.ReadLine(); if (int.TryParse(v, out int i)) { mode = i; if (i == 0) { //退出程序 Environment.Exit(0); return; } Init().GetAwaiter().GetResult(); // 启动 return; } } while (true); } private int consoleWidth = 0, consoleHeight = 0; private async Task Init() { Console.CursorVisible = false; // 隐藏光标 Console.Clear(); Program.printf("加载资源中"); // 获取控制台的大小 consoleWidth = Console.WindowWidth; consoleHeight = Console.WindowHeight - 1; for (int i = 0; i < 3; i++) { Program.printf("·"); await Task.Delay(300); } Console.WriteLine(); Program.printfLine("加载完成"); await Task.Delay(500); Console.Clear(); setCharArry(); switch (mode) {//默认模式 case 1: new Thread(MusicDebug.Default).Start(); break; case 2: new Thread(MusicDebug.DebugDefault).Start(); break; case 3: case 4: { Console.CursorVisible = true; // 隐藏光标 Console.WriteLine("请输入字符串"); string? v = Console.ReadLine(); //string转成char[] char[] ch = v!.ToCharArray(); if (mode == 3) { //指定字符串模式 new Thread(() => MusicDebug.DesignateDown(ch)).Start(); } else { //随机指定字符串下落 new Thread(() => MusicDebug.DesignateRandmoDown(ch)).Start(); } break; } case 5: new Thread(MusicDebug.MusicRhythm).Start(); //MusicDebug.(); break; default: break; } Console.CursorVisible = false; // 隐藏光标 new Thread(PrintCharArray).Start(); // 等待用户按下任意键后退出 // Console.ReadKey(); } /// /// 随机字符下落 /// private static readonly Random random = new(); //常量 public const char ShowChar = ' '; //Y,X public static readonly Point[,] chars = new Point[10, 30]; public static void Down(char a) { // 随机生成字符出现的初始位置 // 设置光标位置 ConsoleColor Color = ConsoleColor.White; int v = random.Next(0, 2); switch (v) { case 0: Color = ConsoleColor.Red; break; case 1: Color = ConsoleColor.Blue; break; } // 让字符从初始位置下落 int x = random.Next(0, chars.GetLength(1)); for (int y = 0; y < chars.GetLength(0); y++) // 注意这里使用consoleHeight { // 移动到下一行 chars[y, x].Char = a; if (y > 0) { chars[y - 1, x].Char = ShowChar; } chars[y, x].Color = Color; Thread.Sleep(random.Next(60, 120)); // 控制字符下落速度 } Thread.Sleep(50); chars[chars.GetLength(0) - 1, x].Char = ShowChar; } private static long item = 0; // 定义一个方法来打印二维字符数组 public static void PrintCharArray() { var stopwatch = new Stopwatch(); int frameCount = 0; double totalTime = 0; int i; int j; var a = chars.GetLength(0); var b = chars.GetLength(1); while (true) { stopwatch.Restart(); Console.Clear(); Console.SetCursorPosition(0, 0); for (i = 0; i < a; i++) { for (j = 0; j < b; j++) { Console.ForegroundColor = chars[i, j].Color; Console.Write($" {chars[i, j].Char} "); item++; if (item > 100000) { GC.Collect(); item = 0; } } Console.WriteLine(); } switch (new Random().Next(0, 2)) { case 0: Console.ForegroundColor = ConsoleColor.Red; break; case 1: Console.ForegroundColor = ConsoleColor.Blue; break; } for (i = 0; i < b; i++) { Console.Write("---"); } Console.ResetColor(); Console.SetCursorPosition(0, 1);// 设定光标位置到第二行 // 停止计时并计算本帧的处理时间 stopwatch.Stop(); double elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; totalTime += elapsedMilliseconds; frameCount++; // 计算帧率 double fps = frameCount / (totalTime / 1000.0); Console.WriteLine($" {fps:0} FPS"); // 保持每秒约16.67ms(即大约60 FPS)的间隔 // Thread.Sleep(Math.Max(0, 60 - (int)elapsedMilliseconds)); //死方法 不知道为什么 控制台限制60 帧这样闪烁不会太严重 Thread.Sleep(100); } } private void setCharArry() { for (int i = 0; i < chars.GetLength(0); i++) { for (int j = 0; j < chars.GetLength(1); j++) { chars[i, j] = new Point(); // 初始化每个元素 } // Console.WriteLine(); } } }