Send Keys to Game Container 2048
Try it:
from selenium.webdriver.common.keys import Keys
import random
import time
moves = [Keys.LEFT, Keys.DOWN, Keys.RIGHT, Keys.UP]
while True:
driver.find_element_by_css_selector('body').send_keys(random.choice(moves))
time.sleep(2)
python: How can I press arrow keys randomly selenium
How to simulate keys in game with pywinauto
We have had a long journey my past self. Though we have much to learn here is what we discovered:
Sending Virtual Keys will be ignored if the game is running on DirectX.
Use sendinput and send the scan_codes instead.
# http://www.gamespp.com/directx/directInputKeyboardScanCodes.html
import ctypes
import time
SendInput = ctypes.windll.user32.SendInput
W = 0x11
A = 0x1E
S = 0x1F
D = 0x20
Z = 0x2C
UP = 0xC8
DOWN = 0xD0
LEFT = 0xCB
RIGHT = 0xCD
ENTER = 0x1C
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def pressKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def releaseKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0,
ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
if __name__ == '__main__':
pressKey(0x11)
time.sleep(1)
releaseKey(0x11)
time.sleep(1)
Source:
Simulate Python keypresses for controlling a game
http://www.gamespp.com/directx/directInputKeyboardScanCodes.html
Thank you Sentdex for awesome tutorials on Machine Learning.
I've been wanting to do this to some of my favorite games but couldn't get the keys across (due to DirectX).
Next step:
Windows Driver Kit to emulate keypresses...
Send key input to HTML5 game using Selenium
Looks like selenium doesn't focus on your app.
Try clicking on the element and chain with sending keys
element = driver.find_element_by_tag_name("canvas")
actions.click(element).key_down(Keys.ARROW_LEFT).perform()
This worked for me
Programatically send keyboard input to graphical application (game) in Windows
It appears that the problem is that while text input generally pulls input from a buffer, realtime games will miss keypresses that come and go as fast as a virtual keyboard can press them. The solution is simply adding a short call to Sleep() between the keypress and the keyup.
Additionally, for anybody working in Python who like me tried the often-suggested SendKeys.py with no success, look for the 'playkeys' function in the code and add time.sleep(pause) after key_down(vk) , this should resolve the problem (it worked for me).
SendKeys using pywin32 to a PC Game
Most Windows games use the DirectX API for reading keystrokes, they simply ignore that kind of key-pressing messages. They interact directly with the hardware. So your code won't work in the 99% of the Windows games out there.
I would achieve this by writing my own driver and send keystrokes like if they are being pressed manually. It's complex, but not impossible.
Also, I think there's a better way to achieve whatever you want to do. In most cases sending keystrokes it's not a clean solution (specially if you are trying to cheat).
Hope it helps.
How to "send keys" to a canvas element for longer duration?
Unfortunately I cannot see a reproducible behaviour for jumps in that game. When i press UP o SPACE, I randomly see short or long jumps, so I cannot be really sure if my approach will work for you.
However, I think that, with a small effort, you could create a suitable event that will fit you needs.
Basically, since Selenium can execute arbitrary javascript, my approach here is to send a keydown event to the canvas element (tested with Firefox 77).
A screenshot is made for each iteration to ensure the dino actually jumps.
Have fun.
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
options = FirefoxOptions()
options.add_argument("--headless")
driver = webdriver.Firefox(options=options)
driver.get('https://chromedino.com/')
canvas = driver.find_element_by_css_selector('.runner-canvas')
main_body = driver.find_element_by_xpath("//html")
try:
canvas.click()
except:
main_body.send_keys(Keys.SPACE)
while True:
driver.execute_script('''
var keydownEvt = new KeyboardEvent('keydown', {
altKey:false,
altKey: false,
bubbles: true,
cancelBubble: false,
cancelable: true,
charCode: 0,
code: "Space",
composed: true,
ctrlKey: false,
currentTarget: null,
defaultPrevented: true,
detail: 0,
eventPhase: 0,
isComposing: false,
isTrusted: true,
key: " ",
keyCode: 32,
location: 0,
metaKey: false,
repeat: false,
returnValue: false,
shiftKey: false,
type: "keydown",
which: 32,
});
arguments[0].dispatchEvent(keydownEvt);
''', canvas)
driver.get_screenshot_as_file('proof_%s.png' % int(time.time()))
time.sleep(0.2)
driver.quit()
Related Topics
Join Dataframes Based on Partial String-Match Between Columns
Finding the Maximum Number of Columns in a File or CSV Using Python
Replacing Pandas or Numpy Nan With a None to Use With Mysqldb
Reading Contents of a Gzip File from a Aws S3 in Python
Python - How to Separate Paragraphs from Text
How to Create an Automatically Updating Gui Using Tkinter
No Unique Mode; Found 2 Equally Common Values
How to Use Installed Packages in Pycharm
Could Not Find a Version That Satisfies the Requirement in Python
How to Convert a Datetime Object to Milliseconds Since Epoch (Unix Time) in Python
How to Check for an Exact Word in a String in Python
How to Assign Class Instance to a Variable and Use That in Other Class
Pandas: Group by Name and Take Row With Most Recent Date
How to Store the Result of an Executed Function and Re-Use Later
Convert String to Negative Number
How to Add Thousand Separator to Numbers in Python Pandas Dataframe
How to Call a Classes Method from Another Class Without Initialising the First Class