我已经开始学习一些Microsoft.DirectX 3D基本技术,并且碰到了这个对我来说太难的问题。我已经创建了3D场景,相机,灯光等,并绘制了一些简单的3D对象。我现在要做的是围绕所有三个轴简单地旋转对象。为此我想使用Arrow和ASWD键盘键,就像在计算机游戏中一样。为此,我使用了OnKeyDown和OnKeyUp事件处理程序:
#region - Event handler -
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
#region - speed -
if(e.KeyValue == (char)Keys.Add || e.KeyValue == (char)Keys.Oemplus)
step_p = true;
if(e.KeyValue == (char)Keys.Subtract || e.KeyValue == (char)Keys.OemMinus)
step_m = true;
if(step_p)
step++;
if(step_m)
step--;
if(step==0)
step = 1;
#endregion
#region - rotation -
if(e.KeyCode == Keys.Left)
{
left = true;
}
if(e.KeyCode == Keys.Right)
{
right = true;
}
if(e.KeyCode == Keys.Up)
{
up = true;
}
if(e.KeyCode == Keys.Down)
{
down = true;
}
if(e.KeyCode == Keys.A)
{
a = true;
}
if(e.KeyCode == Keys.D)
{
d = true;
}
if(left)
angleZ_D+=step;
if(right)
angleZ_D-=step;
if(up)
angleX_D-=step;
if(down)
angleX_D+=step;
if(a)
angleY_D+=step;
if(d)
angleY_D-=step;
//
//
//
if(angleX_D == 360)
angleX_D = 0;
if(angleY_D >= 360)
angleY_D = 0;
if(angleZ_D >= 360)
angleZ_D = 0;
angleX_R = angleX_D * rad;
angleY_R = angleY_D * rad;
angleZ_R = angleZ_D * rad;
//
//
//
#endregion
#region - zoom -
if(e.KeyValue == (char)Keys.W)
{
w = true;
}
if(e.KeyValue == (char)Keys.S)
{
s = true;
}
if(w)
{
zoom+=0.1f * step;
if(zoom>10.0f) zoom=10.0f;
}
if(s)
{
zoom-=0.1f * step;
if(zoom<1.0f) zoom=1.0f;
}
#endregion
Draw();
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
#region - speed -
if(e.KeyValue == (char)Keys.Add || e.KeyValue == (char)Keys.Oemplus)
step_p = false;
if(e.KeyValue == (char)Keys.Subtract || e.KeyValue == (char)Keys.OemMinus)
step_m = false;
#endregion
#region - rotation -
if(e.KeyCode == Keys.Left)
{
left = false;
}
if(e.KeyCode == Keys.Right)
{
right = false;
}
if(e.KeyCode == Keys.Up)
{
up = false;
}
if(e.KeyCode == Keys.Down)
{
down = false;
}
if(e.KeyCode == Keys.A)
{
a = false;
}
if(e.KeyCode == Keys.D)
{
d = false;
}
#endregion
#region - zoom -
if(e.KeyValue == (char)Keys.W)
{
w = false;
}
if(e.KeyValue == (char)Keys.S)
{
s = false;
}
#endregion
Draw();
}
这就是问题所在:
当我按下 A 键并按住它时我按下键 W ,程序运行正常但是当我释放键 W 时处理程序无法识别仍然按下 A 键。
C#4.0和.Net framework 2.0中是否存在解决此问题的方法
一切顺利, ŽeljkoPerić
根据
引用: 您按照键盘按下时重复按键。 按下另一个键后,它就会停止工作。 您需要使用Timer并在Tick事件处理程序中 检查你想要移动的方式。现在关键重复不再重要。 将计时器的Interval属性设置为15或31以获得良好的一致性。 - Hans Passant
这是问题解决方案:
using System; using System.Windows.Forms; namespace WASD_keyboard_game_control { public partial class MainForm : Form { // // Global variables declaration // // // Timer // // Implements a timer that // raises event at user defined interval // Timer Clock; // // Set Timer tick Interval in miliseconds // // By changing value of Interval, // we control how often the timer tick event handler is raised // and eventually the call frequency of Main_Function() // const int Interval = 15; // // Variables for counting the number // of times that program has confirmed // the key down state of AWSD keys // int W = 0; int A = 0; int S = 0; int D = 0; // // Variables ( flags ) for memorizing // the key down state of AWSD keys // // true - key is down ( pressed ) // // false - key is up ( released ) // // bool w = false; bool a = false; bool s = false; bool d = false; // // // public MainForm() { // // The InitializeComponent() call is required // for Windows Forms designer support. // InitializeComponent(); // // Call Initialize_Timer() function // Initialize_Timer(); } void Initialize_Timer() { // Create new timer Clock = new Timer(); // Set timer tick interval in miliseconds // // By changing value of interval, // we control how often the timer tick event handler is raised // and eventually the call frequency of Main_Function() // Clock.Interval = Interval; // // Add timer tick event handler // // This event handler is raised // every time timer make tick // // The smaler value for timer interval, // more often the event handler is raised // Clock.Tick += new System.EventHandler(this.ClockTick); // // Start timer // Clock.Start(); } void ClockTick(object sender, EventArgs e) { // // Timer tick event handler // // // Call Main_Function() // Main_Function(); // // // } protected override void OnKeyDown(KeyEventArgs e) { // // This event handler is raised every time // some key on the keyboard is first pressed // base.OnKeyDown(e); // // Set corresponding key down flag state to true // if(e.KeyCode == Keys.W) w = true; if(e.KeyCode == Keys.A) a = true; if(e.KeyCode == Keys.S) s = true; if(e.KeyCode == Keys.D) d = true; } protected override void OnKeyUp(KeyEventArgs e) { // // This event handler is raised every time // some key on the keyboard is released // base.OnKeyUp(e); // // Set corresponding key down flag state to false // if(e.KeyCode == Keys.W) w = false; if(e.KeyCode == Keys.A) a = false; if(e.KeyCode == Keys.S) s = false; if(e.KeyCode == Keys.D) d = false; } void Main_Function() { // // Main function // // // This function is called every time the // timer tick event handler is raised // // // This function determines wich key is pressed // upon key down flag value and updates correspondig counter value // // Counter value shows how many times program has confirmed the // key down state and not how many times user has pressed the key // // // Increase counter value if key is down // if(a) A++; if(s) S++; if(w) W++; if(d) D++; // // Show values of counters // Label_A.Text = "A = " + A.ToString(); Label_S.Text = "S = " + S.ToString(); Label_W.Text = "W = " + W.ToString(); Label_D.Text = "D = " + D.ToString(); } } }