2025-01-04 11:26:18 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
2025-01-07 11:46:11 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
2025-01-04 11:26:18 +00:00
|
|
|
|
using System.Text;
|
2025-01-07 11:46:11 +00:00
|
|
|
|
using NAudio.Wave;
|
2025-01-04 11:26:18 +00:00
|
|
|
|
|
2025-01-07 11:46:11 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The <c>ModelingMusic</c> namespace contains classes and methods for modeling and manipulating musical data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
namespace Debug.ModelingMusic;
|
2025-01-04 11:26:18 +00:00
|
|
|
|
|
|
|
|
|
public class MusicFrom
|
|
|
|
|
{
|
|
|
|
|
private long time = 0;
|
2025-01-07 11:46:11 +00:00
|
|
|
|
int MaxX = 0;
|
|
|
|
|
int MaxY = 0;
|
2025-01-04 11:26:18 +00:00
|
|
|
|
|
|
|
|
|
public MusicFrom()
|
|
|
|
|
{
|
|
|
|
|
setCharArry();
|
2025-01-07 11:46:11 +00:00
|
|
|
|
MaxY = Program.chars.GetLength(0);
|
|
|
|
|
MaxX = Program.chars.GetLength(1);
|
2025-01-04 11:26:18 +00:00
|
|
|
|
new Thread(PrintCharArray).Start();
|
2025-01-07 11:46:11 +00:00
|
|
|
|
new Thread(KeyboardMapping).Start();
|
|
|
|
|
new Thread(Run).Start();
|
2025-01-04 11:26:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-07 11:46:11 +00:00
|
|
|
|
public void Run()
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
while (Program.IsWhile)
|
|
|
|
|
{
|
|
|
|
|
// 随机数
|
|
|
|
|
int random = Program.random.Next(0, 7);
|
|
|
|
|
DownKey(jianpan[random]);
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
class ZIFUKEY
|
|
|
|
|
{
|
|
|
|
|
public char key;
|
|
|
|
|
public bool isDown;//是否被按下
|
|
|
|
|
}
|
|
|
|
|
public void DownKey(char key)
|
|
|
|
|
{
|
|
|
|
|
new Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
var zIFUKEY = new ZIFUKEY() { key = key, isDown = false };
|
|
|
|
|
for (int i = 0; i < MaxY; i++)
|
|
|
|
|
{
|
|
|
|
|
Program.chars[i, 3].Char = zIFUKEY.key;
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
Program.chars[i, 3].Char = ' ';
|
|
|
|
|
if (zIFUKEY.isDown)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly char[] jianpan = ['D', 'F', 'G', ' ', 'J', 'K', 'L'];
|
2025-01-04 11:26:18 +00:00
|
|
|
|
public void PrintCharArray()
|
|
|
|
|
{
|
|
|
|
|
|
2025-01-07 11:46:11 +00:00
|
|
|
|
var stopwatch = new Stopwatch();
|
2025-01-04 11:26:18 +00:00
|
|
|
|
int frameCount = 0;
|
|
|
|
|
double totalTime = 0;
|
|
|
|
|
int i; int j;
|
|
|
|
|
// 获取字符数组的行数和列数
|
|
|
|
|
var a = Program.chars.GetLength(0);
|
|
|
|
|
var b = Program.chars.GetLength(1);
|
|
|
|
|
var buffer = new StringBuilder();
|
|
|
|
|
ConsoleColor xiantiaoColor = Program.random.Next(0, 2) == 0 ? ConsoleColor.Red : ConsoleColor.Blue;//线条的颜色
|
|
|
|
|
while (Program.IsWhile)
|
|
|
|
|
{
|
|
|
|
|
stopwatch.Restart();
|
|
|
|
|
Console.SetCursorPosition(0, 0);// 设定光标位置
|
|
|
|
|
Console.Clear();
|
|
|
|
|
buffer.Clear();
|
|
|
|
|
for (i = 0; i < a; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < b; j++)
|
|
|
|
|
{
|
|
|
|
|
//Console.ForegroundColor = Program.chars[i, j].Color;
|
|
|
|
|
//Console.Write($" {Program.chars[i, j].Char} ");
|
|
|
|
|
|
|
|
|
|
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 < b; i++)
|
|
|
|
|
{
|
|
|
|
|
buffer.Append('-');
|
|
|
|
|
}
|
|
|
|
|
// 打印ASDF HJKL
|
|
|
|
|
buffer.AppendLine();
|
2025-01-07 11:46:11 +00:00
|
|
|
|
Console.Write(buffer);
|
|
|
|
|
buffer.Clear();
|
2025-01-04 11:26:18 +00:00
|
|
|
|
// int totalLength = 50;
|
|
|
|
|
int totalAs = jianpan.Length;
|
|
|
|
|
int spaceBetweenAs = (b - totalAs) / (totalAs - 1);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < totalAs; i++)
|
|
|
|
|
{
|
2025-01-07 11:46:11 +00:00
|
|
|
|
buffer.Clear();
|
|
|
|
|
// if (isDown[3] && i == 3)
|
|
|
|
|
// {
|
|
|
|
|
// // 显示空格键
|
|
|
|
|
// // ConsoleKey.Spacebar
|
|
|
|
|
// buffer.Append("Spacebar");
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
2025-01-04 11:26:18 +00:00
|
|
|
|
for (j = 0; j < spaceBetweenAs / 2; j++)
|
|
|
|
|
{
|
|
|
|
|
buffer.Append(' ');
|
|
|
|
|
}
|
2025-01-07 11:46:11 +00:00
|
|
|
|
|
2025-01-04 11:26:18 +00:00
|
|
|
|
buffer.Append(jianpan[i]);
|
2025-01-07 11:46:11 +00:00
|
|
|
|
if (isDown[i])
|
|
|
|
|
{
|
|
|
|
|
Console.ForegroundColor = ConsoleColor.Red; // 设置颜色为红色
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.ForegroundColor = ConsoleColor.Blue; // 设置颜色为白色
|
|
|
|
|
}
|
2025-01-04 11:26:18 +00:00
|
|
|
|
for (j = 0; j < spaceBetweenAs / 2; j++)
|
|
|
|
|
{
|
|
|
|
|
buffer.Append(' ');
|
|
|
|
|
}
|
2025-01-07 11:46:11 +00:00
|
|
|
|
Console.Write(buffer);
|
2025-01-04 11:26:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 停止计时并计算本帧的处理时间
|
|
|
|
|
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);
|
2025-01-07 11:46:11 +00:00
|
|
|
|
buffer.Clear();
|
|
|
|
|
buffer.Append($" {score.ToString("D10")} ");
|
|
|
|
|
Console.SetCursorPosition(49, 0);
|
|
|
|
|
Console.Write(buffer);
|
2025-01-04 11:26:18 +00:00
|
|
|
|
// 保持每秒约16.67ms(即大约60 FPS)的间隔
|
|
|
|
|
// Thread.Sleep(Math.Max(0, 60 - (int)elapsedMilliseconds));
|
|
|
|
|
//这样闪烁不会太严重
|
2025-01-07 11:46:11 +00:00
|
|
|
|
Thread.Sleep(50);
|
2025-01-04 11:26:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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(); // 初始化每个元素
|
|
|
|
|
}
|
|
|
|
|
// Console.WriteLine();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-07 11:46:11 +00:00
|
|
|
|
//分数long 000000000
|
|
|
|
|
private long score = 0;
|
|
|
|
|
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键
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 键盘监听方法
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void KeyboardMapping()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 创建一个字典来跟踪每个按键的前一次状态
|
|
|
|
|
var keyStates = new System.Collections.Generic.Dictionary<int, bool>
|
|
|
|
|
{
|
|
|
|
|
{ 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)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 检查并处理所有监控的按键状态变化
|
|
|
|
|
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(10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
case VK_G:
|
|
|
|
|
isDown[2] = true;
|
|
|
|
|
// 处理G键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
case VK_SPACE:
|
|
|
|
|
isDown[3] = true;
|
|
|
|
|
// 处理空格键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
case VK_J:
|
|
|
|
|
isDown[4] = true;
|
|
|
|
|
// 处理J键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
case VK_K:
|
|
|
|
|
isDown[5] = true;
|
|
|
|
|
// 处理K键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
case VK_L:
|
|
|
|
|
isDown[6] = true;
|
|
|
|
|
// 处理L键被按下的逻辑
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
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;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-04 11:26:18 +00:00
|
|
|
|
}
|