Как я могу создать скользящий курсор с определенной формой в PsychToolBox?

Это должно быть похоже на это http://prntscr.com/dezwb6. красный прямоугольник должен двигаться как курсор.

он должен быть создан с помощью цикла while, но я пытался использовать цикл for

 for x=1:1366 % my screen's length
        if( x > 383) & (x < 983)  % in order to keep cursor within the borders of the green rectangle
                  cLeft=x; % I determine the left s,de of the red rectangele
            cRight=cLeft+20; % with using lef side I determine right side

            cTop=374; %  I determine top side with using the same values with green rectangle
            cBottom=394;% bottom border of the red rectangle

            RedRect=[cLeft,cTop,cRight,cBottom]; % I determine the all sides of the rectangle

            Red=[255 50 50]%I determine the color of the rect

          Screen('FillRect',myWindow,Red,RedRect); % I try to create a rectangular %with using cursor' position bu it didn't work:/

        end 

    end

1 ответ

Решение

Я создаю прямоугольники в цикле while и использую if, если решение и задача решены. здесь наш скользящий прямоугольник. Кстати, комментарии на турецком языке извините за это, я изменю их, как только.

clear all


ListenChar(2);
% krem rengi bir pencere oluşturdum
[myWindow, rect] = Screen('OpenWindow',0,[230 230 230]);

%imleci sakladım
Screen('HideCursorHelper', 0, 0)

%ekranın merkezini belirledim
centerX=rect(3)/2;
centerY=rect(4)/2;

% imleci ekranın mekerkezine koydum
SetMouse(centerX, centerY);

% while loop kullanarak ekrandaki diğer ögeleri oluştrum
buttons=0;
while ~buttons
    % mouse hareketlerini alıyorum
    [x, y, buttons] = GetMouse(myWindow);


    % x imlecin yatay eksendeki yerini belitiyor
    % 383 ve 983 yeşil dörtgenimin sınırları imlecimin yani kırmızı
    % dörtgenimin bu sınırlar içinde kalması için if kullanarak bir
    % statement oluşturuyorum
    if ( x > 383) & (x < 983)

    % ekrana ilgili cümleyi yazdırıyorum    
    Screen('TextSize', myWindow,20);
    Screen('TextFont', myWindow, 'Times');
    [normBoundsRect, offsetBoundsRect]=Screen('TextBounds',myWindow, 'Adjust the slide below according to your confidence level');
    Screen('DrawText', myWindow, 'Adjust the slide below according to your confidence level', (centerX-(normBoundsRect(3)/2)),(centerY-(normBoundsRect(4)/2+100)), [0,0,0]);


    % ekranın bir tarafına not confident yazdırıyorum
    Screen('TextSize', myWindow,20);
    Screen('TextFont', myWindow, 'Times');
    [normBoundsRect, offsetBoundsRect]=Screen('TextBounds',myWindow, 'Not Confident');
    Screen('DrawText', myWindow, 'Not Confident', (centerX-(normBoundsRect(3)/2-250)),(centerY-(normBoundsRect(4)/2+30)), [0,0,0]);


    % ekranın diğer tarafına very confident yazdırıyorum
    Screen('TextSize', myWindow,20);
    Screen('TextFont', myWindow, 'Times');
    [normBoundsRect, offsetBoundsRect]=Screen('TextBounds',myWindow, 'Very Confident');
    Screen('DrawText', myWindow, 'Very Confident', (centerX-(normBoundsRect(3)/2+250)),(centerY-(normBoundsRect(4)/2+30)), [0,0,0]);


    % yeşil dörtgenimi çiziyorum, aslında belirlediğim centerları
    % kullanarak yazmayı denedim ancak çalışmadı o yüzden kendi ekran
    % boyutuma göre orta noktaya yerleştirdim(1366*768)
    % Screen('FrameRect',myWindow,[50,205,50], [centerX-300, centerY +10,centerX+300, centerY-10],... 5);
     Screen('FrameRect',myWindow,[50,205,50], [383, 374,983, 394], [5])

     % yeşil dörtgenin içini beyaza boayadım
     Screen('FillRect', myWindow,[255,255,255], [388,379,979,389])


    % yeşil kutunun altında yazması gerekeni yazdırdım
    Screen('TextSize', myWindow,15);
    Screen('TextFont', myWindow, 'Times');
    [normBoundsRect, offsetBoundsRect]=Screen('TextBounds',myWindow, 'Note: Slide red rectangle to indicate your confidence level');
    Screen('DrawText', myWindow, 'Note: Slide red rectangle to indicate your confidence level', (centerX-(normBoundsRect(3)/2)),(centerY-(normBoundsRect(4)/2-100)), [0,0,0]);


     % x'i yani imlecin koordinatlarını kullanarak, 10 piksel kalınlığında,
     % x'in sağına ve soluna 5 piksel gidecek şekilde kırmızı kutuyu
     % çizdirdim
    Screen('FillRect',myWindow,[255 50 50],[x-5,374, x+5, 394])

            % kutuyu ekranda gösterdim
            Screen('Flip',myWindow)
    end

    % yeni bir if kullanarak eğer farenin tuşlarının basılırsa bu loop'u
    % bitirmesini söyledim
    if buttons==1
        break
    end

end 


% clickleri toplamasını söyledim
[clicks, x, y, buttons] = GetClicks(myWindow);


% ListenChar kodunu kullandım ama sanırım işe yaramıyor, ctrl+c yapmadan klavye
% kullanılamıyor
ListenChar(1);


Screen('CloseAll');

% command window'a nereye tıklandığını yazdırdım
fprintf('You clicked at %d and %d x-y location.\n', x, y);

Может быть, это все еще полезно. Я написал функцию именно для этого с вертикальной линией, которая называется slideScale. Если вы хотите посмотреть, как это работает, посмотрите тестовый скрипт.

Код:

function [position, RT, answer] = slideScale(screenPointer, question, rect, endPoints, varargin)
%SLIDESCALE This funtion draws a slide scale on a PSYCHTOOLOX 3 screen and returns the
% position of the slider in pixel as well as the rection time and if an answer was given.
%
%   Usage: [position, secs] = slideScale(ScreenPointer, question, center, rect, endPoints, varargin)
%   Mandatory input:
%    ScreenPointer  -> pointer to the window
%    question       -> Text string containing the question
%    rect           -> Double contatining the screen size.
%                      Obtained with [myScreen, rect] = Screen('OpenWindow', 0);
%    endPoints      -> Cell containg the two text string of the left and right
%                      end of the scala. Exampe: endPoints = {'left, 'right'};
%
%   Varargin:
%    'linelength'    -> An integer specifying the lengths of the ticks in
%                       pixels. The default is 10.
%    'width'         -> An integer specifying the width of the scala leine in
%                       pixels. The default is 3.
%    'scalalength'   -> Double value between 0 and 1 for the length of the
%                       scale. The default is 0.9.
%    'scalaposition' -> Double value between 0 and 1 for the position of the
%                       scale. 0 is top and 1 is bottom.
%    'device'        -> A string specifying the response device. Either 'mouse' 
%                       or 'keyboard'. The default is 'mouse'.
%    'responsekey'   -> String containing name of the key from the keyboard to log the
%                       response. Example. The default is 'return'.
%    'slidecolor'    -> Vector for the color value of the slider [r g b] 
%                       from 0 to 255. The dedult is red [255 0 0].
%    'scalacolor'    -> Vector for the color value of the scale [r g b] 
%                       from 0 to 255.The dedult is black [0 0 0].
%    'aborttime'     -> Double specifying the time in seconds after which
%                       the function should be aborted. In this case no
%                       answer is saved. The default is 8 secs.
%    'image'         -> An image saved in a uint8 matrix. Use
%                       imread('image.png') to load an image file.  
%
%   Output:
%    'position'      -> Deviation from zero in percentage, 
%                       with -100 <= position <= 100 to indicate left-sided
%                       and right-sided deviation.
%    'RT'            -> Reaction time in milliseconds.
%    'answer'        -> If 0, no answer has been given. Otherwise this
%                       variable is 1.
%
%   Author: Joern Alexander Quent
%   e-mail: alexander.quent@rub.de
%   Version history:
%                    1.0 - 01/04/2016 - First draft
%                    1.1 - 02/18/2016 - Added abort time and option to
%                    choose between mouse and key board
%                    1.2 - 05/10/2016 - End points will be aligned to end
%                    ticks
%                    1.3 - 06/01/2016 - Added the possibility to display an
%                    image



%% Return error if in multi display mode!
screens       = Screen('Screens');
if length(screens) > 1
    error('Multi display mode not supported.');
end

%% Parse input arguments
% Default values
center        = round([rect(3) rect(4)]/2);
lineLength    = 10;
width         = 3;
scalaLength   = 0.9;
scalaPosition = 0.8;
sliderColor    = [255 0 0];
scaleColor    = [0 0 0];
device        = 'mouse';
aborttime     = 8;
responseKey   = KbName('return');
drawImage     = 0;

i = 1;
while(i<=length(varargin))
    switch lower(varargin{i})
        case 'linelength'
            i             = i + 1;
            lineLength    = varargin{i};
            i             = i + 1;
        case 'width'
            i             = i + 1;
            width         = varargin{i};
            i             = i + 1;
        case 'scalalength'
            i             = i + 1;
            scalaLength   = varargin{i};
            i             = i + 1;
        case 'scalaposition'
            i             = i + 1;
            scalaPosition = varargin{i};
            i             = i + 1;
        case 'device' 
            i             = i + 1;
            device = varargin{i};
            i             = i + 1;
        case 'responsekey'
            i             = i + 1;
            responseKey   = KbName(varargin{i});
            i             = i + 1;
        case 'slidecolor'
            i             = i + 1;
            sliderColor    = varargin{i};
            i             = i + 1;
        case 'scalacolor'
            i             = i + 1;
            scaleColor    = varargin{i};
            i             = i + 1;
        case 'aborttime'
            i             = i + 1;
            aborttime     = varargin{i};
            i             = i + 1;
        case 'image'
            i             = i + 1;
            image         = varargin{i};
            i             = i + 1;
            imageSize     = size(image);
            stimuli       = Screen('MakeTexture', screenPointer, image);
            drawImage     = 1; 
    end
end

% Sets the default key depending on choosen device
if strcmp(device, 'mouse')
    responseKey   = 1; % X mouse button
end

%% Coordinates of scale lines and text bounds
midTick    = [center(1) rect(4)*scalaPosition - lineLength - 5 center(1) rect(4)*scalaPosition  + lineLength + 5];
leftTick   = [rect(3)*(1-scalaLength) rect(4)*scalaPosition - lineLength rect(3)*(1-scalaLength) rect(4)*scalaPosition  + lineLength];
rightTick  = [rect(3)*scalaLength rect(4)*scalaPosition - lineLength rect(3)*scalaLength rect(4)*scalaPosition  + lineLength];
horzLine   = [rect(3)*scalaLength rect(4)*scalaPosition rect(3)*(1-scalaLength) rect(4)*scalaPosition];
textBounds = [Screen('TextBounds', screenPointer, endPoints{1}); Screen('TextBounds', screenPointer, endPoints{2})];
if drawImage == 1
    rectImage  = [center(1) - imageSize(2)/2 rect(4)*(scalaPosition - 0.2) - imageSize(1) center(1) + imageSize(2)/2 rect(4)*(scalaPosition - 0.2)];
    if rect(4)*(scalaPosition - 0.2) - imageSize(1) < 0
        error('The height of the image is too large. Either lower your scale or use the smaller image.');
    end
end

%% Loop for scale loop
t0                         = GetSecs;
answer                     = 0;
while answer == 0
    [x,y,buttons,focus,valuators,valinfo] = GetMouse(screenPointer, 1);
    if x > rect(3)*scalaLength
        x = rect(3)*scalaLength;
    elseif x < rect(3)*(1-scalaLength)
        x = rect(3)*(1-scalaLength);
    end

    % Draw image if provided
    if drawImage == 1
         Screen('DrawTexture', screenPointer, stimuli,[] , rectImage, 0);
    end

    % Drawing the question as text
    DrawFormattedText(screenPointer, question, 'center', rect(4)*(scalaPosition - 0.1)); 

    % Drawing the end points of the scala as text
    DrawFormattedText(screenPointer, endPoints{1}, leftTick(1, 1) - textBounds(1, 3)/2,  rect(4)*scalaPosition+10, [],[],[],[],[],[],[]); % Left point
    DrawFormattedText(screenPointer, endPoints{2}, rightTick(1, 1) - textBounds(2, 3)/2,  rect(4)*scalaPosition+10, [],[],[],[],[],[],[]); % Right point

    % Drawing the scala
    Screen('DrawLine', screenPointer, scaleColor, midTick(1), midTick(2), midTick(3), midTick(4), width);         % Mid tick
    Screen('DrawLine', screenPointer, scaleColor, leftTick(1), leftTick(2), leftTick(3), leftTick(4), width);     % Left tick
    Screen('DrawLine', screenPointer, scaleColor, rightTick(1), rightTick(2), rightTick(3), rightTick(4), width); % Right tick
    Screen('DrawLine', screenPointer, scaleColor, horzLine(1), horzLine(2), horzLine(3), horzLine(4), width);     % Horizontal line

    % The slider
    Screen('DrawLine', screenPointer, sliderColor, x, rect(4)*scalaPosition - lineLength, x, rect(4)*scalaPosition  + lineLength, width);

    % Flip screen
    onsetStimulus = Screen('Flip', screenPointer);

    % Check if answer has been given
    if strcmp(device, 'mouse')
        secs = GetSecs;
        if buttons(responseKey) == 1
            answer = 1;
        end
    elseif strcmp(device, 'keyboard')
        [keyIsDown, secs, keyCode] = KbCheck;
        if keyCode(responseKey) == 1
            answer = 1;
        end
    else
        error('Unknown device');
    end

    % Abort if answer takes too long
    if secs - t0 > aborttime 
        break
    end
end
%% Calculating the rection time and the position
RT                = (secs - t0)*1000;                                          % converting RT to millisecond
scaleRange        = round(rect(3)*(1-scalaLength)):round(rect(3)*scalaLength); % Calculates the range of the scale
scaleRangeShifted = round((scaleRange)-mean(scaleRange));                      % Shift the range of scale so it is symmetrical around zero
position          = round((x)-mean(scaleRange));                               % Shift the x value according to the new scale
position          = (position/max(scaleRangeShifted))*100;                     % Converts the value to percentage
end
Другие вопросы по тегам