我对Matlab很陌生,但确实想改进。在我的实验中,我想展示一张图片,参与者使用两个不同的键(f&g)对其做出是/否的回答,然后展示下一张图片并继续重复。
展示图片,使用按键效果很好,但我无法让它重复试用。因此,我的问题是如何让程序重复/循环我的试用?到目前为止,我的代码中是否有错误,或者我应该使用其他编码?
这是我到目前为止的代码
function try1_6()
cleanupObj= onCleanup(@() myCleanupFxn);
% PRETEST
% Initialize screen with black background
winID = Screen('openWindow',0, [0 0 0]);
%Parameter
backcol=255;
textcol=0;
% Load image file(s)
structimages= [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i=1: length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structimages(end+1).filename=TheImagesdir(i).name;
structimages(end).destRect= destRect;
structimages(end).texture= myTexture;
end
%Make triallist
numberOfItems= [5]; %list of all possible items
Nrepeats=4;
Response=0;
TrialList=HH_mkTrialList({numberOfItems Response},Nrepeats);
%PRESENTATION
for trialnum=1:size(TrialList,1)
nitems = TrialList(trialnum,1);
Screen('FillRect', winID,backcol); % makes the screen blank
%displays text
DrawFormattedText(winID,'dkjfghaslkdfglksdjgfh','center','center',textcol);
Screen('Flip', winID)
HH_waitForKeyPress({'space'}); % waits for spacebar to be pressed
Screen('FillRect',winID,backcol);
Screen('Flip',winID);
WaitSecs(1);
%display picture
whichTheImages= randi(length(TheImagesdir)); % randomly selects image for directory
Screen('FillRect',winID,backcol);
Screen('DrawTexture', winID, myTexture, [], destRect);
Screen('Flip', winID);
HH_waitForKeyPress({'f','j'},5)
if resp==-1
break
end
TrialList(trialnum,4)= response; %records response
end
end
function myCleanupFxn()
Screen('CloseAll')
end
代码中有许多问题需要解决。首先,TrialList
是在声明/初始化之前使用的。Make triallist
代码块在for
循环的主体中似乎不合适,可能应该放在循环TrialList
之前。
第二个问题是加载图像的内部for
循环。现在,它加载目录中找到的每一个图像,每次试用都你没有理由这么做,你也应该把这个for
循环放在试验循环之外。此外,您的原始代码从未按预期工作,因为您从未将加载的纹理保存在任何位置;myTexture
会被文件夹中的最后一张图像覆盖,这是你唯一能得到的纹理。因此,除了在循环之前预加载图像外,还需要将它们保存在数据结构中,以便稍后在试验循环中使用。一个简单的struct
在这里可以很好地工作:
structImages = [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i = 1:length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structImages(end+1).filename = TheImagesdir(i).name;
structImages(end).destRect = destRect;
structImages(end).texture = myTexture;
end
您的代码中还有其他不一致之处:
- 已定义但未使用
whichTheIamges
resp
用于比较if resp==-1
,但未定义response
在定义之前被保存到TrialList
中
最后,最大的问题是Screen('CloseAll', winID);
在试用循环中,所以你在第一次试用后就拆除了整个演示平台。
仅供参考,正如我在评论中所指出的,将整个脚本封装在try
块中是非常糟糕的做法。我怀疑你这样做是因为你想在任务中期Ctrl+C,但有更好的方法可以做到这一点。如果您将整个脚本设置为一个函数,那么每当函数退出时(无论是正常、错误还是中断),都可以使用onCleanup
方法执行代码。方法如下:
function myScript()
%//make your script a function. There is an additional advantages to doing this:
%//function performance is better than script performance.
%//blah-blah-blah
%//setup the cleanup object before opening screen
cleanupObj = onCleanup(@() myCleanupFxn);
%//open the screen
winID = Screen('openWindow',0, [0 0 0]);
%//blah-blah-blah
end
function myCleanupFxn()
%//local function, not visible outside of this file
Screen('CloseAll');
end