Fairly new to PsychoPy/Python, so bear with me. I’m trying to create a task where people “dig” for gold. For this I’ve created an array which holds the coordinates, the status (dug/not-dug) and whether it contains gold. For a set number of clicks (while loop) I want to draw the grid (eventually based on the status column, with say different shades), which refreshes the display each click. So far I’ve got the grid programmed and I can display all elements as either black (no gold) or yellow (gold). I’ve also got a blue circle showing in click positions for now, just so i know clicks have been registered.
So my question is, does the below code look at all optimal or efficient? The reason I ask is that the timing is showing that it takes around .35 seconds to draw the grid. About half of this seems to be taken up by the draw command - if I comment out patch.draw() it is about .16 seconds.
In PsychToolBox I would take advantage of the buffer clear parameter, to hold contents on the screen and only redraw the clicked square. But as I understand it, that’s not how the buffers/draw work in PsychoPy.
I can’t find a lot of help for it, but I’m assuming that “ElementArrayStim” might be the solution here. Could I go about setting up squares of different colours with that?
from psychopy import visual, event, core
from psychopy.event import Mouse
import numpy as np
import time, random
win = visual.Window([1200,1200])
mouse = Mouse(visible=True)
stimBlue = visual.Circle(win, radius=.01, edges=64, fillColorSpace='rgb255', fillColor=[0, 0, 255])
gridSize = 40
gridWidth = .9 # how much border around grid (1 = none)
patchSize = (gridWidth*2)/gridSize
goldQuantity = 15
gridX = np.linspace(0-gridWidth,0+gridWidth,gridSize)
numEl = gridSize ** 2
gridDetails = np.zeros((numEl, 4)) # X, Y, status, gold
gridDetails[:, 0] = np.resize(gridX, numEl)
gridDetails[:, 1] = np.resize(np.transpose(np.tile(gridX, (gridSize, 1))), numEl)
gold = np.random.choice(numEl, goldQuantity)
for g in gold: gridDetails[g, 3] = 1
mouse_clicked = False
patch = visual.Rect(win=win, width=patchSize, height=patchSize, fillColorSpace='rgb255')
stimBlue.opacity = 0
for i in range(0,5):
t0 = time.clock()
for g in gridDetails:
patch.pos = g[0:2]
if g[3] == 1:
patch.fillColor = [255, 255, 0]
else:
patch.fillColor = [0, 0, 0]
patch.draw()
t1 = time.clock()
stimBlue.draw()
win.flip()
print(t1-t0)
while True:
if mouse.getPressed()[0] == 1: # button press detected
mouse_clicked = True
if mouse.getPressed()[0] == 0 and mouse_clicked: # button must have been released
mouse_clicked = False
stimBlue.pos = mouse.getPos()
stimBlue.opacity = 1
break