1

苦労している問題があります。キーボードを使用して画像を左、右、上または下、斜めに移動したいです。ウェブを検索したところ、2 つの異なるキーを使用するには、前のキーを覚えておく必要があることがわかりました。そのために、bool 辞書を使用しています。

私のメイン Form クラスでは、これは KeyDown イベントがどのように見えるかです:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    baseCar.carAccelerate(e.KeyCode.ToString().ToLower());
    carBox.Refresh(); //carbox is a picturebox in my form that store the image I want to move.
}

私のKeyUpイベント:

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    baseCar.carBreak(e.KeyCode.ToString().ToLower());
}

私のペイントイベント:

private void carBox_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(Car, baseCar.CharPosX, baseCar.CharPosY); // Car is just an image
}

そして私のbaseCarクラス:

private Dictionary KeysD = new Dictionary(); // there is a method to set the W|A|S|D Keys, like: KeysD.Add("w",false)

public void carAccelerate(string moveDir)
{       
    KeysD[moveDir] = true;
    moveBeta();
}
public void moveBeta()
{
    if (KeysD["w"])
    {
        this.CharPosY -= this.carMoveYSpeed;
    }
    if (KeysD["s"])
    {
        CharPosY += carMoveYSpeed;
    }
    if (KeysD["a"])
    {
        CharPosX -= carMoveXSpeed;
    }
    if (KeysD["d"])
    {
        CharPosX += carMoveXSpeed;
    }
}
public void carBreak(string str)
{
    KeysD[str] = false;
}

とにかく動作しますが、私の問題は、たとえば最初に押されたキーに戻れないことです:

W を押して上に移動し、D キーを押して対角線に移動しましたが、D キーを離しても、KeyDown イベントが「死んで」おり、carAccelerate() メソッドを再度呼び出さないため、再び上に移動しません。それを修正する方法を理解していない..

誰でも私を助けてもらえますか?キーを処理するためのより良い方法があるかもしれませんか?私はどんなアイデアにもオープンです!そして、あなたがそれを理解してくれることを願っています、私の英語は最高ではありません:S

4

1 に答える 1

1

通常、これらの種類のキー イベントを直接処理することはありません。代わりに、現在押されているキーを追跡します。物理計算は一定の間隔で行われ、タイマーで行うことができます。以下の簡単で汚い例。ただし、これは WinForms で試みるべきことではありません。

    private const int ACCELERATION = 1;

    private HashSet<Keys> pressed;
    private int velocityX = 0;
    private int velocityY = 0;

    public Form1()
    {
        InitializeComponent();
        pressed = new HashSet<Keys>();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        pressed.Add(e.KeyCode);
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        pressed.Remove(e.KeyCode);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        car.Location = new Point(
            car.Left + velocityX,
            car.Top + velocityY);
        if (pressed.Contains(Keys.W)) velocityY -= ACCELERATION;
        if (pressed.Contains(Keys.A)) velocityX -= ACCELERATION;
        if (pressed.Contains(Keys.S)) velocityY += ACCELERATION;
        if (pressed.Contains(Keys.D)) velocityX += ACCELERATION;
    }
于 2013-01-22T14:02:37.633 に答える