我已经在C#中创建了一个程序,让我的孩子们在阅读音乐时测试它们。它以设定的间隔显示随机音符(由计时器确定),然后根据键盘的输入检查当前显示的音符,看它们是否正确。它工作得很好,除了一次意外按下两个音符的事实,其中第二个音符被认为是后续音符的预期答案,它甚至还没有被显示出来!我假设在音乐键盘上弹奏的音符存储在缓冲区中,然后在下次需要时使用。我希望能够清理干净的石板"当屏幕上显示新笔记时,将忽略任何先前的输入。我很高兴有任何关于如何做到这一点的想法。
部分代码如下:
using System;
using Midi;
using System.Media;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
// Create persistent delegates which we can add and remove to events.
noteOnHandler = new InputDevice.NoteOnHandler(this.NoteOn);
noteOffHandler = new InputDevice.NoteOffHandler(this.NoteOff);
InputDevice preferredInputDevice = InputDevice.InstalledDevices[0];
UseInputDevice(InputDevice.InstalledDevices[0]);
}
private void UseInputDevice(InputDevice newInputDevice)
{
if (newInputDevice == inputDevice)
{
return;
}
if (inputDevice != null)
{
if (inputDevice.IsOpen)
{
if (inputDevice.IsReceiving)
{
inputDevice.StopReceiving();
}
inputDevice.Close();
}
inputDevice.NoteOn -= noteOnHandler;
inputDevice.NoteOff -= noteOffHandler;
}
inputDevice = newInputDevice;
inputDevice.NoteOn += noteOnHandler;
inputDevice.NoteOff += noteOffHandler;
inputDevice.Open();
inputDevice.StartReceiving(null);
}
// Method called when the input device receives a NoteOn message. Updates
// the input status label. Respects GUI thread affinity by invoking to the
// GUI thread if necessary.
public void NoteOn(NoteOnMessage msg)
{
if (button1.Text == "STOP")
{
if (InvokeRequired)
{
BeginInvoke(noteOnHandler, msg);
return;
}
if (string.Equals(String.Format("{0}", msg.Pitch), notename)) { currentscore++; correct[numberofnotes] = true; using (SoundPlayer player = new SoundPlayer("chime_up.wav")) { player.PlaySync(); } }
else { using (SoundPlayer player = new SoundPlayer("klaxon_ahooga.wav")) { player.PlaySync(); } correct[numberofnotes] = false; }
outof++;
score.Text = String.Format("{0}", currentscore);
notesshown.Text = String.Format("{0}", outof);
numberofticks = 0;
if (outof < 20) { generate_note(); }
Redrawit();
Invalidate();
if (outof == 20) { reset_screen(); }
}
}
// Method called when the input device receives a NoteOff message. Updates
// the input status label. Respects GUI thread affinity by invoking to the
// GUI thread if necessary.
public void NoteOff(NoteOffMessage msg)
{
if (InvokeRequired)
{
BeginInvoke(noteOffHandler, msg);
return;
}
}
// Persistent delegate objects for the note handlers.
private InputDevice.NoteOnHandler noteOnHandler;
private InputDevice.NoteOffHandler noteOffHandler;
}
}