如何在 C# 中正确移动 PictureBox
How to properly move a PictureBox in C#
我正在尝试使用 WSAD 键移动 PictureBox“英雄”。它的工作原理,但只要按下 2 个按钮,它就会向按下的最旧按钮的方向移动(应该如此),但是当其中一个按钮被释放时,在它再次移动之前会有轻微的延迟。有人知道如何解决这个问题吗?
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.S:
hero.SetDirection("down");
break;
case Keys.W:
hero.SetDirection("up");
break;
case Keys.D:
hero.SetDirection("right");
break;
case Keys.A:
hero.SetDirection("left");
break;
}
hero.heroTimer.Start();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.S || e.KeyCode == Keys.W || e.KeyCode == Keys.A || e.KeyCode == Keys.D)
{
hero.SetDirection("");
hero.heroTimer.Stop();
}
}
这是来自class英雄
private void heroTimer_Tick(object sender, EventArgs e)
{
switch (direction)
{
case "down":
this.Top += 5;
break;
case "up":
this.Top -= 5;
break;
case "left":
this.Left -= 5;
break;
case "right":
this.Left += 5;
break;
}
}
P.S如果代码比较乱,我很抱歉,我是新手。
but when one of the buttons are released, there is a slight delay before it moves again
可能是因为松开任何一个按钮都会停止计时器。解决这个问题的一种方法是保留一个被按下的键列表,并且仅在所有键都被释放时才停止计时器。这也可以让您应用多个移动,即向下+向左将沿对角线移动图片。您可能还想在按下某个键时直接调用 heroTimer_Tick
方法,以便在与按键相同的帧上开始移动。
我还建议根据事件之间的实际时间来调整你的运动。如果 UI 线程忙于做其他事情,Winforms 计时器事件可能会延迟,甚至完全忽略。因此,秒表可能有助于准确测量每个事件之间的时间并允许您缩放运动。
在游戏中使用共同的更新时钟是相当普遍的。与其使用不同计时器的多个组件,不如使用一个以固定速率、尽可能快或尽可能快地达到某个最大帧速率的单个计时器。然后这个计时器会调用所有游戏组件的更新方法,通常带有一个增量时间参数。这往往会提供更一致的行为,因为所有组件在每一帧都以相同的顺序更新。
最后,使用字符串来存储移动不是一个好的做法,并且可能会导致编译器无法检测到问题。枚举将是更合适的类型来描述运动。可选择使用 [Flags] 属性和单独的位来同时描述多个动作。
我正在尝试使用 WSAD 键移动 PictureBox“英雄”。它的工作原理,但只要按下 2 个按钮,它就会向按下的最旧按钮的方向移动(应该如此),但是当其中一个按钮被释放时,在它再次移动之前会有轻微的延迟。有人知道如何解决这个问题吗?
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.S:
hero.SetDirection("down");
break;
case Keys.W:
hero.SetDirection("up");
break;
case Keys.D:
hero.SetDirection("right");
break;
case Keys.A:
hero.SetDirection("left");
break;
}
hero.heroTimer.Start();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.S || e.KeyCode == Keys.W || e.KeyCode == Keys.A || e.KeyCode == Keys.D)
{
hero.SetDirection("");
hero.heroTimer.Stop();
}
}
这是来自class英雄
private void heroTimer_Tick(object sender, EventArgs e)
{
switch (direction)
{
case "down":
this.Top += 5;
break;
case "up":
this.Top -= 5;
break;
case "left":
this.Left -= 5;
break;
case "right":
this.Left += 5;
break;
}
}
P.S如果代码比较乱,我很抱歉,我是新手。
but when one of the buttons are released, there is a slight delay before it moves again
可能是因为松开任何一个按钮都会停止计时器。解决这个问题的一种方法是保留一个被按下的键列表,并且仅在所有键都被释放时才停止计时器。这也可以让您应用多个移动,即向下+向左将沿对角线移动图片。您可能还想在按下某个键时直接调用 heroTimer_Tick
方法,以便在与按键相同的帧上开始移动。
我还建议根据事件之间的实际时间来调整你的运动。如果 UI 线程忙于做其他事情,Winforms 计时器事件可能会延迟,甚至完全忽略。因此,秒表可能有助于准确测量每个事件之间的时间并允许您缩放运动。
在游戏中使用共同的更新时钟是相当普遍的。与其使用不同计时器的多个组件,不如使用一个以固定速率、尽可能快或尽可能快地达到某个最大帧速率的单个计时器。然后这个计时器会调用所有游戏组件的更新方法,通常带有一个增量时间参数。这往往会提供更一致的行为,因为所有组件在每一帧都以相同的顺序更新。
最后,使用字符串来存储移动不是一个好的做法,并且可能会导致编译器无法检测到问题。枚举将是更合适的类型来描述运动。可选择使用 [Flags] 属性和单独的位来同时描述多个动作。