如何在 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] 属性和单独的位来同时描述多个动作。