Grabbing Joystick / Gamepad button presses

If this template helps then use it. If not then just delete and start from scratch.

OS (e.g. Win10):
PsychoPy version (2022.1.3):
**Standard Standalone? (y, standalone)
What are you trying to achieve?:
I am trying to grab the button presses from A and B keys on a NES USB controller and use the button presses to alter a score

**What did you try to make it work?:**I tried EVERYTHING! Here is something that almost works, it can print the pressed button and button states to the display but not much else:

$(‘1’,joystick_2.device.getAllButtons(),“2”,
button_resp_2.pressedButtons,‘3’,
button_resp_2.newPressedButtons
)

What specifically went wrong when you tried that?: I can get the buttons pressed to print to the display but I can never get it to increment a counter
Include pasted full error message if possible. “That didn’t work” is not enough information.

So what I want to do is player 1 presses button a, I will have a counter on the screen increment each time button A is pressed. I can try it now using:

if button_resp_2.status == STARTED:
if button_resp_2.pressedButtons ==1:
player2Score = player2Score + 1

but nothing works. I tried so many things but I’ve had no luck.
I do have it working so that I can press the up arrow or down arrow to increment or decrease the score, now I only need the game pad buttons to work. I’ll post my complete code below

Here is the complete code that I have:

#!/usr/bin/env python

-- coding: utf-8 --

“”"
This experiment was created using PsychoPy3 Experiment Builder (v2022.1.3),
on February 14, 2023, at 17:12
If you publish work using this script the most relevant publication is:

Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) 
    PsychoPy2: Experiments in behavior made easy Behav Res 51: 195. 
    https://doi.org/10.3758/s13428-018-01193-y

“”"

from psychopy import locale_setup
from psychopy import prefs
from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, layout
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)

import numpy as np # whole numpy lib is available, prepend ‘np.’
from numpy import (sin, cos, tan, log, log10, pi, average,
sqrt, std, deg2rad, rad2deg, linspace, asarray)
from numpy.random import random, randint, normal, shuffle, choice as randchoice
import os # handy system and path functions
import sys # to get file system encoding

import psychopy.iohub as io
from psychopy.hardware import keyboard

This is a before experiment comment

import time
player1InputTimer = 0
player2InputTimer = 0

playerInfo = {‘Player 1’: ‘Green’, ‘Player 2’: ‘Blue’,‘Game Time (minutes)’:‘’}
dlg = gui.DlgFromDict(dictionary=playerInfo, sortKeys=False, title=‘Player Info’)

This ends the before experiment comment

gameTimer = core.CountdownTimer(int(playerInfo[‘Game Time (minutes)’]))

gameTimer.getTime()

player1Score = 0
player2Score = 0

Controller note: joystick_2.device.getAllButtons() yields a string in

the form of [False, False, False, False, False, False, False, False, False,

False] so 10 buttons.

2 = a

3 = b

9 = select

10 = start

This returns pressed button: print(button_resp_2.newPressedButtons)

alter button_resp_2.newPressedButtons = [i for i in [0,1,2,3,4,5,6,7,8,9,10]

to include all 10 buttons

The below return either a split second of the pressed button,

or an array / string containing all buttons pressed that doesn’t

change until the next button is pressed

button_resp_2.pressedButtons,

button_resp_2.keys

This makes list , button_resp_2.keys,‘4’,

try joystickCACHE (dictionary)

Ensure that relative paths start from the same directory as this script

_thisDir = os.path.dirname(os.path.abspath(file))
os.chdir(_thisDir)

Store info about the experiment session

psychopyVersion = ‘2022.1.3’
expName = ‘controllerCode’ # from the Builder filename that created this script
expInfo = {‘participant’: ‘’, ‘session’: ‘001’}
dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
if dlg.OK == False:
core.quit() # user pressed cancel
expInfo[‘date’] = data.getDateStr() # add a simple timestamp
expInfo[‘expName’] = expName
expInfo[‘psychopyVersion’] = psychopyVersion

Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc

filename = thisDir + os.sep + u’data/%s%s_%s’ % (expInfo[‘participant’], expName, expInfo[‘date’])

An ExperimentHandler isn’t essential but helps with data saving

thisExp = data.ExperimentHandler(name=expName, version=‘’,
extraInfo=expInfo, runtimeInfo=None,
originPath=‘C:\CODE\1_ VS CODE\Ratsketball\Psychopy\controllerCode.py’,
savePickle=True, saveWideText=True,
dataFileName=filename)

save a log file for detail verbose info

logFile = logging.LogFile(filename+‘.log’, level=logging.EXP)
logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file

endExpNow = False # flag for ‘escape’ or other condition => quit the exp
frameTolerance = 0.001 # how close to onset before ‘same’ frame

Start Code - component code to be run after the window creation

from psychopy.hardware import joystick as joysticklib # joystick/gamepad accsss
from psychopy.experiment.components.joystick import virtualJoystick as virtualjoysticklib
from psychopy.hardware import joystick as joysticklib # joystick/gamepad accsss
from psychopy.experiment.components.joystick import virtualJoystick as virtualjoysticklib
from psychopy.hardware import joystick as joysticklib # joystick/gamepad accsss
from psychopy.experiment.components.joyButtons import virtualJoyButtons as virtualjoybuttonslib
from psychopy.hardware import joystick as joysticklib # joystick/gamepad accsss
from psychopy.experiment.components.joyButtons import virtualJoyButtons as virtualjoybuttonslib

Setup the Window

win = visual.Window(
size=(1024, 768), fullscr=True, screen=0,
winType=‘pyglet’, allowGUI=False, allowStencil=False,
monitor=‘testMonitor’, color=[0,0,0], colorSpace=‘rgb’,
blendMode=‘avg’, useFBO=True,
units=‘height’)

store frame rate of monitor if we can measure it

expInfo[‘frameRate’] = win.getActualFrameRate()
if expInfo[‘frameRate’] != None:
frameDur = 1.0 / round(expInfo[‘frameRate’])
else:
frameDur = 1.0 / 60.0 # could not measure, so guess

Setup ioHub

ioConfig = {}

Setup iohub keyboard

ioConfig[‘Keyboard’] = dict(use_keymap=‘psychopy’)

ioSession = ‘1’
if ‘session’ in expInfo:
ioSession = str(expInfo[‘session’])
ioServer = io.launchHubServer(window=win, **ioConfig)
eyetracker = None

create a default keyboard (e.g. to check for escape)

defaultKeyboard = keyboard.Keyboard(backend=‘iohub’)

Initialize components for Routine “trial”

trialClock = core.Clock()

This is a begin experiment comment

This ends the begin experiment comment

x, y = [None, None]
joystick = type(‘’, (), {})() # Create an object to use as a name space
joystick.device = None
joystick.device_number = 0
joystick.joystickClock = core.Clock()
joystick.xFactor = 1
joystick.yFactor = 1

try:
numJoysticks = joysticklib.getNumJoysticks()
if numJoysticks > 0:
try:
joystickCache
except NameError:
joystickCache={}
if not 0 in joystickCache:
joystickCache[0] = joysticklib.Joystick(0)
joystick.device = joystickCache[0]
if win.units == ‘height’:
joystick.xFactor = 0.5 * win.size[0]/win.size[1]
joystick.yFactor = 0.5
else:
joystick.device = virtualjoysticklib.VirtualJoystick(0)
logging.warning(“joystick_{}: Using keyboard+mouse emulation ‘ctrl’ + ‘Alt’ + digit.”.format(joystick.device_number))
except Exception:
pass

if not joystick.device:
logging.error(‘No joystick/gamepad device found.’)
core.quit()

joystick.status = None
joystick.clock = core.Clock()
joystick.numButtons = joystick.device.getNumButtons()
joystick.getNumButtons = joystick.device.getNumButtons
joystick.getAllButtons = joystick.device.getAllButtons
joystick.getX = lambda: joystick.xFactor * joystick.device.getX()
joystick.getY = lambda: joystick.yFactor * joystick.device.getY()

x, y = [None, None]
joystick_2 = type(‘’, (), {})() # Create an object to use as a name space
joystick_2.device = None
joystick_2.device_number = 1
joystick_2.joystickClock = core.Clock()
joystick_2.xFactor = 1
joystick_2.yFactor = 1

try:
numJoysticks = joysticklib.getNumJoysticks()
if numJoysticks > 0:
try:
joystickCache
except NameError:
joystickCache={}
if not 1 in joystickCache:
joystickCache[1] = joysticklib.Joystick(1)
joystick_2.device = joystickCache[1]
if win.units == ‘height’:
joystick_2.xFactor = 0.5 * win.size[0]/win.size[1]
joystick_2.yFactor = 0.5
else:
joystick_2.device = virtualjoysticklib.VirtualJoystick(1)
logging.warning(“joystick_{}: Using keyboard+mouse emulation ‘ctrl’ + ‘Alt’ + digit.”.format(joystick_2.device_number))
except Exception:
pass

if not joystick_2.device:
logging.error(‘No joystick/gamepad device found.’)
core.quit()

joystick_2.status = None
joystick_2.clock = core.Clock()
joystick_2.numButtons = joystick_2.device.getNumButtons()
joystick_2.getNumButtons = joystick_2.device.getNumButtons
joystick_2.getAllButtons = joystick_2.device.getAllButtons
joystick_2.getX = lambda: joystick_2.xFactor * joystick_2.device.getX()
joystick_2.getY = lambda: joystick_2.yFactor * joystick_2.device.getY()

button_resp = type(‘’, (), {})() # Create an object to use as a name space
button_resp.device = None
button_resp.device_number = 0

try:
numJoysticks = joysticklib.getNumJoysticks()
if numJoysticks > 0:
button_resp.device = joysticklib.Joystick(0)
try:
joystickCache
except NameError:
joystickCache={}
if not 0 in joystickCache:
joystickCache[0] = joysticklib.Joystick(0)
button_resp.device = joystickCache[0]
else:
button_resp.device = virtualjoybuttonslib.VirtualJoyButtons(0)
logging.warning(“joystick_{}: Using keyboard emulation ‘ctrl’ + ‘Alt’ + digit.”.format(button_resp.device_number))
except Exception:
pass

if not button_resp.device:
logging.error(‘No joystick/gamepad device found.’)
core.quit()

button_resp.status = None
button_resp.clock = core.Clock()
button_resp.numButtons = button_resp.device.getNumButtons()

button_resp_2 = type(‘’, (), {})() # Create an object to use as a name space
button_resp_2.device = None
button_resp_2.device_number = 1

try:
numJoysticks = joysticklib.getNumJoysticks()
if numJoysticks > 0:
button_resp_2.device = joysticklib.Joystick(1)
try:
joystickCache
except NameError:
joystickCache={}
if not 1 in joystickCache:
joystickCache[1] = joysticklib.Joystick(1)
button_resp_2.device = joystickCache[1]
else:
button_resp_2.device = virtualjoybuttonslib.VirtualJoyButtons(1)
logging.warning(“joystick_{}: Using keyboard emulation ‘ctrl’ + ‘Alt’ + digit.”.format(button_resp_2.device_number))
except Exception:
pass

if not button_resp_2.device:
logging.error(‘No joystick/gamepad device found.’)
core.quit()

button_resp_2.status = None
button_resp_2.clock = core.Clock()
button_resp_2.numButtons = button_resp_2.device.getNumButtons()

score = visual.TextStim(win=win, name=‘score’,
text=‘’,
font=‘Open Sans’,
pos=(-.4, 0), height=0.5, wrapWidth=None, ori=0.0,
color=[-1.0000, -0.2157, -1.0000], colorSpace=‘rgb’, opacity=None,
languageStyle=‘LTR’,
depth=-5.0);
score_2 = visual.TextStim(win=win, name=‘score_2’,
text=‘’,
font=‘Open Sans’,
pos=(.4, 0), height=0.5, wrapWidth=None, ori=0.0,
color=[-1.0000, -1.0000, 0.0902], colorSpace=‘rgb’, opacity=None,
languageStyle=‘LTR’,
depth=-6.0);
name_1 = visual.TextStim(win=win, name=‘name_1’,
text=(playerInfo.get(‘Player 1’)),
font=‘Open Sans’,
pos=(-.4, 0.4), height=0.25, wrapWidth=None, ori=0.0,
color=‘white’, colorSpace=‘rgb’, opacity=None,
languageStyle=‘LTR’,
depth=-7.0);
name_2 = visual.TextStim(win=win, name=‘name_2’,
text=(playerInfo.get(‘Player 2’)),
font=‘Open Sans’,
pos=(.5, 0.4), height=0.25, wrapWidth=None, ori=0.0,
color=‘white’, colorSpace=‘rgb’, opacity=None,
languageStyle=‘LTR’,
depth=-8.0);
allControllerVariables = visual.TextStim(win=win, name=‘allControllerVariables’,
text=‘’,
font=‘Open Sans’,
pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
color=‘white’, colorSpace=‘rgb’, opacity=None,
languageStyle=‘LTR’,
depth=-9.0);

Create some handy timers

globalClock = core.Clock() # to track the time since experiment started
routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine

------Prepare to start Routine “trial”-------

continueRoutine = True

update component parameters for each repeat

This is a begin routine comment

This ends the begin routine comment

joystick.oldButtonState = joystick.device.getAllButtons()[:]
joystick.activeButtons=[i for i in range(joystick.numButtons)]

setup some python lists for storing info about the joystick

joystick.x =
joystick.y =
joystick.buttonLogs = [ for i in range(joystick.numButtons)]
joystick.time =
gotValidClick = False # until a click is received
joystick_2.oldButtonState = joystick_2.device.getAllButtons()[:]
joystick_2.activeButtons=[i for i in range(joystick_2.numButtons)]

setup some python lists for storing info about the joystick_2

joystick_2.x =
joystick_2.y =
joystick_2.buttonLogs = [ for i in range(joystick_2.numButtons)]
joystick_2.time =
gotValidClick = False # until a click is received
button_resp.oldButtonState = button_resp.device.getAllButtons()[:]
button_resp.keys =
button_resp.rt =
button_resp_2.oldButtonState = button_resp_2.device.getAllButtons()[:]
button_resp_2.keys =
button_resp_2.rt =

keep track of which components have finished

trialComponents = [joystick, joystick_2, button_resp, button_resp_2, score, score_2, name_1, name_2, allControllerVariables]
for thisComponent in trialComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, ‘status’):
thisComponent.status = NOT_STARTED

reset timers

t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock=“now”)
trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
frameN = -1

-------Run Routine “trial”-------

while continueRoutine:
# get current time
t = trialClock.getTime()
tThisFlip = win.getFutureFlipTime(clock=trialClock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# This is an each frame comment #
if joystick.device._device.y == -1:
if time.time() >= (player1InputTimer):
player1Score = player1Score + 1
player1InputTimer = (time.time()+.5)
elif joystick.device._device.y == 1:
if time.time() >= (player1InputTimer):
player1Score = player1Score - 1
player1InputTimer = (time.time()+.5)

if joystick_2.device._device.y == -1:
    if time.time() >= (player2InputTimer):
        player2Score = player2Score + 1
        player2InputTimer = (time.time()+.5)
elif joystick_2.device._device.y == 1:
    if time.time() >= (player2InputTimer):
        player2Score = player2Score - 1
        player2InputTimer = (time.time()+.5)
        
     

# *button_resp_2* updates
if button_resp_2.status == STARTED:
    if button_resp_2.pressedButtons ==1:
        player2Score = player2Score + 1
        player2InputTimer = (time.time()+.5)    

# This ends the each frame comment # 
# *joystick* updates
if joystick.status == NOT_STARTED and t >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    joystick.frameNStart = frameN  # exact frame index
    joystick.tStart = t  # local t and not account for scr refresh
    joystick.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(joystick, 'tStartRefresh')  # time at next scr refresh
    joystick.status = STARTED
if joystick.status == STARTED:  # only update if started and not finished!
    joystick.newButtonState = joystick.getAllButtons()[:]
    if joystick.newButtonState != joystick.oldButtonState: # New button press
        joystick.pressedButtons = [i for i in range(joystick.numButtons) if joystick.newButtonState[i] and not joystick.oldButtonState[i]]
        joystick.releasedButtons = [i for i in range(joystick.numButtons) if not joystick.newButtonState[i] and joystick.oldButtonState[i]]
        joystick.newPressedButtons = [i for i in joystick.activeButtons if i in joystick.pressedButtons]
        joystick.oldButtonState = joystick.newButtonState
        joystick.buttons = joystick.newPressedButtons
        [logging.data("joystick_{}_button: {}, pos=({:1.4f},{:1.4f})".format(joystick.device_number, i, joystick.getX(), joystick.getY())) for i in joystick.pressedButtons]
        if len(joystick.buttons) > 0:  # state changed to a new click
            x, y = joystick.getX(), joystick.getY()
            joystick.x.append(x)
            joystick.y.append(y)
            [joystick.buttonLogs[i].append(int(joystick.newButtonState[i])) for i in joystick.activeButtons]
            joystick.time.append(globalClock.getTime())
# *joystick_2* updates
if joystick_2.status == NOT_STARTED and t >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    joystick_2.frameNStart = frameN  # exact frame index
    joystick_2.tStart = t  # local t and not account for scr refresh
    joystick_2.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(joystick_2, 'tStartRefresh')  # time at next scr refresh
    joystick_2.status = STARTED
if joystick_2.status == STARTED:  # only update if started and not finished!
    joystick_2.newButtonState = joystick_2.getAllButtons()[:]
    if joystick_2.newButtonState != joystick_2.oldButtonState: # New button press
        joystick_2.pressedButtons = [i for i in range(joystick_2.numButtons) if joystick_2.newButtonState[i] and not joystick_2.oldButtonState[i]]
        joystick_2.releasedButtons = [i for i in range(joystick_2.numButtons) if not joystick_2.newButtonState[i] and joystick_2.oldButtonState[i]]
        joystick_2.newPressedButtons = [i for i in joystick_2.activeButtons if i in joystick_2.pressedButtons]
        joystick_2.oldButtonState = joystick_2.newButtonState
        joystick_2.buttons = joystick_2.newPressedButtons
        [logging.data("joystick_{}_button: {}, pos=({:1.4f},{:1.4f})".format(joystick_2.device_number, i, joystick_2.getX(), joystick_2.getY())) for i in joystick_2.pressedButtons]
        if len(joystick_2.buttons) > 0:  # state changed to a new click
            x, y = joystick_2.getX(), joystick_2.getY()
            joystick_2.x.append(x)
            joystick_2.y.append(y)
            [joystick_2.buttonLogs[i].append(int(joystick_2.newButtonState[i])) for i in joystick_2.activeButtons]
            joystick_2.time.append(globalClock.getTime())

# *button_resp* updates
if button_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    button_resp.frameNStart = frameN  # exact frame index
    button_resp.tStart = t  # local t and not account for scr refresh
    button_resp.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(button_resp, 'tStartRefresh')  # time at next scr refresh
    button_resp.status = STARTED
    # joyButtons checking is just starting
    win.callOnFlip(button_resp.clock.reset)  # t=0 on next screen flip
if button_resp.status == STARTED:
    button_resp.newButtonState = button_resp.device.getAllButtons()[:]
    button_resp.pressedButtons = []
    button_resp.releasedButtons = []
    button_resp.newPressedButtons = []
    if button_resp.newButtonState != button_resp.oldButtonState:
        button_resp.pressedButtons = [i for i in range(button_resp.numButtons) if button_resp.newButtonState[i] and not button_resp.oldButtonState[i]]
        button_resp.releasedButtons = [i for i in range(button_resp.numButtons) if not button_resp.newButtonState[i] and button_resp.oldButtonState[i]]
        button_resp.oldButtonState = button_resp.newButtonState
        button_resp.newPressedButtons = [i for i in [0,1,2,3,4,5,6,7,8,9,10] if i in button_resp.pressedButtons]
        [logging.data("joystick_{}_button: {}".format(button_resp.device_number,i)) for i in button_resp.pressedButtons]
    theseKeys = button_resp.newPressedButtons
    if len(theseKeys) > 0:  # at least one key was pressed
        button_resp.keys.extend(theseKeys)  # storing all keys
        button_resp.rt.append(button_resp.clock.getTime())

# *button_resp_2* updates
if button_resp_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    button_resp_2.frameNStart = frameN  # exact frame index
    button_resp_2.tStart = t  # local t and not account for scr refresh
    button_resp_2.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(button_resp_2, 'tStartRefresh')  # time at next scr refresh
    button_resp_2.status = STARTED
    # joyButtons checking is just starting
    win.callOnFlip(button_resp_2.clock.reset)  # t=0 on next screen flip
if button_resp_2.status == STARTED:
    button_resp_2.newButtonState = button_resp_2.device.getAllButtons()[:]
    button_resp_2.pressedButtons = []
    button_resp_2.releasedButtons = []
    button_resp_2.newPressedButtons = []
    if button_resp_2.newButtonState != button_resp_2.oldButtonState:
        button_resp_2.pressedButtons = [i for i in range(button_resp_2.numButtons) if button_resp_2.newButtonState[i] and not button_resp_2.oldButtonState[i]]
        button_resp_2.releasedButtons = [i for i in range(button_resp_2.numButtons) if not button_resp_2.newButtonState[i] and button_resp_2.oldButtonState[i]]
        button_resp_2.oldButtonState = button_resp_2.newButtonState
        button_resp_2.newPressedButtons = [i for i in [0,1,2,3,4,5,6,7,8,9,10] if i in button_resp_2.pressedButtons]
        [logging.data("joystick_{}_button: {}".format(button_resp_2.device_number,i)) for i in button_resp_2.pressedButtons]
    theseKeys = button_resp_2.newPressedButtons
    if len(theseKeys) > 0:  # at least one key was pressed
        button_resp_2.keys.extend(theseKeys)  # storing all keys
        button_resp_2.rt.append(button_resp_2.clock.getTime())

# *score* updates
if score.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    score.frameNStart = frameN  # exact frame index
    score.tStart = t  # local t and not account for scr refresh
    score.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(score, 'tStartRefresh')  # time at next scr refresh
    score.setAutoDraw(True)
if score.status == STARTED:  # only update if drawing
    score.setText((player1Score), log=False)

# *score_2* updates
if score_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    score_2.frameNStart = frameN  # exact frame index
    score_2.tStart = t  # local t and not account for scr refresh
    score_2.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(score_2, 'tStartRefresh')  # time at next scr refresh
    score_2.setAutoDraw(True)
if score_2.status == STARTED:  # only update if drawing
    score_2.setText((player2Score), log=False)

# *name_1* updates
if name_1.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    name_1.frameNStart = frameN  # exact frame index
    name_1.tStart = t  # local t and not account for scr refresh
    name_1.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(name_1, 'tStartRefresh')  # time at next scr refresh
    name_1.setAutoDraw(True)

# *name_2* updates
if name_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    name_2.frameNStart = frameN  # exact frame index
    name_2.tStart = t  # local t and not account for scr refresh
    name_2.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(name_2, 'tStartRefresh')  # time at next scr refresh
    name_2.setAutoDraw(True)

# *allControllerVariables* updates
if allControllerVariables.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    allControllerVariables.frameNStart = frameN  # exact frame index
    allControllerVariables.tStart = t  # local t and not account for scr refresh
    allControllerVariables.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(allControllerVariables, 'tStartRefresh')  # time at next scr refresh
    allControllerVariables.setAutoDraw(True)
if allControllerVariables.status == STARTED:  # only update if drawing
    allControllerVariables.setText(('1',joystick_2.device.getAllButtons(),"2", 

button_resp_2.pressedButtons,‘3’,
button_resp_2.newPressedButtons
), log=False)

# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
    core.quit()

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
    break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in trialComponents:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break  # at least one component has not yet finished

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()

-------Ending Routine “trial”-------

for thisComponent in trialComponents:
if hasattr(thisComponent, “setAutoDraw”):
thisComponent.setAutoDraw(False)

This is an end routine comment

This ends the end routine comment

store data for thisExp (ExperimentHandler)

thisExp.addData(‘joystick.x’, joystick.x)
thisExp.addData(‘joystick.y’, joystick.y)
thisExp.addData(‘joystick.time’, joystick.time)
[thisExp.addData(‘joystick.button_{0}’.format(i), joystick.buttonLogs[i]) for i in joystick.activeButtons if len(joystick.buttonLogs[i])]
thisExp.addData(‘joystick.started’, joystick.tStart)
thisExp.addData(‘joystick.stopped’, joystick.tStop)
thisExp.nextEntry()

store data for thisExp (ExperimentHandler)

thisExp.addData(‘joystick_2.x’, joystick_2.x)
thisExp.addData(‘joystick_2.y’, joystick_2.y)
thisExp.addData(‘joystick_2.time’, joystick_2.time)
[thisExp.addData(‘joystick_2.button_{0}’.format(i), joystick_2.buttonLogs[i]) for i in joystick_2.activeButtons if len(joystick_2.buttonLogs[i])]
thisExp.addData(‘joystick_2.started’, joystick_2.tStart)
thisExp.addData(‘joystick_2.stopped’, joystick_2.tStop)
thisExp.nextEntry()

check responses

if button_resp.keys in [‘’, , None]: # No response was made
button_resp.keys=None
thisExp.addData(‘button_resp.keys’,button_resp.keys)
if button_resp.keys != None: # we had a response
thisExp.addData(‘button_resp.rt’, button_resp.rt)
thisExp.nextEntry()

check responses

if button_resp_2.keys in [‘’, , None]: # No response was made
button_resp_2.keys=None
thisExp.addData(‘button_resp_2.keys’,button_resp_2.keys)
if button_resp_2.keys != None: # we had a response
thisExp.addData(‘button_resp_2.rt’, button_resp_2.rt)
thisExp.nextEntry()
thisExp.addData(‘name_1.started’, name_1.tStartRefresh)
thisExp.addData(‘name_1.stopped’, name_1.tStopRefresh)
thisExp.addData(‘name_2.started’, name_2.tStartRefresh)
thisExp.addData(‘name_2.stopped’, name_2.tStopRefresh)
thisExp.addData(‘allControllerVariables.started’, allControllerVariables.tStartRefresh)
thisExp.addData(‘allControllerVariables.stopped’, allControllerVariables.tStopRefresh)

the Routine “trial” was not non-slip safe, so reset the non-slip timer

routineTimer.reset()

This is an end experiment comment

This ends the end experiment comment

Flip one final time so any remaining win.callOnFlip()

and win.timeOnFlip() tasks get executed before quitting

win.flip()

these shouldn’t be strictly necessary (should auto-save)

thisExp.saveAsWideText(filename+‘.csv’, delim=‘auto’)
thisExp.saveAsPickle(filename)
logging.flush()

make sure everything is closed down

if eyetracker:
eyetracker.setConnectionState(False)
thisExp.abort() # or data files will save again on exit
win.close()
core.quit()

Hey guys, so I haven’t stopped coding since posting this, I think I’ve finally found an acceptable way.

if joystick_2.device.getButton(1):
player2Score = player2Score + 1
player2InputTimer = (time.time()+.5)

One thing that was confusing is evidently the a,b, select, and start buttons are part of the button_resp_ thing, but they can evidently be grabbed from the joystick function.

So to grab the state of the buttons I wound up not using button_resp_, but rather joystick_2.device.getButton(1):