0

我正在尝试制作一个移动图片框(带有我的“播放器”的图像),这一切都很好,但我遇到了 Windows 字符延迟的问题。
对于不知道这是什么的你:如果你按住一个键,windows 会打印它,稍等片刻,然后发送垃圾邮件。

所以发生的事情是我的玩家移动了 10px 等待,然后按照它应该的方式移动。

搬家代码:

if (e.KeyCode == Keys.Left)
{
    if (shipBox.Left >= 7)
    {
        shipBox.Left -= 10;
    }
}
if (e.KeyCode == Keys.Right)
{
    if (shipBox.Left <= 375)
    {
        shipBox.Left += 10;
    }
}
if (e.KeyCode == Keys.Up)
{
    if (shipBox.Top >= 120)
    {
        shipBox.Top -= 10;
    }
}
if (e.KeyCode == Keys.Down)
{
    if (shipBox.Top <= 520)
    {
        shipBox.Top += 10;
    }
}
4

2 回答 2

1

有一种解决方法

基本上,您有一个计时器,它将以您选择的固定间隔移动图片

打开计时器以继续前进,OnKeyDown然后将其关闭OnKeyUp。确保OnKeyDown您提供可以移动的 X/Y 坐标。OnKeyUp并在事件中重置该值。

public class MyForm : Form
{
    private int deltaX;
    private int deltaY;

    private const int movementAmount = 10;

    private Timer movementTimer = new Timer();

    public MyForm()
    {
        movementTimer.Interval = 100; // make this whatever interval you'd like there to be in between movements

        movementTimer.Tick += new EventHandler(movementTimer_Tick);
    }

    void movementTimer_Tick(object sender, EventArgs e)
    {
        myMonster.Location = new Point(myMonster.X + deltaX, myMonster.Y + deltaY);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        switch (e.KeyCode)
        {
            case Keys.Left:
                {
                    deltaX -=movementAmount;
                } break;
            case Keys.Right:
                {
                    deltaX += movementAmount;
                } break;
            case Keys.Up:
                {
                    deltaY -= movementAmount;
                } break;
            case Keys.Down:
                {
                    deltaY += movementAmount;
                } break;
        }

        UpdateTimer();
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);

        switch (e.KeyCode)
        {
            case Keys.Left:
                {
                    deltaX += movementAmount;
                } break;
            case Keys.Right:
                {
                    deltaX -= movementAmount;
                } break;
            case Keys.Up:
                {
                    deltaY += movementAmount;
                } break;
            case Keys.Down:
                {
                    deltaY -= movementAmount;
                } break;
        }

        UpdateTimer();
    }

    private void UpdateTimer()
    {
        movementTimer.Enabled = deltaX != 0 || deltaY != 0;
    }
}

注意:Switch..Case当你有很多条件时尝试

于 2013-10-18T09:31:18.010 回答
0

我想您正在尝试创建某种游戏。如果您希望播放器的移动流畅,则不应更新播放器图像的位置,或在键盘/鼠标事件处理程序中重绘其图像。相反,您应该实现某种主循环(在单独的线程中,计时器回调函数,或者可能在主窗口循环中),它将根据当前按下的键和自上次更新以来经过的时间更新播放器的屏幕位置和重绘它。

于 2013-10-18T09:30:53.747 回答