locked
Reacting on multiple arrow keys simultanously RRS feed

  • Question

  • Hello everyone,

    I have a little problem with a small Jump 'n' Run game I am currently developing involving keyboard input.

    To better illustrate my problem, I've created a small example program (see below). In order to react accordingly to the user input, I want to keep track of the keys currently being pressed. This is achieved by setting a corresponding variable to 1 once the key is being pressed and back to 0 after it got released. As long as only one key is pressed at a time, the source code below works perfectly fine.

    GraphicsWindow.Width = 400
    GraphicsWindow.Height = 200
    GraphicsWindow.Title = "Multiple keys test"
    GraphicsWindow.CanResize = "false"
    GraphicsWindow.KeyDown =  KeyPressed
    GraphicsWindow.KeyUp = KeyReleased
    GraphicsWindow.Show()
    
    leftDown = 0
    rightDown = 0
    upDown = 0
    
    While 1 = 1
      GraphicsWindow.Clear()
      GraphicsWindow.DrawText(50,50, "Left down: " + leftDown)
      GraphicsWindow.DrawText(50,75, "Right down: " + rightDown)
      GraphicsWindow.DrawText(50,100, "Up down: " + upDown)
    
      Program.Delay(30)
    endwhile
    
    Sub KeyPressed
      key = GraphicsWindow.LastKey
      If key = "Left" And leftDown = 0 Then
        leftDown = 1
      EndIf
      If key = "Right" And rightDown = 0 Then
        rightDown = 1
      Endif
      If key = "Up" And upDown = 0 Then
        upDown = 1
      EndIf
    EndSub
      
    Sub KeyReleased
      If key = "Left" Then
        leftDown = 0
      EndIf
      If key = "Right" Then
        rightDown = 0
      endif
      if key = "Up" Then
       upDown = 0 
      EndIf
    EndSub

    The problem arises if for instance the following sequence of key actions is executed:

    • Press "Right" key
    • Press "Up" key
    • Release "Up" key
    • Release "Right" key

    One would expect the program to show all keys as released after this procedure. However, this is not my observed result. For me the "Right" arrow key will still be displayed as pressed, despite it being already released of course. In the context of my Jump 'n' Run game that would mean, that the protagonist keeps running to the right with no keys being pressed.

    Evidently my goal will be to implement a system, which allows to correctly identify the state of each arrow key, while simultaniously allowing more than one key to be pressed at a time, hence eliminating the problem stated above.

    Thanks for reading this so far! If anyone could help me with this problem, I would greatly appreciate it.

    galgtonold

    Sunday, October 13, 2013 10:18 PM

Answers

  • A flickerless version:  (^_^)

    SBR991

    '************************************************************'
    ' Multiple Keys Test (v2.03)
    ' by  galgtonold (2013/Oct)
    ' mod GoToLoop
    
    ' SBR991
    
    ' http://social.msdn.microsoft.com/Forums/en-US/
    ' fea3b8a2-ee28-45dc-a06b-0dd0c4754e24/
    ' reacting-on-multiple-arrow-keys-simultanously
    '************************************************************'
    
    '---------------------------------------------------------------------------'
    GW = 150
    GH = 150
    
    isUp = "False"
    isDown = "False"
    isLeft = "False"
    isRight = "False"
    
    isWaitingKey = "True"
    '---------------------------------------------------------------------------'
    GraphicsWindow.Title = "Mult Keys"
    GraphicsWindow.CanResize = "False"
    GraphicsWindow.BackgroundColor = "MidnightBlue"
    
    GraphicsWindow.Width  = GW
    GraphicsWindow.Height = GH
    
    CreateLabels()
    
    GraphicsWindow.KeyDown =  KeyPressed
    GraphicsWindow.KeyUp = KeyReleased
    '---------------------------------------------------------------------------'
    Loop:
    
    While isWaitingKey
      Program.Delay(10)
    EndWhile
    
    isWaitingKey = "True"
    UpdateLabels()
    
    Goto Loop
    '---------------------------------------------------------------------------'
    Sub KeyPressed
      
      k = GraphicsWindow.LastKey
      
      If k = "Up" Then
        isUp = "True"
        
      ElseIf k = "Down" Then
        isDown = "True"
        
      ElseIf k = "Left" Then
        isLeft = "True"
        
      ElseIf k = "Right" Then
        isRight = "True"
        
      ElseIf k = "Escape" Then
        Sound.PlayChimeAndWait()
        Program.End()
      EndIf
      
      isWaitingKey = "False"
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub KeyReleased
      
      kk = GraphicsWindow.LastKey
      
      If kk = "Up" Then
        isUp = "False"
        
      ElseIf kk = "Down" Then
        isDown = "False"
        
      ElseIf kk = "Left" Then
        isLeft = "False"
        
      ElseIf kk = "Right" Then
        isRight = "False"
      EndIf
      
      isWaitingKey = "False"
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub CreateLabels
      
      GraphicsWindow.BrushColor = "Gold"
      
      up = Shapes.AddText("Up: False")
      down = Shapes.AddText("Down: False")
      left = Shapes.AddText("Left: False")
      right = Shapes.AddText("Right: False")
      
      Shapes.Move(up  40, 25)
      Shapes.Move(down  40, 50)
      Shapes.Move(left  40, 75)
      Shapes.Move(right  40, 100)
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub UpdateLabels
      
      Shapes.SetText(up  "Up: " + isUp)
      Shapes.SetText(down  "Down: " + isDown)
      Shapes.SetText(left  "Left: " + isLeft)
      Shapes.SetText(right  "Right: " + isRight)
      
    EndSub
    '---------------------------------------------------------------------------'


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    • Edited by GoToLoopEditor Monday, October 14, 2013 3:01 AM
    • Marked as answer by galgtonold Monday, October 14, 2013 6:08 PM
    Monday, October 14, 2013 2:28 AM
    Answerer
  • Hi galgtonold

    This situation is because the variable "key" is equal to the last key pressed as set in the KeyPressed Subroutine only.

    So

    • Press "Right" key  = 1st key pressed
    • Press "Up" key   =  last  key pressed
    • Release "Up" key  --->  key  is still set as "Up"
    • Release "Right" key  ---->  key isn't set

    Copy this line "key = GraphicsWindow.LastKey"  into the  Key Released Subroutine and the problem is fixed.


    • Edited by Jibba j Monday, October 14, 2013 12:44 AM addd
    • Proposed as answer by litdev Monday, October 14, 2013 5:52 PM
    • Marked as answer by galgtonold Monday, October 14, 2013 6:07 PM
    Monday, October 14, 2013 12:43 AM

All replies

  • Hi galgtonold

    This situation is because the variable "key" is equal to the last key pressed as set in the KeyPressed Subroutine only.

    So

    • Press "Right" key  = 1st key pressed
    • Press "Up" key   =  last  key pressed
    • Release "Up" key  --->  key  is still set as "Up"
    • Release "Right" key  ---->  key isn't set

    Copy this line "key = GraphicsWindow.LastKey"  into the  Key Released Subroutine and the problem is fixed.


    • Edited by Jibba j Monday, October 14, 2013 12:44 AM addd
    • Proposed as answer by litdev Monday, October 14, 2013 5:52 PM
    • Marked as answer by galgtonold Monday, October 14, 2013 6:07 PM
    Monday, October 14, 2013 12:43 AM
  • Here's a sample for the above: FTW338

    Monday, October 14, 2013 1:14 AM
  • A flickerless version:  (^_^)

    SBR991

    '************************************************************'
    ' Multiple Keys Test (v2.03)
    ' by  galgtonold (2013/Oct)
    ' mod GoToLoop
    
    ' SBR991
    
    ' http://social.msdn.microsoft.com/Forums/en-US/
    ' fea3b8a2-ee28-45dc-a06b-0dd0c4754e24/
    ' reacting-on-multiple-arrow-keys-simultanously
    '************************************************************'
    
    '---------------------------------------------------------------------------'
    GW = 150
    GH = 150
    
    isUp = "False"
    isDown = "False"
    isLeft = "False"
    isRight = "False"
    
    isWaitingKey = "True"
    '---------------------------------------------------------------------------'
    GraphicsWindow.Title = "Mult Keys"
    GraphicsWindow.CanResize = "False"
    GraphicsWindow.BackgroundColor = "MidnightBlue"
    
    GraphicsWindow.Width  = GW
    GraphicsWindow.Height = GH
    
    CreateLabels()
    
    GraphicsWindow.KeyDown =  KeyPressed
    GraphicsWindow.KeyUp = KeyReleased
    '---------------------------------------------------------------------------'
    Loop:
    
    While isWaitingKey
      Program.Delay(10)
    EndWhile
    
    isWaitingKey = "True"
    UpdateLabels()
    
    Goto Loop
    '---------------------------------------------------------------------------'
    Sub KeyPressed
      
      k = GraphicsWindow.LastKey
      
      If k = "Up" Then
        isUp = "True"
        
      ElseIf k = "Down" Then
        isDown = "True"
        
      ElseIf k = "Left" Then
        isLeft = "True"
        
      ElseIf k = "Right" Then
        isRight = "True"
        
      ElseIf k = "Escape" Then
        Sound.PlayChimeAndWait()
        Program.End()
      EndIf
      
      isWaitingKey = "False"
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub KeyReleased
      
      kk = GraphicsWindow.LastKey
      
      If kk = "Up" Then
        isUp = "False"
        
      ElseIf kk = "Down" Then
        isDown = "False"
        
      ElseIf kk = "Left" Then
        isLeft = "False"
        
      ElseIf kk = "Right" Then
        isRight = "False"
      EndIf
      
      isWaitingKey = "False"
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub CreateLabels
      
      GraphicsWindow.BrushColor = "Gold"
      
      up = Shapes.AddText("Up: False")
      down = Shapes.AddText("Down: False")
      left = Shapes.AddText("Left: False")
      right = Shapes.AddText("Right: False")
      
      Shapes.Move(up  40, 25)
      Shapes.Move(down  40, 50)
      Shapes.Move(left  40, 75)
      Shapes.Move(right  40, 100)
      
    EndSub
    '---------------------------------------------------------------------------'
    Sub UpdateLabels
      
      Shapes.SetText(up  "Up: " + isUp)
      Shapes.SetText(down  "Down: " + isDown)
      Shapes.SetText(left  "Left: " + isLeft)
      Shapes.SetText(right  "Right: " + isRight)
      
    EndSub
    '---------------------------------------------------------------------------'


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    • Edited by GoToLoopEditor Monday, October 14, 2013 3:01 AM
    • Marked as answer by galgtonold Monday, October 14, 2013 6:08 PM
    Monday, October 14, 2013 2:28 AM
    Answerer
  • Thank you everyone for your quick responses, you allowed me to solve my problem. Although it makes me feel quite stupid unfortunately...

    I am just too used to working with programming languages where that last key would be provided as a paramter.

    Thanks again also for the flickerless version, I already was aware of how to implement it, I just implemented the other version, as it was shorter to write. ;)

    Monday, October 14, 2013 6:12 PM