简体   繁体   English

C#WPF游戏键盘动作

[英]C# WPF keyboard movement for game

I'm trying to make a small game in c# using wpf. 我正在尝试使用WPF在C#中制作一个小型游戏。 I have my rectangle moving around, the problem I am trying to fix is if you press another key well holding the original key, then release one of them it will go in the direction being held. 我的矩形移动了,我要解决的问题是,如果您按住另一个键并同时按住原始键,然后松开其中一个,它将朝着所保持的方向移动。 The code I have works but if ran once a key is released there is a delay then the rectangle will continue moving. 我拥有的代码有效,但是一旦释放键就运行了,则会有延迟,则矩形将继续移动。

    enum Direction { left, right, up, down, none};
    Direction _direction = Direction.none;
    bool _directionIsPressed = false;
    bool _directionIsReleased = false;
    double x = 0;
    double y = 0;

    public MainWindow()
    {
        InitializeComponent();



        DispatcherTimer timer = new DispatcherTimer();
        timer.Tick += new EventHandler(MovePlayer);
        timer.Start();

        this.KeyDown += new KeyEventHandler(OnButtonKeyDown);
        this.KeyUp += new KeyEventHandler(OnButtonKeyRelease);

    }

    private void MovePlayer(object sender, EventArgs e)
    {
        switch (_direction)
        {
            case Direction.down:
                y += .05;
                Canvas.SetTop(Player, y);
                break;
            case Direction.up:
                y -= .05;
                Canvas.SetTop(Player, y);
                break;
            case Direction.left:
                x -= .05;
                Canvas.SetLeft(Player, x);
                break;
            case Direction.right:
                x += .05;
                Canvas.SetLeft(Player, x);
                break;
        }
    }

    private void OnButtonKeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.Down:
                _direction = Direction.down;
                _directionIsPressed = true;
                break;
            case Key.Up:
                _direction = Direction.up;
                _directionIsPressed = true;
                break;
            case Key.Left:
                _direction = Direction.left;
                _directionIsPressed = true;
                break;
            case Key.Right:
                _direction = Direction.right;
                _directionIsPressed = true;
                break;
            default:
                _direction = Direction.none;
                break;
        }
    }

    //When a key is released it will set the direction to none then 
    //reset the direction but there is about a half second delay in 
    //setting the direction again
    private void OnButtonKeyRelease(Object sender, KeyEventArgs e) 
    {
        _direction = Direction.none;
        this.KeyDown += new KeyEventHandler(OnButtonKeyDown);
    }

Edit: If anyone wants smooth keyboard movement in C# using wpf here is how I fixed it. 编辑:如果有人想使用wpf在C#中平稳地移动键盘,这就是我固定的方法。 Thank you Stefan for the help. 谢谢Stefan的帮助。

        public MainWindow()
    {
        InitializeComponent();
        DispatcherTimer timer = new DispatcherTimer();
        timer.Tick += new EventHandler(MovePlayer);
        timer.Start();
    }

    private void MovePlayer(object sender, EventArgs e)
    {
        if(Keyboard.IsKeyDown(Key.Left))
        {
            x -= .05;
            Canvas.SetLeft(Player, x);
        }
        if(Keyboard.IsKeyDown(Key.Up))
        {
            y -= .05;
            Canvas.SetTop(Player, y);
        }
        if(Keyboard.IsKeyDown(Key.Down))
        {
            y += .05;
            Canvas.SetTop(Player, y);
        }
        if(Keyboard.IsKeyDown(Key.Right))
        {
            x += .05;
            Canvas.SetLeft(Player, x);
        }
    }

instead of using two switch statements in different functions, try merging them into one. 而不是在不同的功能中使用两个switch语句,请尝试将它们合并为一个。 The reason for delay could be the overhead required to jump from one function to another. 延迟的原因可能是从一种功能跳到另一种功能所需的开销。

Instead of call MovePlayer() separately, you can try to move the player when the key is pressed. 您可以尝试在按下键时移动播放器,而不是分别调用MovePlayer()。

private void OnButtonKeyDown(object sender, KeyEventArgs e)
{
    switch (e.Key)
    {
        case Key.Down:
            y += .05;
            Canvas.SetTop(Player, y);
            break;
        case Key.Up:
            y -= .05;
            Canvas.SetTop(Player, y);
            break;
        case Key.Left:
            x -= .05;
            Canvas.SetLeft(Player, x);
            break;
        case Key.Right:
            x += .05;
            Canvas.SetLeft(Player, x);
            break;
        default:
            _direction = Direction.none;
            break;
    }
}

if you would like to allow to combine movement, for example up + left together then i you can do it only with the timer and Keyboard.IsKeyDown(key) verification 如果您想允许组合移动,例如向上+向左组合在一起,那么我只能使用计时器和Keyboard.IsKeyDown(key)验证来完成此操作

private void MovePlayer(object sender, EventArgs e)
{
    if (Keyboard.IsKeyDown(Key.Down))
    {
        y += .05;
        Canvas.SetTop(Player, y);
    }
    if(Keyboard.IsKeyDown(Key.Up))
    {
        y -= .05;
        Canvas.SetTop(Player, y);
    }
    if (Keyboard.IsKeyDown(Key.Left))
    {
        x -= .05;
        Canvas.SetLeft(Player, x);
    }
    if (Keyboard.IsKeyDown(Key.Right))
    {
        x += .05;
        Canvas.SetLeft(Player, x);
    }
}

other case, if the movement can be done only in one simple direction at the time, you can check the statements in your KeyReleased routine. 在其他情况下,如果一次只能在一个简单的方向上进行移动,则可以检查KeyReleased例程中的语句。

private void OnButtonKeyRelease(Object sender, KeyEventArgs e) 
{
    if (Keyboard.IsKeyDown(Key.Down))
        _direction = Direction.down;
    else if(Keyboard.IsKeyDown(Key.Up))
        _direction = Direction.up;
    else if (Keyboard.IsKeyDown(Key.Left))
        _direction = Direction.left;
    else if (Keyboard.IsKeyDown(Key.Right))
        _direction = Direction.right;
    else
        _direction = Direction.none;
}

But if you want to press over 2 movement buttons at the same time you need to save it in some array and check witch was pressed later, and set movement depended from this button. 但是,如果您想同时按下两个以上的运动按钮,则需要将其保存在某个数组中,然后检查是否按下了该按钮,然后根据此按钮设置运动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM