Polygon appearance and position based on keyboard response

***Win10: **
PsychoPy version 2020.2.10

****What are you trying to achieve?:
I am trying to make a polygon (line) appear based on the key response. The position of this line depends on the key press 1, 2, or 3.

What did you try to make it work?:
I have a keyboard component (‘key_resp’), polygon component (response_line), and a code component.
In the polygon component I have the start time as $key_resp.rt. Since the routine has a fixed 3sec timing, I have the duration set as $line_time.
In code component: In the Begin experiment tab, I define line_pos = []. In the Begin routine tab, I have the following code:

> key_pressed = key_resp.getKeys(['1','2','3'])
> if key_pressed == '1':
>     line_pos = [-0.7, 0.0] #on the left
>     line_time = 3 - key_resp.rt
> if key_pressed == '2':
>     line_pos=[0.0, 0.0] #in the middle
>     line_time = 3 - key_resp.rt
> if key_pressed =='3':
>     line_pos=[0.7, 0.0] #on the right
>     line_time = 3 - key_resp.rt
> else:
>     line_pos = []
> ```

In the end routine tab, I have line_pos = []

I have tried different versions of this code including putting the code in ‘each frame’ tab and end routine tab. However, I haven’t been able to make it work.

What specifically went wrong when you tried that?:
I get a grey screen on the browser after several trials. The line never appears even when the keys are pressed. In the browser console the error seems to be the key presses never being ‘defined’. I get ‘undefined’ when I tried to print the ‘key_pressed’

This is only a part of the routine as I am basically trying to highlight the random images that correspond with keypresses. As my task has code components and is randomized, I’d prefer to not insert another routine for conditional polygon as has been suggested in other threads. I have scavenged the forums trying to make this seemingly simple thing to work… but to no avail. Any help will be much appreciated!

The main issue is that you are getting confused between event.getKeys() which checks the keyboard and key_resp.keys which checks a keyboard component.

Sorry can you clarify what the alternative would be for my code? I have tried key_pressed = key_resp.keys and key_pressed = event.getKeys() but it didn’t work. Thanks for responding!

These only work in Begin Routine if the key was actually pressed to end the previous routine.

I’m sorry if I am not understanding this. Are you suggesting that the only way to make a polygon appear based on the corresponding key response is to insert another routine and have this code in the begin routine tab of code component in this 2nd routine?

I’m also not clear on the difference between keyboard and keyboard component… note that this task needs to be hosted on pavlovia, not sure if that changes things but thank again for helping me!

The code in Begin Routine is only performed once, when the routine starts.

If you are wanting polygons to appear dynamically during a routine then you need to be checking the keyboard every frame.

You can either use a keyboard component to check the keyboard or a code component. I usually use a component if I want the key press to end the routine and event.getKeys() if I want versatility in code.

I tried the following code in each frame of my code component but the polygon line only appears at key press ‘3’. Also the next trial has a flickering line in the same place.
Nothing happens when 1 or 2 or any other keys are pressed. (Again $line_pos is the position in the polygon position field)


keys = event.getKeys(['1', '2', '3'])
for key_pressed in keys:
    if key_pressed == '1':
        line_pos = [-0.7, 0.0] #on the left
    if key_pressed == '2':
        line_pos=[0.0, 0.0] #in the middle
    if key_pressed =='3':
        line_pos=[0.7, 0.0] #on the right
    else:
        line_pos = []

I tried to debug via end routine and put the following:

print(line_pos) 
line_pos = []

I got (2) and [0.7, 0]

Not sure what I’m doing wrong here.

Try

keys = event.getKeys()

    if ‘1’ in keys:
        line_pos = [-0.7, 0.0] #on the left
    elif ‘2’ in keys:
        line_pos=[0.0, 0.0] #in the middle
    elif ‘3’ in keys:
        line_pos=[0.7, 0.0] #on the right
    else:
        line_pos = []

You probably need line_pis=[] in End Routine

1 Like

That worked! Thank you so much!
Really quickly, right now the polygon line appears for a quick second. If I want to extend the duration to a little longer, how will I do that?

Do you want it to sustain for an exact number of frames or an approximate number of milliseconds ?

I was thinking until the next key press or until the routine ends. In terms of approx millisec I’d say about 500ms

If you don’t want a brief presentation why not try removing these lines., which are resetting the line after 1 frame?

That worked but the line flickered at the same position in the next trial. I put a line_pos = [] in the begin routine tab in addition to the line_pos = [] in end routine which took care of it.
Thank you so much for helping me with this!

Personally I wouldn’t use “line_pos=[]” to hide the line. How about line_pos=[2,2] to draw it off the visible screen.

Hi everyone, I know I might be a little late for the party but still want to try :slight_smile:
@anad : what did you set as the polygon position in the component?
I am trying to achieve something quite similar but am not experienced with coding (or PsychoPy). Basically I have a “yes” or “no” response -question for my participants. “yes” and “no” are displayed on the screen in the left and right bottom corners, and the participants have to press either the left or right arrow key to indicate their response. Now I would like to highlight the corresponding response on the screen as a feedback for the participant.
I am using a polygon component for the rectange (only displaying the border to surround the answer; “rect_response”) and a code component to adjust the position according to the keypress. But this doesnt work. If i put a position in the polygon component, it is only displayed at that position and not matching the keypress, but if I dont, I get an immediate error.

keys = event.getKeys()

if ‘left’ in keys:
rect_response_pos = [-0.75, -0.75]
elif ‘right’ in keys:
rect_response_pos = [0.75, -0.75]
else:
rect_response_pos =

Can someone help me with that? Thank you in advance!