I have created two stimuli(red and green rectangles) as stimuli in Psychopy. Also, I have enabled mouse movements to four directions. Using the function[mouse.getPressed()] in Psychopy for selecting the stimuli, I am facing some issues. Basically, I want the mouse to move in four directions, and when the mouse reaches red/green rectangle stimuli, I need to select that stimuli and change its color to blue.
Can anyone look into the issue and help me to resolve the same?
Here is my code:
from psychopy import visual, core, event
import numpy as np
# Create a window.
# For configuring and debugging the code turn off full screen.
fullscr = False
win = visual.Window(
[1200,1000],
monitor="testMonitor",
units="deg",
fullscr=fullscr
)
#cursor = visual.Circle(win, radius=0.2)
#cursor = visual.CustomMouse(win,
# leftLimit=-10, topLimit=10, rightLimit=10, bottomLimit=-10,
# showLimitBox=True, clickOnUp=True)
pos_zero = (0, 0)
cursor = visual.Rect(
win=win,
size=400,
pos=pos_zero,
opacity=0
)
mouse = event.Mouse(visible=True)
# Sinusoidal control version.
freq_one = 0.5
freq_two = 1.5
# Colors of the rectangles.
#color_zero='black'
color_one = 'red'
color_two = 'green'
# Positions of the rectanges.
pos_one = (-10, 0)
pos_two = (10, 0)
start = core.getTime()
cnt = 0
cursor.pos = mouse.getPos()
print cursor.pos
while cnt<600:
second = core.getTime() - start
sin_val_one = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_one))
sin_val_two = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_two))
#while not mouse.getPressed()[0]:
# Do something if mouse moved
for key in event.getKeys():
if key == 'escape':
core.quit()
elif key == "right":
cursor.pos = cursor.pos + (2,0)
elif key =="left":
cursor.pos = cursor.pos - (2,0)
elif key =="up":
cursor.pos = cursor.pos + (0,2)
elif key =="down":
cursor.pos = cursor.pos - (0,2)
#if cursor.pos == pos_one:
# mouse.getpressed(rect_one)
#elif cursor.pos == pos_two:
# mouse.getpressed(rect_two)
mouse.setPos(cursor.pos)
mouse.lastPos = cursor.pos
rect_one = visual.Rect(
win=win,
fillColor=color_one,
lineColor=color_one,
size=15,
pos=pos_one,
opacity=sin_val_one
)
rect_two = visual.Rect(
win=win,
fillColor=color_two,
lineColor=color_two,
size=15,
pos=pos_two,
opacity=sin_val_two
)
#images = [rect_one, rect_two]
#for image in images:
# if mouse.isPressedIn(image):
# pressed_shape = shape
#
# pressed_image.fillColor = 'blue'
# pressed_image.draw()
# print pressed_image.name
rect_one.draw()
rect_two.draw()
cursor.draw()
win.flip()
cnt += 1
win.close()
Any help is greatly appreciated. Thanks!
I made several changes and post the updated code below. It's significantly shorter and simpler.
Removed everything using mouse. Since you just want something visual to move on key presses, there's no need to invoke the mouse - especially when you actually don't want subjects to use the mouse...
Create the colored shapes once, then updating the color during runtime. This is significantly faster, i.e. avoids dropping frames.
Changed the cursor size. It was 400 degrees!
Removed the line around the rectangles so that only fillColor
needs to be changed on overlap.
A few other simplifications.
Here is the code:
from psychopy import visual, core, event
import numpy as np
# Settings
fullscr = False
directions = {'left': (-2,0), 'right': (2,0), 'up': (0, 2), 'down': (0, -2)}
freq_one = 0.5 # # Sinusoidal control
freq_two = 1.5
# Create a window.
win = visual.Window([1200,1000], monitor="testMonitor", units="deg", fullscr=fullscr)
# The two rectangles
rect_one = visual.Rect(win=win, fillColor='red', lineColor=None, size=15, pos=(-10, 0))
rect_two = visual.Rect(win=win, fillColor='green', lineColor=None, size=15, pos=(10, 0))
# Cursor
cursor = visual.Circle(win, fillColor='white', radius=0.2)
# Run five trials
for trial in range(5):
# Set to initial condition
rect_one.fillColor = 'red'
rect_two.fillColor = 'green'
cursor.pos = (0, 0)
# Start task
start = core.getTime()
for frame in range(600):
# Set rectangle opacities
second = core.getTime() - start
rect_one.opacity = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_one))
rect_two.opacity = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_two))
# Show it
rect_one.draw()
rect_two.draw()
cursor.draw()
win.flip()
# Get keyboard responses and change color if there is overlap
for key in event.getKeys():
if key == 'escape':
core.quit()
elif key in directions.keys(): # if this is a key corresponding to a direction
cursor.pos += directions[key] # Lookup the pos change in "directions" and add it to current position
if cursor.overlaps(rect_one):
rect_one.fillColor = 'blue'
if cursor.overlaps(rect_two):
rect_two.fillColor = 'blue'