bobtheguy
bobtheguy

Reputation: 51

pyautogui.press() causing lag when called

I have been working on a project where I need to call pyautogui.press('space'), however, when this is called, there is a noticable amount of lag. I need to try and keep the code running fairly fast because OpenCV is being used. If anyone knows how I can try to stop the code from slowing down when pyautogui.press('space') is called, that would be amazing. You can also see the lag in this video whenever the dinosaur jumps: https://www.youtube.com/watch?v=vceDabnT3OE.

Here is the code:

import numpy as np
import cv2
import pyautogui
import time
from PIL import ImageGrab

# Defining Template Images
gameOver = cv2.imread('GameOver.png')
dino = cv2.imread('Dino.png')
smallCactus = cv2.imread('SmallCactus.png')
bigCactus = cv2.imread('BigCactus.png')
ptero = cv2.imread('Ptero.png')

# Assigning Sample Image Dimensions
h, w = dino.shape[:-1]
sch, scw = smallCactus.shape[:-1]
bch, bcw = bigCactus.shape[:-1]
ph, pw = ptero.shape[:-1]

# Time Variables
lastTime = time.time()
runningTime = 0

# Key Variables
keyDown = False

pyautogui.keyDown('space')

while True:
    # Capturing Screen
    # 'bbox' Is Rectangle Around The Game
    screen = np.array(ImageGrab.grab(bbox=(150,125,800,300)))

    # Time stuff
    #print('Loop took {} seconds'.format(time.time() - lastTime))
    runningTime += time.time() - lastTime
    lastTime = time.time()

    # Checking If Game Over
    gameOverRes = cv2.matchTemplate(screen, gameOver, cv2.TM_CCOEFF_NORMED)
    minValG, maxValG, minLocG, maxLocG = cv2.minMaxLoc(gameOverRes)

    if maxValG >= 0.9 and runningTime > 4:
        print('Game Ended In ', int(round(runningTime)), ' Seconds')
        pyautogui.press('space')
        runningTime = 0

    # Finding Dinosaur
    dinoRes = cv2.matchTemplate(screen, dino, cv2.TM_CCOEFF_NORMED)
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(dinoRes)

    # Finding Small Cacti
    smallCactusRes = cv2.matchTemplate(screen, smallCactus, cv2.TM_CCOEFF_NORMED)
    smallCactusThreshhold = 0.725
    smallCactusLoc = np.where(smallCactusRes >= smallCactusThreshhold)

    # Finding Big Cacti
    bigCactusRes = cv2.matchTemplate(screen, bigCactus, cv2.TM_CCOEFF_NORMED)
    bigCactusThreshhold = 0.725
    bigCactusLoc = np.where(bigCactusRes >= bigCactusThreshhold)

    # Finding Pterodactyls
    pteroRes = cv2.matchTemplate(screen, ptero, cv2.TM_CCOEFF_NORMED)
    minValP, maxValP, minLocP, maxLocP = cv2.minMaxLoc(pteroRes)

    # Drawing Box Around Dinosaur
    cv2.rectangle(screen, maxLoc, (maxLoc[0] + w, maxLoc[1] + h), (0, 255, 0), 2)

    # Avoiding Closest Small Cactus
    if smallCactusLoc[0].size > 0:
        leftmostXS = min(smallCactusLoc[1])
        leftmostYS = min(smallCactusLoc[0])

        distS = (leftmostXS - maxLoc[0])

        if (distS < 175 and distS > 0):
            pyautogui.press('space')

        cv2.rectangle(screen, (leftmostXS, leftmostYS), (leftmostXS+scw, leftmostYS+sch), (255, 160, 0), 2)

    # Avoiding Closest Big Cactus
    if bigCactusLoc[0].size > 0:
        leftmostXB = min(bigCactusLoc[1])
        leftmostYB = min(bigCactusLoc[0])

        distB = (leftmostXB - maxLoc[0])

        if distB < 175 and distB > 0:
            pyautogui.press('space')

        cv2.rectangle(screen, (leftmostXB, leftmostYB), (leftmostXB+bcw, leftmostYB+bch), (255, 0, 0), 2)


    # Avoiding Pterodactyls
    # Check 'maxValP' Because Otherwise Dino Gets Mistaken As Pterodactyl
    # 'keyDown' Is Needed For Down Arrow, Otherwise It Doesn't Work Properly
    if maxValP >= 0.60:

        distP = maxLocP[0] - maxLoc[0]
        heightP = maxLoc[1] - maxLocP[1]

        if distP < 190 and distP > 0:
            if heightP > 10:
                keyDown = True
                pyautogui.keyDown('down')
            else:
                pyautogui.press('space')            

        cv2.rectangle(screen, maxLocP, (maxLocP[0] + pw, maxLocP[1] + ph), (0, 0, 255), 2)

    # elif keyDown == True:
        # pyautogui.keyUp('down')
        # keyDown = False

    # Showing Image
    cv2.imshow('Dino Game', cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))

    # Quit
    if cv2.waitKey(1) & 0xFF == 27:
        cv2.destroyAllWindows()
        break

Upvotes: 5

Views: 7344

Answers (3)

user14393903
user14393903

Reputation: 1

set MINIMUM_SLEEP = 0.0 in init.py file in the package. It will work super fast.

Upvotes: 0

Tomas
Tomas

Reputation: 1

I think there is some glitch in functions like click or typewrite. I discovered that if you use them in cycle you can get empty mouse clicks or misswrites, e.g. if you want to write 1001, you can get only 101. At the moment testing raw functions like mouseDown and mouseUp and it seems they tend to work better. Hope that helps someone.

Upvotes: 0

Al Sweigart
Al Sweigart

Reputation: 12939

I'm the author of PyAutoGUI. PyAutoGUI has a "fail-safe" feature to help in case your script is buggy and you want to shut it off, but it may be moving the mouse around making it impossible to hit the keyboard. There is a 0.1 second delay after all PyAutoGUI calls, giving you a chance to slam the mouse to the upper right corner (PyAutoGUI will raise FailSafeException if the mouse is ever at coordinates (0, 0).)

The tenth second delay gives the user a chance to move the mouse to the upper left corner. However, you can also disable this by setting pyautogui.PAUSE to 0:

>>> pyautogui.PAUSE = 0

However, this means if something screws up and your script causes the mouse to constantly click around, you might have a harder time killing your script.

Upvotes: 16

Related Questions