重构Music和MusicFrom类,优化键盘监听和按键处理逻辑

This commit is contained in:
muqing 2025-01-07 19:46:11 +08:00
parent 51c5c5d137
commit b75ca2bc5a
4 changed files with 245 additions and 23 deletions

0
.editorconfig Normal file
View File

View File

@ -1,7 +1,6 @@
using System.Diagnostics;
using System.Text;
using ModelingMusic;
namespace Debug.ModelingMusic;
public class Music

View File

@ -1,26 +1,69 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Debug;
using Debug.ModelingMusic;
using NAudio.Wave;
namespace ModelingMusic;
/// <summary>
/// The <c>ModelingMusic</c> namespace contains classes and methods for modeling and manipulating musical data.
/// </summary>
namespace Debug.ModelingMusic;
public class MusicFrom
{
private long time = 0;
int MaxX = 0;
int MaxY = 0;
public MusicFrom()
{
setCharArry();
MaxY = Program.chars.GetLength(0);
MaxX = Program.chars.GetLength(1);
new Thread(PrintCharArray).Start();
new Thread(KeyboardMapping).Start();
new Thread(Run).Start();
}
char[] jianpan = { 'D', 'F', 'G', ' ', 'J', 'K', 'L' };
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'];
public void PrintCharArray()
{
var stopwatch = new Stopwatch();
var stopwatch = new Stopwatch();
int frameCount = 0;
double totalTime = 0;
int i; int j;
@ -50,16 +93,9 @@ public class MusicFrom
}
}
buffer.AppendLine();
//Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.Write(buffer.ToString());
if (time % 1000 == 0)
{
xiantiaoColor = Program.random.Next(0, 2) == 0 ? ConsoleColor.Red : ConsoleColor.Blue;
}
// Console.ForegroundColor = (ConsoleColor)random.Next(0, 16);
Console.ForegroundColor = xiantiaoColor;
buffer.Clear();
for (i = 0; i < b; i++)
{
@ -67,24 +103,43 @@ public class MusicFrom
}
// 打印ASDF HJKL
buffer.AppendLine();
Console.Write(buffer);
buffer.Clear();
// int totalLength = 50;
int totalAs = jianpan.Length;
int spaceBetweenAs = (b - totalAs) / (totalAs - 1);
for (i = 0; i < totalAs; i++)
{
buffer.Clear();
// if (isDown[3] && i == 3)
// {
// // 显示空格键
// // ConsoleKey.Spacebar
// buffer.Append("Spacebar");
// continue;
// }
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);
}
Console.Write(buffer);
// 停止计时并计算本帧的处理时间
stopwatch.Stop();
double elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds;
@ -97,10 +152,14 @@ public class MusicFrom
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(100);
Thread.Sleep(50);
}
}
private void setCharArry()
@ -114,4 +173,174 @@ public class MusicFrom
// Console.WriteLine();
}
}
//分数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;
}
}
}

View File

@ -1,11 +1,6 @@

using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using Debug.ModelingMusic;
using ModelingMusic;
namespace Debug;
/// <summary>
@ -23,16 +18,15 @@ public class Program
{
Console.WriteLine(a);
}
public static void Main(string[] args)
{
Console.Title = "Tools";//设置窗口标题
// 设置控制台输出编码,以支持复杂字符
Console.OutputEncoding = Encoding.UTF8;
Console.Clear();
Console.CursorVisible = false;
_ = new Program();
new MusicFrom();
// _ = new Program();
}
//Y,X