使用 KeyDown 事件平滑地移动控件
Move a control smoothly using KeyDown event
我正在尝试使用 Visual Studio Windows 表单应用程序在 C# 中制作一个简单的游戏。我想让用户可以使用相应的键自由地向上、向右、向下和向左移动蓝色框。
我正在使用一个定时器,它每 0.1 秒检测一次盒子的新位置,以及一个实际改变盒子位置的按键事件。
按住键的同时,盒子需要继续朝相应的方向移动。
我的问题是,除了当用户第一次按下某个键时,方框移动一点点并暂停片刻,然后继续移动之外,我当前的程序可以完成这项工作。我想让这个盒子从第一次按键开始移动得更顺畅,而不是那样停顿。这可能很难用文字解释,所以我添加了一个 gif 文件。
有办法解决这个问题吗?这是我当前的代码。
private int posX, posY; //Both initialized in Form Load event
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
posY -= 3;
else if (e.KeyCode == Keys.Right)
posX += 3;
else if (e.KeyCode == Keys.Down)
posY += 3;
else if (e.KeyCode == Keys.Left)
posX -= 3;
}
//Timer ticks every 0.1 second
private void Timer_Tick(object sender, EventArgs e)
{
Box.Location = new Point(posX, posY);
labelPosX.Text = posX.ToString(); //Testing purposes
labelPosY.Text = posY.ToString(); //Testing purposes
}
我很想使用 KeyDown 事件来实现这一点,但如果在真实游戏世界中有更好或更常见的实际使用方式,我也很想知道!
在你的 Timer_Tick
方法中使用 Keyboard.IsKeyDown
方法,不要监听 keydown 事件。
像这样:
double posX, posY;
private void Timer_Tick(object sender, EventArgs e)
{
double velocity = /*(speed: pixels per seconds)*/ 100 * /*(timer tick time in seconds)*/ 0.003;
if (Keyboard.IsKeyDown(Keys.Up))
{
posY -= velocity;
}
else if (Keyboard.IsKeyDown(Keys.Down))
{
posY += velocity;
}
//Also, don't put else here, so you can go diagonally.
if (Keyboard.IsKeyDown(Keys.Left))
{
posX -= velocity;
}
else if (Keyboard.IsKeyDown(Keys.Right))
{
posX += velocity;
}
Box.Location = new Point((int)posX, (int)posY);
labelPosX.Text = posX.ToString(); //Testing purposes
labelPosY.Text = posY.ToString(); //Testing purposes
}
public static class Keyboard
{
private static readonly HashSet<Keys> keys = new HashSet<Keys>();
public static void OnKeyDown(object sender, KeyEventArgs e)
{
if (keys.Contains(e.KeyCode) == false)
{
keys.Add(e.KeyCode);
}
}
public static void OnKeyUp(object sender, KeyEventArgs e)
{
if (keys.Contains(e.KeyCode))
{
keys.Remove(e.KeyCode);
}
}
public static bool IsKeyDown(Keys key)
{
return keys.Contains(key);
}
}
要使用键盘 class,请在 InitializeComponent
方法中设置 Form1 的 KeyDown 和 KeyUp 事件。
KeyDown += Keyboard.OnKeyDown;
KeyUp += Keyboard.OnKeyUp;
你可以通过改变速度来控制它的速度。
我正在尝试使用 Visual Studio Windows 表单应用程序在 C# 中制作一个简单的游戏。我想让用户可以使用相应的键自由地向上、向右、向下和向左移动蓝色框。
我正在使用一个定时器,它每 0.1 秒检测一次盒子的新位置,以及一个实际改变盒子位置的按键事件。 按住键的同时,盒子需要继续朝相应的方向移动。
我的问题是,除了当用户第一次按下某个键时,方框移动一点点并暂停片刻,然后继续移动之外,我当前的程序可以完成这项工作。我想让这个盒子从第一次按键开始移动得更顺畅,而不是那样停顿。这可能很难用文字解释,所以我添加了一个 gif 文件。
有办法解决这个问题吗?这是我当前的代码。
private int posX, posY; //Both initialized in Form Load event
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
posY -= 3;
else if (e.KeyCode == Keys.Right)
posX += 3;
else if (e.KeyCode == Keys.Down)
posY += 3;
else if (e.KeyCode == Keys.Left)
posX -= 3;
}
//Timer ticks every 0.1 second
private void Timer_Tick(object sender, EventArgs e)
{
Box.Location = new Point(posX, posY);
labelPosX.Text = posX.ToString(); //Testing purposes
labelPosY.Text = posY.ToString(); //Testing purposes
}
我很想使用 KeyDown 事件来实现这一点,但如果在真实游戏世界中有更好或更常见的实际使用方式,我也很想知道!
在你的 Timer_Tick
方法中使用 Keyboard.IsKeyDown
方法,不要监听 keydown 事件。
像这样:
double posX, posY;
private void Timer_Tick(object sender, EventArgs e)
{
double velocity = /*(speed: pixels per seconds)*/ 100 * /*(timer tick time in seconds)*/ 0.003;
if (Keyboard.IsKeyDown(Keys.Up))
{
posY -= velocity;
}
else if (Keyboard.IsKeyDown(Keys.Down))
{
posY += velocity;
}
//Also, don't put else here, so you can go diagonally.
if (Keyboard.IsKeyDown(Keys.Left))
{
posX -= velocity;
}
else if (Keyboard.IsKeyDown(Keys.Right))
{
posX += velocity;
}
Box.Location = new Point((int)posX, (int)posY);
labelPosX.Text = posX.ToString(); //Testing purposes
labelPosY.Text = posY.ToString(); //Testing purposes
}
public static class Keyboard
{
private static readonly HashSet<Keys> keys = new HashSet<Keys>();
public static void OnKeyDown(object sender, KeyEventArgs e)
{
if (keys.Contains(e.KeyCode) == false)
{
keys.Add(e.KeyCode);
}
}
public static void OnKeyUp(object sender, KeyEventArgs e)
{
if (keys.Contains(e.KeyCode))
{
keys.Remove(e.KeyCode);
}
}
public static bool IsKeyDown(Keys key)
{
return keys.Contains(key);
}
}
要使用键盘 class,请在 InitializeComponent
方法中设置 Form1 的 KeyDown 和 KeyUp 事件。
KeyDown += Keyboard.OnKeyDown;
KeyUp += Keyboard.OnKeyUp;
你可以通过改变速度来控制它的速度。