Results 1 to 15 of 15

Thread: How To Use Multiple GetAsyncKeystate Keys?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Exclamation How To Use Multiple GetAsyncKeystate Keys?

    This code works great for single keys pressed, but I am looking to use this to make a graphic move using two keys. For instance, this code makes the graphic move up, down, left, & right. How about using Up-Left to make the graphic move diagonally Up-Left? Here's the code I have so far, but still need to know how to make the graphic move diagonally...

    Create a Class and add the following...
    Code:
    Option Explicit
    
    Public Enum enmDirection
      kDirLeft = 1
      kDirUp = 2
      kDirRight = 4
      kDirDown = 8
    End Enum
    
    Event StateChange(ByVal Up As Boolean)
     
    Public State As enmDirection
    
    Public Sub ProcessKeyEvt(KeyCode As Integer, ByVal Up As Boolean)
      Dim D As enmDirection: D = State
      Select Case KeyCode
        Case 37, 65: D = IIf(Up, D And Not kDirLeft, D Or kDirLeft)
        Case 38, 87: D = IIf(Up, D And Not kDirUp, D Or kDirUp)
        Case 39, 68: D = IIf(Up, D And Not kDirRight, D Or kDirRight)
        Case 40, 83: D = IIf(Up, D And Not kDirDown, D Or kDirDown)
      End Select
      If D <> State Then State = D: RaiseEvent StateChange(Up)
    End Sub
    Added to Form1...
    Code:
    Option Explicit
    
    Private WithEvents GK As cGameKeys, x, y
    
    Private Sub Form_Load()
      KeyPreview = True: ScaleMode = vbPixels: DrawWidth = 12
      x = ScaleWidth \ 2: y = ScaleHeight \ 2
      Set GK = New cGameKeys
      Timer1.Enabled = False: Timer1.Interval = 50
    End Sub
    
    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
      GK.ProcessKeyEvt KeyCode, False
    End Sub
    
    Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
      GK.ProcessKeyEvt KeyCode, True
    End Sub
    
    Private Sub GK_StateChange(ByVal Up As Boolean)
      Debug.Print "Key-"; IIf(Up, "Up", "Down"), GK.State
      Timer1.Enabled = GK.State: If Not Up Then Timer1_Timer
    End Sub
    
    Private Sub Timer1_Timer()
     If GK.State And kDirLeft Then x = x - 1
     If GK.State And kDirUp Then y = y - 1
     If GK.State And kDirRight Then x = x + 1
     If GK.State And kDirDown Then y = y + 1
     If GK.State Then Cls: PSet (x, y), vbRed: Caption = x & ", " & y
    End Sub

  2. #2
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: How To Use Multiple GetAsyncKeystate Keys?

    i wrote in the other thread about how to do it, but u didnt reply.

    use VB own _KeyDown and _KeyUp

    in _KeyDown:
    Code:
    Select Case KeyCode
    Case 37: Keys.Left = True
    Case 38: Keys.Up = True
    Case 39: Keys.Right = True
    Case 40: Keys.Down = True
    End Select
    in _KeyUp
    Code:
    Select Case KeyCode
    Case 37: Keys.Left = False
    Case 38: Keys.Up = False
    Case 39: Keys.Right = False
    Case 40: Keys.Down = False
    End Select
    Keys is a type to store what keys are pressed.
    should be self explanatory what to do next.

    Also, I would use a "Picturebox" where the "game" is rendered not directly into the Form.
    So I would use the Pictureobox _Key Events.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Baka, your code is for single keys pressed by themselves. I am looking for two keys pressed at the same time.

  4. #4
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Im doing a game myself and it works without issues. otherwise i would not suggest it.
    i can press 2 keys simultaneously.
    also, in the "game-loop", i use
    Code:
    If Keys.Up Then .m.Y = .m.Y - .sp:  If .m.Y < 0 Then .m.Y = 0
    If Keys.Down Then .m.Y = .m.Y + .sp:  If .m.Y > .AreaH Then .m.Y = .AreaH
    If Keys.Left Then .m.X = .m.X - .sp:  If .m.X < 0 Then .m.X = 0
    If Keys.Right Then .m.X = .m.X + .sp:  If .m.X > .AreaW Then .m.X = .AreaW
    Last edited by baka; Mar 12th, 2018 at 10:04 AM.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Okay. Within my own code that I posted, where would I place your code?

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    See how your code doesn't look anything like what I've posted? You're getting to the end result in a different way than I am. I already have the way to get to it set. I need to use that way to achieve the goal I need, not the way you're getting there. Make sense?

  7. #7
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: How To Use Multiple GetAsyncKeystate Keys?

    I like using modules or classes,
    so, in the form code, I have:
    Code:
    Private Sub area_KeyDown(KeyCode As Integer, Shift As Integer)
        KeyDown KeyCode
    End Sub
    
    Private Sub area_KeyUp(KeyCode As Integer, Shift As Integer)
        KeyUp KeyCode
    End Sub
    change that to form instead, as you are using Form, not a picturebox.

    so in the module you have:
    Code:
    Sub KeyDown(ByVal KeyCode As Integer)
    Sub KeyUp(ByVal KeyCode As Integer)
    adding the lines I posted before.

    now, your "game-loop" is a timer, while Im using a Do/Sleep/DoEvents/Loop method.
    it should not be that different, i assume you use a low value, like 1?
    inside the Timer you put that code I posted previously, with your own variables of course.
    create your own type, here's mine in the module:
    Code:
    Type KeyRECT
        Up As Boolean
        Down As Boolean
        Left As Boolean
        Right As Boolean
    End Type
    
    Public Keys As KeyRECT
    to make it easy for you you just write:
    Code:
    Private Sub Timer1_Timer()
    If Keys.Up Then y = y - 1
    If Keys.Down Then y = y + 1
    If Keys.Left Then x = x - 1
    If Keys.Right Then x = x + 1
    End Sub
    Not sure what this state is doing or what the need of it.
    But if its about moving or not moving, its easy added by checking the KeyRECT.

    edit: If so, you should not ask for help and instead do it yourself, trial & error kind of way. asking help will always give you how others are doing it.

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Error: Out Of Stack Space

    Code:
    Sub KeyUp(ByVal KeyCode%)
    KeyUp KeyCode
    End Sub

  9. #9
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: How To Use Multiple GetAsyncKeystate Keys?

    u are calling KeyCode recursively, creating an infinity loop until out of stack. you call KeyUP inside your form_keyup event.
    and please, programming is about learning and trial & error. you can not just put stuff and run and complain if error, go back and look carefully your code and im sure you would have found the mistake yourself.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    I did exactly what you told me to do. It's very difficult to understand your code when you are all over the place.

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Quote Originally Posted by mcoulter876 View Post
    How about using Up-Left to make the graphic move diagonally Up-Left?
    The code from my example (as it stands in your Opener-Post) should already support multiple Keys (and diagonal movements)...

    Could you please test or verify that again - and in case it doesn't work - post which OS you are using?

    Olaf

  12. #12
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    Re: How To Use Multiple GetAsyncKeystate Keys?

    I understand this is difficult for you, as you don't follow my examples, this tells me you need full code and you are not used to do trial & error until you figure it out.
    here the full code.
    Code:
    Private Type KeyRECT
        Up As Boolean
        Down As Boolean
        Left As Boolean
        Right As Boolean
    End Type
    
    Dim Keys As KeyRECT
    Dim x As Long, y As Long
    
    Private Sub Form_Load()
      KeyPreview = True: ScaleMode = vbPixels: DrawWidth = 12
      x = ScaleWidth \ 2: y = ScaleHeight \ 2
      Timer1.Enabled = False: Timer1.Interval = 50
      Timer1.Enabled = True
    End Sub
    
    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Select Case KeyCode
    Case 37, 65: Keys.Left = True
    Case 38, 87: Keys.Up = True
    Case 39, 68: Keys.Right = True
    Case 40, 83: Keys.Down = True
    End Select
    End Sub
    
    Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
    Select Case KeyCode
    Case 37, 65: Keys.Left = False
    Case 38, 87: Keys.Up = False
    Case 39, 68: Keys.Right = False
    Case 40, 83: Keys.Down = False
    End Select
    End Sub
    
    
    Private Sub Timer1_Timer()
    Dim Draw As Boolean
    
    If Keys.Up Then y = y - 1: Draw = True
    If Keys.Down Then y = y + 1: Draw = True
    If Keys.Left Then x = x - 1: Draw = True
    If Keys.Right Then x = x + 1: Draw = True
    If Draw Then Cls: PSet (x, y), vbRed: Caption = x & ", " & y
    End Sub
    also, better to change to a picturebox. using the Forms Keys is not favorable as the arrow keys don't work.
    of course you can make it work using API and skip the Forms Key event completely and everything inside a Timer.

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Sep 2013
    Posts
    127

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Hi, Schmidt. I was hoping you'd see this. The code I posted, which you gave, seems to only make the object move in the four directions. I've tried using both W and A to make the object move Up-Left, but it only seems to do one or the other when both are pressed. I was thinking I would need the And operator, but not sure where, in your code, I would do that. Many thanks in advance.

  14. #14
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Hi mcoulter876,

    Olaf's code (and mine), basically process multiple keys on each cycle. In other words, if you're holding down your "move-left" key and your "move-down" key, and you've processed both on a single cycle, you should get the effect of moving at 45° (although that's not precisely what's happening).

    If you truly want to move at 45° angles, you will need to modify Olaf's code to simultaneously test for both keys being down, and yes, an AND would be correct. But you'd also probably want to put it all into a Select Case True block so you didn't process multiple conditions.

    All of this seems fairly straightforward to me.

    Best Of Luck,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  15. #15
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: How To Use Multiple GetAsyncKeystate Keys?

    Quote Originally Posted by mcoulter876 View Post
    I've tried using both W and A to make the object move Up-Left, but it only seems to do one or the other when both are pressed....
    As said, this should work already with the code in your top-posting...
    Holding down W and A (or alternatively the ArrowUp+ArrowLeft-Keys) will move the red Circle diagonally in "NorthWest"-direction.
    I've tested this on Win8 and XP.

    So if it doesn't work in *your* VB6-IDE, then I can only suspect:
    - either an installed (and active) IDE-Addin which kinda "breaks" the KeyEvent-Flow (due to Hooking or SubClassing or something)
    - or a "special KeyBoard" on your end (although unlikely)

    To rule out potential IDE-Addin-issues, you could simply compile the little App into an Executable - and run that.

    HTH

    Olaf

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width