Я создал игру для нового исследования, которое я буду запускать, используя Psychtoolbox (3.0.13, flavour beta) в Matlab R2018a, и условие для выхода из цикла while в пробной версии, которая иногда является нажатием пробела, иногдаработает сразу, но иногда требуется несколько нажатий клавиш для выхода.
Я попытался сделать свой код более эффективным, удалив ненужный код и вставив время ожидания, прежде чем показывать стимулы на случай, если это решит проблему.У меня есть цикл while, который требует ввода щелчков мыши вместе с нажатием пробела, чтобы удовлетворить условия выхода.Код выполняется в конце, но я просто не понимаю, почему иногда достаточно одного нажатия пробела, а в других случаях мне нужно нажать его 3 раза, чтобы выйти.У меня та же проблема в другой задаче, где я также использую щелчки мыши и нажатие клавиши пробела (и звука нет, поэтому я не думаю, что звук вызывает его) в качестве условий для выхода из цикла while.Интересно, это как-то связано с тем, как я использую структуру RECS, и могу ли я использовать более эффективный способ?Было бы замечательно, если бы кто-нибудь имел представление о том, как улучшить это в задаче.
% Start game: They play a total of 5 games. A game finishes when
% they have selected at least 1 card and pressed spacebar.
for Game = 1:5
% If ESC is pressed, quit game.
if OM.ESC == 0
% Draw wooden background
Screen('DrawTexture', OM.wid, OM.greywoodTexture);
% Show score and game counter
Screen('TextSize', OM.wid, OM.textSize);
DrawFormattedText(OM.wid, ['Score: ', num2str(OM.Score)], ...
OM.origin(1)+750, OM.origin(2)-400);
DrawFormattedText(OM.wid, ['Game: ', num2str(Game)], ...
OM.origin(1), OM.origin(2)-425);
% create sequence for where Randy wil be and randomise it
sequence = [1 0 0 0 0 0 0 0 0 0];
sequence = sequence(randperm(length(sequence)));
% Draw the cards upside down
for i = 1:length(RECS)
Screen('DrawTexture', OM.wid, OM.cardsTexture, [], RECS(i).rectangles);
end
% Show the cards and get the time. If it's the first game, use 0.5
% seconds before showing to make sure the game is up to speed. (Thought
% this might help with speed later on, not sure if it does.)
if Game == 1
WaitSecs(0.5);
end
timage = GetSecs;
Screen('Flip', OM.wid);
% set screenpress and loss to 0
Screenpress = 0;
loss = 0;
% wait for screenpress (space bar press)
while Screenpress == 0 && OM.ESC == 0 % checks for completion
[keyIsDown, keyTime, keyCode] = KbCheck;
if keyIsDown
keyStroke = KbName(keyCode);
% check if space was pressed and atleast one card was
% selected
if any(strcmpi(keyStroke,OM.screenKey)) && sum([RECS(:).pressed]) ~= 0
Screenpress = 1;
RT = round((keyTime - timage)*1000);
elseif any(strcmpi(keyStroke,OM.exitKey))
OM.ESC = 1;
RT = 0;
break;
end
end
% check if the mouse was pressed inside any of the rectangles
% (cards)
[mx,my,buttons] = GetMouse(); %waits for a key-press
for i = 1:length(RECS)
if IsInRect(mx, my, RECS(i).rectangles) == 1 && sum(buttons) > 0 && RECS(i).pressed == 0
RECS(i).pressed = 1;
elseif IsInRect(mx, my, RECS(i).rectangles) == 1 && sum(buttons) > 0 && RECS(i).pressed == 1
% This is to enable de-selecting a card by double
% clicking on it.
RECS(i).pressed = 0;
end
end
% Draw wooden background
Screen('DrawTexture', OM.wid, OM.greywoodTexture);
% Draw score counter
Screen('TextSize', OM.wid, OM.textSize);
DrawFormattedText(OM.wid, ['Score: ', num2str(OM.Score)], ...
OM.origin(1)+750, OM.origin(2)-400);
DrawFormattedText(OM.wid, ['Game: ', num2str(Game)], ...
OM.origin(1), OM.origin(2)-425);
% Draw cards with a frame around it if selected.
for i = 1:length(RECS)
Screen('DrawTexture', OM.wid, OM.cardsTexture, [], RECS(i).rectangles);
if RECS(i).pressed == 1
Screen('FrameRect', OM.wid, OM.selRecColour, RECS(i).rectangles, OM.selRecSize);
end
end
% Show the selected card borders and delay against flicker
WaitSecs(0.2); % need this delay to stop flicker
Screen('Flip', OM.wid);
end % space was pressed, after the cards were selected. Now we need to flip the cards and show what they chose.
% if space was pressed,
% Draw wooden background
Screen('DrawTexture', OM.wid, OM.greywoodTexture);
% Draw score counter
Screen('TextSize', OM.wid, OM.textSize);
DrawFormattedText(OM.wid, ['Score: ', num2str(OM.Score)], ...
OM.origin(1)+750, OM.origin(2)-400);
DrawFormattedText(OM.wid, ['Game: ', num2str(Game)], ...
OM.origin(1), OM.origin(2)-425);
% randomly select the 9 animals to show. Replace is set to false so
% each animal can only be shown once in one game. It needs to be 10,
% else the game won't run if they select 10 cards (just in case they
% do).
animals = datasample(1:26, 10, 'Replace', false);
% Set card count to 0
card_count = 0;
% display animations
for i = 1:length(RECS)
if RECS(i).pressed == 1
% add to card_count if a card was selected
card_count = card_count + 1;
Screen('FrameRect', OM.wid, OM.selRecColour, RECS(i).rectangles, OM.selRecSize);
if sequence(i) == 0 % normal animal
t = animals(i);
Screen('FillRect', OM.wid, OM.turnedCardColour, RECS(i).rectangles)
Screen('DrawTexture', OM.wid, ANIMAL(t).AniTexture, [], RECS(i).animals);
elseif sequence(i) == 1 % troll face
Screen('FillRect', OM.wid, OM.redColour, RECS(i).rectangles)
Screen('DrawTexture', OM.wid, OM.trollTexture, [], RECS(i).animals);
% play giggle if Randy was selected
PsychPortAudio('Start', OM.giggle, 1);
loss = 1;
end
else
% Show the cards upside down for the ones that weren't
% selected.
Screen('DrawTexture', OM.wid, OM.cardsTexture, [], RECS(i).rectangles);
end
end
Screen('Flip', OM.wid);
WaitSecs(2);
% Draw wooden background
Screen('DrawTexture', OM.wid, OM.greywoodTexture);
Screen('TextSize', OM.wid, OM.feedbackSize);
% Show text after game round, and determine Score for game
if loss == 1
message = 'Oh no! You lost all your cards for this round...';
DrawFormattedText(OM.wid, message, 'center', 'center', OM.textColor);
Score = 0;
elseif loss == 0
message = sprintf('Well done! You''ve won %d cards this round!', card_count);
DrawFormattedText(OM.wid, message, 'center', 'center', OM.textColor);
Score = card_count;
end
% calculate the total score in the game
OM.Score = OM.Score + Score ;
% Draw score counter
Screen('TextSize', OM.wid, OM.textSize);
DrawFormattedText(OM.wid, ['Score: ', num2str(OM.Score)], ...
OM.origin(1)+750, OM.origin(2)-400);
DrawFormattedText(OM.wid, ['Game: ', num2str(Game)], ...
OM.origin(1), OM.origin(2)-425);
Screen('Flip',OM.wid);
WaitSecs(2); %change back to 1 second. % put to 2 seconds because is delay of showing text?
%% Save the data file
OM.dataFile = fopen(OM.dataFileName, 'a');
fprintf(OM.dataFile, OM.formatString, OM.SJNB, OM.Test_session, OM.Age, OM.Date, Game, RT, card_count, loss, OM.Score);
fclose(OM.dataFile);
% Cleaning this.
for i = 1:10
RECS(i).pressed = 0;
RECS(i).pressedCount = 0;
end
end
end