2016-11-26 44 views
0

我正在创建一个Galaga类型的游戏,我将重点放在船的移动上。我有这个代码:我该如何检查键盘状态?而不是使用事件处理程序

public partial class MainWindow : Window 
{   
    public MainWindow() 
    { 
     InitializeComponent(); 
    }  

    private void Window_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Left) 
     { 
      moveLeft(); 
     } 
     else if (e.Key == Key.Right) 
     { 
      moveRight(); 
     } 
     else if (e.Key == Key.Space) 
     { 
      bullet(); 
     } 
    } 

    private async void bullet() 
    { 
     Line bullet = new Line(); 
     bullet.X1 = Canvas.GetLeft(testMovement) + (testMovement.Width/2); 
     bullet.Y1 = Canvas.GetTop(testMovement); 

     bullet.X2 = bullet.X1; 
     bullet.Y2 = bullet.Y1 + 3; 

     bullet.Stroke = new SolidColorBrush(Color.FromRgb(255,255,255)); 
     bullet.StrokeThickness = 3; 

     horizontalMove.Children.Add(bullet); 

     for (int i = 0; i < 50; i++) 
     { 
      await Task.Delay(20); 
      shoot(bullet); 
     } 

     horizontalMove.Children.Remove(bullet); 
    } 

    private void shoot(Line bullet) 
    {   
      bullet.Y2 = bullet.Y1; 
      bullet.Y1 -= 5; 
    } 

    int x = 0; 
    private void moveRight() 
    { 
     if (x>=0 && x <= 370) 
     { 
      if(x == 370) 
      { 
       x -= 10; 
      } 
      Canvas.SetLeft(testMovement, x += 10); 
     } 
     else 
     { 
      if (x < 0) 
       x = 0; 
      else 
       x = 370; 
     } 
     label.Content = x ; 
    } 

    private void moveLeft() 
    { 
     if (x>=0 && x <= 370) 
     { 
      if (x == 0) 
      { 
       x += 10; 
      } 
      Canvas.SetLeft(testMovement, x -= 10); 
     } 
     else 
     { 
      if (x < 0) 
       x = 0; 
      else 
       x = 370; 
     } 
     label.Content = x; 
    } 

    private void Window_KeyUp(object sender, KeyEventArgs e) {} 

} 

这个代码的问题是,当我改变方向时,它有一定的延迟,动画不是那么平滑。

因此,如果我不想使用事件处理程序来不断检查键盘的状态(例如,是否单击左键,右键或空格),应如何继续?

+0

首先,我想更换别的'地狱if'用开关 – Qrchack

+0

此外,什么是运动应该是什么样子的?你不断前进,只是转向左/右? – Qrchack

+0

其简单的左右水平移动。并且空间会垂直拍摄子弹 – Danny

回答

2

使用您的代码,您在等待移动播放器之前发生的事件。这是游戏开发中常被误解的一个方面。 SDL库的手册有a great explaination

键盘事件仅发生在被 未按到按下按键的状态变化,反之亦然。

int alien_x=0, alien_y=0; 

/* Main game loop */ 

/* Check for events */ 
while(SDL_PollEvent(&event)){ 
    switch(event.type){ 
     /* Look for a keypress */ 
     case SDL_KEYDOWN: 
      /* Check the SDLKey values and move change the coords */ 
      switch(event.key.keysym.sym){ 
       case SDLK_LEFT: 
        alien_x -= 1; 
        break; 
       case SDLK_RIGHT: 
        alien_x += 1; 
        break; 
       case SDLK_UP: 
        alien_y -= 1; 
        break; 
       case SDLK_DOWN: 
        alien_y += 1; 
        break; 
       default: 
        break; 
      } 
     } 
    } 
} 

乍一看,你可能会认为这是一个完全合理的一块为任务 代码,但事实并非如此。就像我说的键盘事件只有当一个按键发生改变时才会出现 状态,所以用户将不得不按下和 释放左侧光标键100次,将外部100个像素移动到 的左侧。为了解决这个问题,我们不能使用事件来改变外星人的位置,我们使用事件来设置标志,然后在代码的单独部分中使用 来移动外星人。 事情是这样的:

int alien_x=0, alien_y=0; 
int alien_xvel=0, alien_yvel=0; 

/* Main game loop */ 

/* Check for events */ 
while(SDL_PollEvent(&event)){ 
    switch(event.type){ 
     /* Look for a keypress */ 
     case SDL_KEYDOWN: 
      /* Check the SDLKey values and move change the coords */ 
      switch(event.key.keysym.sym){ 
       case SDLK_LEFT: 
        alien_xvel = -1; 
        break; 
       case SDLK_RIGHT: 
        alien_xvel = 1; 
        break; 
       case SDLK_UP: 
        alien_yvel = -1; 
        break; 
       case SDLK_DOWN: 
        alien_yvel = 1; 
        break; 
       default: 
        break; 
      } 
      break; 
     /* We must also use the SDL_KEYUP events to zero the x */ 
     /* and y velocity variables. But we must also be  */ 
     /* careful not to zero the velocities when we shouldn't*/ 
     case SDL_KEYUP: 
      switch(event.key.keysym.sym){ 
       case SDLK_LEFT: 
        /* We check to make sure the alien is moving */ 
        /* to the left. If it is then we zero the */ 
        /* velocity. If the alien is moving to the */ 
        /* right then the right key is still press */ 
        /* so we don't tocuh the velocity   */ 
        if(alien_xvel < 0) 
         alien_xvel = 0; 
        break; 
       case SDLK_RIGHT: 
        if(alien_xvel > 0) 
         alien_xvel = 0; 
        break; 
       case SDLK_UP: 
        if(alien_yvel < 0) 
         alien_yvel = 0; 
        break; 
       case SDLK_DOWN: 
        if(alien_yvel > 0) 
         alien_yvel = 0; 
        break; 
       default: 
        break; 
      } 
      break; 

     default: 
      break; 
    } 
} 
/* Update the alien position */ 
alien_x += alien_xvel; 
alien_y += alien_yvel; 
+0

我有点理解你的代码的流程,但我不明白什么是所有的SDL _...东西。他们是事件,变量还是别的东西。我仍然在一些基本的C#。 – Danny

+0

这是另一个用C/C++编写的库。事情是,不要在事件循环中移动你的船,因为它会随着你的移动而等待,直到另一个事件发生。当你检查左键是否被按下时,只需设置'ship_xvelocity = -1',然后在实际的绘图代码中移动你的船。 – Qrchack

+0

好的,谢谢。最后一件事,我应该在哪里放置这种循环?我一直在尝试像MainWindow方法那样放入一个循环,但它实际上不会显示任何内容或执行任何操作。 – Danny

相关问题