OS - Win10
PsychoPy version 2020.1.3
Standard Standalone
I want to pick up an object and drop it into one of two boxes. I want to record which box it was dropped into and then determine if it is the correct one.
I have code that picks up the object and drops it off into the box and everything works great.
EXCEPT if i just click on the box instead of dropping the object there it also works. Not what I want.
I have the following code to handle the mouse and then use the mouse component to determine if the clickable stimuli were pressed to exit the routine. This detects if the mouse is clicked in one of the boxes. But it does not tell me if the object was in it when it was clicked. I introduced a variable āpickedupā to determine if the object was picked up. I then tried to use it as a condition in the mouse component. However the mouse component never exits. I suspect it may be a scope issue but do not know.
Below is the code and the mouse component settings. Any help would be appreciated.
#code_7 begin routine
#note: definition of mouse must be the same name as the mouse component
def movePicked(picked, mouse2, grabbed):
if grabbed is not None and mouse2.isPressedIn(grabbed):
grabbed.pos = mouse2.getPos()
return grabbed
else:
for piece in picked:
if mouse2.isPressedIn(piece) and grabbed is None:
return piece
picked = []
movingPiece = None
boxchosen = None
pickedup = 0
#code_7 each frame
if mouse2.isPressedIn(blueboat1) and movingPiece is None:
picked.append(blueboat1)
pickedup = 1
if mouse2.isPressedIn(leftbox1):
boxchosen = 'left'
if mouse2.isPressedIn(rightbox1):
boxchosen = 'right'
movingPiece = movePicked(picked, mouse2, movingPiece)
thisExp.addData('boxchosen', boxchosen)
Thanks for your reply. The piece of code you referred to is just to capture the box chosen so that I can determine if it is the correct one in a later piece of code.
The piece of code:
pickedup = 1
I use to determine that the object has been picked up. I want to use that as a condition AND the clickable stimuli box in the mouse component to exit the routine.
If I just use the clickable stimuli box and no condition the routine, PracticeTrial, exits when I click on the left or right box. However I want to exit when the object has also been picked up. I thought using stop on condition $pickedup ==1 would do that. When I use both the routine, does not exit. It looks like the condition is not met.
I suppose exiting the routine could be done directly from the code but I thought using the mouse component, as described above, would also work.
So just incorporate that in your āeach frameā code, by setting continueRoutine = False when the appropriate conditions are met.
From your screenshots, it just looks like you use that expression to terminate the mouse component. All that will do is stop the mouse doing anything beyond that point. As above, terminate the routine explicitly in your āeach frameā code.
I changed the code as shown below. when the mouse moves over the rightbox1 or leftbox1 the routine exits immediately and looks very jerky. However, I want it to exit when the box is clicked, not when the box is entered. Which is what I thought mouse2.isPressedin would do.
I vaguely remember reading somewhere that if you already have something picked up that you could not click again. Is that true?
It is so close to a solution but not quite.
Thanks again for your help and any further suggestions would be greatly appreciated.
Phil
#each frame
if mouse2.isPressedIn(blueboat1) and movingPiece is None:
picked.append(blueboat1)
pickedup = 1
if mouse2.isPressedIn(leftbox1) and movingPiece is not None:
boxchosen = 'left'
continueRoutine = False
if mouse2.isPressedIn(rightbox1)and movingPiece is not None:
boxchosen = 'right'
continueRoutine = False
movingPiece = movePicked(picked, mouse2, movingPiece)
thisExp.addData('boxchosen', boxchosen)
The requirements here keep shifting so it is tricky to give good adviceā¦
If you drag something into an object by holding the mouse button down then, then yes, mouse.isPressedIn will be True. So you just need to extend your code logic to achieve what you want. e.g. instead of immediately setting continueRoutine = False, set some other flag, like stimulus_dropped_in_leftbox = True (having set it to False at the start of the routine). Youāll also need to set some other flag like waiting_for_mouse_up = True. Then you need to wait until the mouse button is next not pressed, when you can set waiting_for_mouse_up = False.
Then you check for: mouse2.isPressedIn(leftbox1) and stimulus_dropped_in_leftbox and not waiting_for_mouse_up and only then set continueRoutine = False.
You will probably want to draw up a flowchart to get the logic correct.
I got it working once the light came on that a mouse click is a pressed off and back on sequence. It took a while to get the logic right but it now works like a charm. Thanks for providing a sounding board it really helped.
The updated code and mouse component that works is below.
#begin routine
#note: definition of mouse must be the same name as the mouse component
def movePicked(picked, mouse2, grabbed):
if grabbed is not None and mouse2.isPressedIn(grabbed):
grabbed.pos = mouse2.getPos()
return grabbed
else:
for piece in picked:
if mouse2.isPressedIn(piece) and grabbed is None:
return piece
picked = []
movingPiece = None
boxchosen = None
pickedup = 0
mousepressedstatus = []
mouseup = False
testcomplete = False
#Each Frame
if mouse2.isPressedIn(blueboat1):
boxchosen = None
if movingPiece is None:
picked.append(blueboat1)
if mouse2.isPressedIn(leftbox1) and movingPiece is not None:
if mouseup == True:
testcomplete = True
boxchosen = 'left'
thisExp.addData('boxchosen', boxchosen)
if mouse2.isPressedIn(rightbox1) and movingPiece is not None:
if mouseup == True:
testcomplete = True
boxchosen = 'right'
thisExp.addData('boxchosen', boxchosen)
if mouse2.getPressed()[0] == 0 and boxchosen is not None:
mouseup = True
if testcomplete == True:
#practice upto 3 times until they get it right
thisExp.addData('boxchosen2', boxchosen)
if boxchosen == PracticeAnswer:
thisExp.addData('correct', '1')
trials_2.finished = True # stop the loop
else:
thisExp.addData('correct', '0') #otherwise go around again
continueRoutine = False
movingPiece = movePicked(picked, mouse2, movingPiece)