Double tap + hold / Dash button

Ask gaming related questions
Dijanigo
Posts: 3
Joined: 06 Aug 2017, 13:09

Double tap + hold / Dash button

27 Feb 2018, 04:28

I need a script that when i tap a key, it double taps and holds the second tap until i release it.

example: I press A once -> the script does button A (pause for 0.05ms) -> button A again and holds it down afterwards.
Reason: The game requires a double tap + hold to dash in a certain direction, which is either A or D

i'd be really glad if someone could help me out there :)
Last edited by Dijanigo on 28 Feb 2018, 12:27, edited 1 time in total.
User avatar
Delta Pythagorean
Posts: 485
Joined: 13 Feb 2017, 13:44
GitHub: DelPyth
Location: Somewhere in the US

Re: Pause script on keypress

27 Feb 2018, 08:50

Code: Select all

~$LButton::
  SetBatchLines, -1
  SetKeyDelay, -1, -1

  While (GetKeyState("LButton", "P")) && (!GetKeyState("Ctrl", "P")) {
    SendInput, {LButton}
    Sleep 50  ;  milliseconds
  }
Return
First question is done.

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  KeyWait, p, D
  SendInput, {a Up}
Return
Second it done.
Dijanigo
Posts: 3
Joined: 06 Aug 2017, 13:09

Re: Pause script on keypress

27 Feb 2018, 13:23

Delta Pythagorean wrote:

Code: Select all

~$LButton::
  SetBatchLines, -1
  SetKeyDelay, -1, -1

  While (GetKeyState("LButton", "P")) && (!GetKeyState("Ctrl", "P")) {
    SendInput, {LButton}
    Sleep 50  ;  milliseconds
  }
Return
First question is done.

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  KeyWait, p, D
  SendInput, {a Up}
Return
Second it done.
First one works, thanks!

Second on works only one single time when i start the script, and then the button is disabled for some reason. It doesn't even work normally anymore
Dijanigo
Posts: 3
Joined: 06 Aug 2017, 13:09

Re: Pause script on keypress

28 Feb 2018, 12:26

Nothing seems to work. I've tried to fix it on my own via

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  loop{
   if !getkeystate(a,P)
       break
}
  SendInput, {a Up}
Return
and, because it caused an error,

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  loop{
   sleep, 50
   if !getkeystate(a,P)
       break
}
  SendInput, {a Up}
Return
because i'm entirely new to this whole AHK thing. didnt work though, the key doesn't even work for typing anymore
User avatar
evilC
Posts: 4742
Joined: 27 Feb 2014, 12:30

Re: Pause script on keypress

01 Mar 2018, 08:52

Delta Pythagorean wrote:

Code: Select all

~$LButton::
  SetBatchLines, -1
  SetKeyDelay, -1, -1

  While (GetKeyState("LButton", "P")) && (!GetKeyState("Ctrl", "P")) {
    SendInput, {LButton}
    Sleep 50  ;  milliseconds
  }
Return
First question is done.
1) SetBatchLines -1 is very risky, and should be avoided. It also brings nothing useful to the script.
2) SetKeyDelay is pointless as you use SendInput, which is unaffected by SetKeyDelay
3) Putting both of these lines inside the hotkey is pointless and wasteful of CPU
4) Doing a while GetKeyState loop inside a hotkey is very bad practice, and only works with one hotkey, see here.

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  KeyWait, p, D
  SendInput, {a Up}
Return
Second it done.
If you are sending the same key as is used to trigger a hotkey, prefix with $. If you added a hotkey for d:: that does Send {a}, then this would cause an infinite loop.
Plus, again, doing a KeyWait inside a hotkey is very bad practise, as previously mentioned in (3) above.

Code: Select all

  loop{
   if !getkeystate(a,P)
       break
1) Yet another wait in hotkey no-no
2) a and P are variable names (Because no quotes), and neither variable is set, so you are passing no parameters to GetKeyState
3) This is incredibly wasteful of CPU and likely to cause 5-10% CPU usage, as you have no sleep in the loop.
User avatar
evilC
Posts: 4742
Joined: 27 Feb 2014, 12:30

Re: Double tap + hold / Dash button

01 Mar 2018, 09:00

Furthermore, sending {a up} when A gets released is not needed - just do not declare the hotkey a up:: as a blocking hotkey, and the game will see the physical key get released.

Code: Select all

SetKeyDelay, 0, 50

$a::
    Send {a}
    Sleep 50 ; If a key goes up, then down again within 50ms, the game may well not see it change state
    Send {a down}
    ; You DO NOT need to send {a up} on release of a, because we have not blocked A up
    return

$d::
    Send {d}
    Sleep 50
    Send {d Down}
    return
User avatar
Nwb
Posts: 444
Joined: 29 Nov 2016, 08:56

Re: Pause script on keypress

01 Mar 2018, 09:38

evilC wrote:
Delta Pythagorean wrote:

Code: Select all

~$LButton::
  SetBatchLines, -1
  SetKeyDelay, -1, -1

  While (GetKeyState("LButton", "P")) && (!GetKeyState("Ctrl", "P")) {
    SendInput, {LButton}
    Sleep 50  ;  milliseconds
  }
Return
First question is done.
1) SetBatchLines -1 is very risky, and should be avoided. It also brings nothing useful to the script.
2) SetKeyDelay is pointless as you use SendInput, which is unaffected by SetKeyDelay
3) Putting both of these lines inside the hotkey is pointless and wasteful of CPU
4) Doing a while GetKeyState loop inside a hotkey is very bad practice, and only works with one hotkey, see here.

Code: Select all

A::
  SendInput, a
  SendInput, {a Down}

  KeyWait, p, D
  SendInput, {a Up}
Return
Second it done.
If you are sending the same key as is used to trigger a hotkey, prefix with $. If you added a hotkey for d:: that does Send {a}, then this would cause an infinite loop.
Plus, again, doing a KeyWait inside a hotkey is very bad practise, as previously mentioned in (3) above.

Code: Select all

  loop{
   if !getkeystate(a,P)
       break
1) Yet another wait in hotkey no-no
2) a and P are variable names (Because no quotes), and neither variable is set, so you are passing no parameters to GetKeyState
3) This is incredibly wasteful of CPU and likely to cause 5-10% CPU usage, as you have no sleep in the loop.
Is there a thread about cpu usage pointers? I never knew that not having a sleep inside a loop can increase cpu usage for example.

I wonder if there is a way to determine which key was pressed inside the script itself. Otherwise (to OP) I think you will have to write identical scripts for all your controls. I think you should use getkeystate instead of keywait. Because for keywait it's waiting for the key to be down so doesn't that mean you have to pull up and press again in order for the keywait to register it?
I am your average ahk newbie. Just.. a tat more cute. ;)
User avatar
evilC
Posts: 4742
Joined: 27 Feb 2014, 12:30

Re: Double tap + hold / Dash button

01 Mar 2018, 09:45

Not that I am aware of, but doing *anything* repeatedly like that in code is likely to cause load.

Code: Select all

c := 0
t := A_TickCount + 1000
while (A_TickCount < t){
    GetKeyState("LButton")
    c++
}
MsgBox % c
On this PC, it excecutes ~100,000 times in one second and hits ~5% CPU usage
Without the GetKeyState check, it executes ~750,000 times and hits ~2.5% CPU usage
User avatar
Nwb
Posts: 444
Joined: 29 Nov 2016, 08:56

Re: Double tap + hold / Dash button

01 Mar 2018, 09:47

evilC wrote:Furthermore, sending {a up} when A gets released is not needed - just do not declare the hotkey a up:: as a blocking hotkey, and the game will see the physical key get released.

Code: Select all

SetKeyDelay, 0, 50

$a::
    Send {a}
    Sleep 50 ; If a key goes up, then down again within 50ms, the game may well not see it change state
    Send {a down}
    ; You DO NOT need to send {a up} on release of a, because we have not blocked A up
    return

$d::
    Send {d}
    Sleep 50
    Send {d Down}
    return
Ohh that's intelligent I would have never thought of that.
I am your average ahk newbie. Just.. a tat more cute. ;)

Return to “Gaming”

Who is online

Users browsing this forum: NewbCoder and 34 guests