Answered by:
Reacting on multiple arrow keys simultanously

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: (^_^)
'************************************************************' ' 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 AMAnswerer -
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: (^_^)
'************************************************************' ' 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 AMAnswerer -
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