matlab sprintf_如何利用Matlab+Psychtoolbox编写打地鼠游戏

a5e575e7ad2f768acca72975a4187950.png

打地鼠(HitHamster)是一款非常有趣的游戏。游戏规则很简单,把冒出头来的地鼠给全部打下去就算成功。本文会详细地介绍如何利用Matlab的Psychtoolbox工具包来实现打地鼠游戏的编写。

这个教程很有趣的一点是,我们会同时用Matlab GUI和Matlab Psychtoolbox两种实验编程框架,这样的对比是一种创新,方便大家从两种不同的角度来领略实验编程的奥义。

一个萝卜一个坑,我们先来看一个坑的时候,地鼠冒头被打的情况。

在写代码之前,我们要准备好材料,包括背景图片,锤子(松开的状态)、锤子(击打的状态)、地鼠(正常的&带坑的)、地鼠(被打晕的&带坑的)和地鼠出没的坑。

模块一:确定背景颜色

一上来先确定背景颜色的RGB参数,我们打开背景图片看一下:

05dd885ebe9646b12bf779ba91a459b1.png
游戏背景图片

我们可以借助微信的截图功能来完成颜色识别。微信一旦开启截图功能,它会自动获取鼠标所在位置的RGB值。如果是苹果mac系统的微信,它是以十六进制显示的数值。当前背景颜色显示的是#C4DE52,需要借助在线的颜色转换,比如下面这个网站来实现:

RGB颜色值与十六进制颜色码转换工具​www.sioe.cn

这个背景颜色的RGB值为196, 222, 82。

模块二:准备好坑和地鼠图片

地鼠出没的坑的图像是这样的:

ace78d833d660fc8e9aee3a92476612e.png

我们的主角地鼠是这样的:

01aaa90e663f961ead0a6798b12289fb.png

一旦被锤子击中,就会出现晕眩的画面:

b547c98a5616a8d3e8d932ac0829d1b2.png

这相当于给了被试一个反馈,地鼠已被击中!

有了背景和坑,就可以预先布置好场景,形成整个游戏的背景。第一段代码,我们要实现的是:布置好游戏的背景画面。

我们试着先用Matlab GUI来实现这个游戏场景的布置,然后再用Matlab+Psychtoolbox做一个镜像,这样对比的好处是可以横向比价两者的利弊。

Matlab GUI的代码:

% function y = guiGame_HitHamster(~)
 
% clear
clc; clear; close all;
 
% prepare bkground color
bkgColor = [196, 222, 82]/255;
 
% get the screen size, for the iMac Pro, it is [1 1 2560 1440]
rect = get(0 , 'ScreenSize');
width_Screen = rect(3);
height_Screen = rect(4);
 
% prepare
materialFolderName = 'Materials';
pngFileName_Hole = 'Hole.png';
pngPathName_Hole = sprintf('%s/%s', materialFolderName, pngFileName_Hole);
[imgMat_Hole colorMap_Hole alphaData_Hole] = imread(pngPathName_Hole);
 
% get the row number, column number for the imgMat_Hole
width_imgMat_Hole = size(imgMat_Hole,2);
height_imgMat_Hole = size(imgMat_Hole,1);
 
% create a figure
% prepare the width and height for the current fig
width_hFigure = 1024;
height_hFigure = 768;
posX_hFigure = (width_Screen - width_hFigure)/2 + 1;
posY_hFigure = (height_Screen - height_hFigure)/2 + 1;
 
hFigure = figure(1);
set(hFigure, 'position',[posX_hFigure posY_hFigure width_hFigure height_hFigure], 'MenuBar','none'); % .. centerize ..
 
% create an axes for bkground picture, with bkground color
hAxes_BKGround = axes('parent',hFigure);
set(hAxes_BKGround, 'units','pixels', 'position',[1 1 1024 768], 'color',bkgColor, 'xtick',[], 'ytick',[]);
 
% create an axes for the hole
% prepare the posX and posY for hAxes_Hole01
posX_hAxes_Hole01 = (width_hFigure - width_imgMat_Hole)/2 + 1;
posY_hAxes_Hole01 = (height_hFigure - height_imgMat_Hole)/2 + 1;
 
hAxes_Hole01 = axes('parent',hFigure);
set(hAxes_Hole01, 'units','pixels', 'position',[posX_hAxes_Hole01 posY_hAxes_Hole01 width_imgMat_Hole height_imgMat_Hole]);
hImage_Hole01 = imshow(imgMat_Hole,'parent',hAxes_Hole01);
set(hImage_Hole01,'AlphaData',alphaData_Hole);
 
 
% assign y
y = 1;
% end

我们来看看效果:

3d320813dce5a634323e0b69a898c004.png

模块三:准备好锤子(感谢金果果的友情支持♥️)

锤子也有两种状态,一种是普通状态:

3aef9ed27fd4a29c51758cde4549718f.png

还有一种是击打状态:

166c5a6d482084c91476cdedbd6717c3.png

我们来看看,能不能通过窗口移动函数WindowButtonMotionFcn来实现锤子随着鼠标移动的效果?

function y = guiGame_HitHamster(~)

% clear
% clc; clear; close all;

% state zone
mState_Hammer = 0;   % 0 == Off vs. 1 == Hit

% prepare bkground color
bkgColor = [196, 222, 82]/255;

% get the screen size, for the iMac Pro, it is [1 1 2560 1440]
rect = get(0 , 'ScreenSize');
width_Screen = rect(3);
height_Screen = rect(4);

% prepare image Hole + image HammerOff
materialFolderName = 'Materials';
% Hole
pngFileName_Hole = 'Hole.png';
pngPathName_Hole = sprintf('%s/%s', materialFolderName, pngFileName_Hole);
[imgMat_Hole colorMap_Hole alphaData_Hole] = imread(pngPathName_Hole);

% get the row number, column number for the imgMat_Hole
width_imgMat_Hole = size(imgMat_Hole,2);
height_imgMat_Hole = size(imgMat_Hole,1);

% HammerOff
pngFileName_HammerOff = 'HammerOff.png';
pngPathName_HammerOff = sprintf('%s/%s', materialFolderName, pngFileName_HammerOff);
[imgMat_HammerOff colorMap_HammerOff alphaData_HammerOff] = imread(pngPathName_HammerOff);

% get the row number, column number for the imgMat_HammerOff
width_imgMat_HammerOff = size(imgMat_HammerOff,2);
height_imgMat_HammerOff = size(imgMat_HammerOff,1);

% HammerHit
pngFileName_HammerHit = 'HammerHit.png';
pngPathName_HammerHit = sprintf('%s/%s', materialFolderName, pngFileName_HammerHit);
[imgMat_HammerHit colorMap_HammerHit alphaData_HammerHit] = imread(pngPathName_HammerHit);

% get the row number, column number for the imgMat_HammerHit
width_imgMat_HammerHit = size(imgMat_HammerHit,2);
height_imgMat_HammerHit = size(imgMat_HammerHit,1);


% create a figure
% prepare the width and height for the current fig
width_hFigure = 1024;
height_hFigure = 768;
posX_hFigure = (width_Screen - width_hFigure)/2 + 1;
posY_hFigure = (height_Screen - height_hFigure)/2 + 1;

hFigure = figure(1);
set(hFigure, 'position',[posX_hFigure posY_hFigure width_hFigure height_hFigure], 'MenuBar','none');  % .. centerize ..

% create an axes for bkground picture, with bkground color
hAxes_BKGround = axes('parent',hFigure);
set(hAxes_BKGround, 'units','pixels', 'position',[1 1 1024 768], 'color',bkgColor, 'xtick',[], 'ytick',[]);

% create an axes for the hole
% prepare the posX and posY for hAxes_Hole01
posX_hAxes_Hole01 = (width_hFigure - width_imgMat_Hole)/2 + 1;
posY_hAxes_Hole01 = (height_hFigure - height_imgMat_Hole)/2 + 1;

hAxes_Hole01 = axes('parent',hFigure);
set(hAxes_Hole01, 'units','pixels', 'position',[posX_hAxes_Hole01 posY_hAxes_Hole01 width_imgMat_Hole height_imgMat_Hole]);
hImage_Hole01 = imshow(imgMat_Hole,'parent',hAxes_Hole01);
set(hImage_Hole01, 'AlphaData', alphaData_Hole);

% create an axes for HammerOff and HammerHit
posX_hAxes_HammerOff = width_hFigure + 1;
posY_hAxes_HammerOff = height_hFigure + 1;

hAxes_HammerOff = axes('parent',hFigure);

set(hAxes_HammerOff, 'units','pixels', 'position',[posX_hAxes_HammerOff posY_hAxes_HammerOff width_imgMat_HammerOff height_imgMat_HammerOff]);
hImage_HammerOff = imshow(imgMat_HammerOff,'parent',hAxes_HammerOff);
set(hImage_HammerOff, 'AlphaData', alphaData_HammerOff);


% create an axes for HammerOff and HammerHit
posX_hAxes_HammerHit = width_hFigure + 1;
posY_hAxes_HammerHit = height_hFigure + 1;

hAxes_HammerHit = axes('parent',hFigure);

set(hAxes_HammerHit, 'units','pixels', 'position',[posX_hAxes_HammerHit posY_hAxes_HammerHit width_imgMat_HammerHit height_imgMat_HammerHit]);
hImage_HammerHit = imshow(imgMat_HammerHit,'parent',hAxes_HammerHit);
set(hImage_HammerHit, 'AlphaData', alphaData_HammerHit);

% Binding Mechanism
set(hFigure, 'WindowButtonMotionFcn', @hFigure_WindowButtonMotionFcn);
set(hFigure, 'WindowButtonDownFcn',@hFigure_WindowButtonDownFcn);
set(hFigure, 'WindowButtonUpFcn',@hFigure_WindowButtonUpFcn);


% function 1 --> hFigure_WindowButtonMotionFcn
    function hFigure_WindowButtonMotionFcn(hObject, eventData, hs)
        posMouse = get(hAxes_BKGround,'CurrentPoint') ;%获得句柄
        posX_Mouse = round(posMouse(1) * width_hFigure);
        posY_Mouse = round(posMouse(3) * height_hFigure);
        
        % let the hammer follow the mouse
        if ~mState_Hammer
            set(hAxes_HammerHit, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerHit height_imgMat_HammerHit]);
            set(hAxes_HammerOff, 'position',[posX_Mouse-80 posY_Mouse-70 width_imgMat_HammerOff height_imgMat_HammerOff]);
        else
            set(hAxes_HammerOff, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerOff height_imgMat_HammerOff]);
            set(hAxes_HammerHit, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerHit height_imgMat_HammerHit]);
        end
        
        
    end

% function 2 --> hFigure_WindowButtonDownFcn
    function hFigure_WindowButtonDownFcn(hObject, eventData, hs)
        posMouse = get(hAxes_BKGround,'CurrentPoint') ;%获得句柄
        posX_Mouse = round(posMouse(1) * width_hFigure);
        posY_Mouse = round(posMouse(3) * height_hFigure);
        
        
        set(hAxes_HammerOff, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerOff height_imgMat_HammerOff]);
        set(hAxes_HammerHit, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerHit height_imgMat_HammerHit]);
        
        % state_Hammer from 0 to 1
        mState_Hammer = 1;
        
    end


% function 3 --> hFigure_WindowButtonUpFcn
    function hFigure_WindowButtonUpFcn(hObject, eventData, hs)
        posMouse = get(hAxes_BKGround,'CurrentPoint') ;%获得句柄
        posX_Mouse = round(posMouse(1) * width_hFigure);
        posY_Mouse = round(posMouse(3) * height_hFigure);
        
        
        set(hAxes_HammerHit, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerHit height_imgMat_HammerHit]);
        set(hAxes_HammerOff, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerOff height_imgMat_HammerOff]);
        
        % state_Hammer from 1 to 0
        mState_Hammer = 0;
    end





% assign y
y = 1;
end

我们来看一下效果:

f8770ccf4d3e0bf48f34745ee2ecd706.png

这个截图是看不到鼠标的,我们需要借助一行代码把鼠标去掉。

set(gcf, 'Pointer', 'custom', 'PointerShapeCData', NaN(16,16));

整个程序的框架就这样搭建好了,有了这个框架之后,我们就可以做一些基本的扩展:

(a)地鼠的坑,从1个扩展成3个;

(b)地鼠出现的次数,从1次扩展为3次;

(c)地鼠出现的位置也是随机的,会均匀分布在3个位置上。

一个标准的心理学实验编程分为四个步骤:

(1)准备指导语和刺激材料;

(2)刺激矩阵生成;

(3)大框架和每个试次的实验流程;

(4)实验文件和文件夹分发。

·首先,因为我们现在这个是demo,所以一切先从一个简单的指导语“Hit the Hammer to Start the Game”开始;

专门制作了一个坐标轴控件 来放置指导语:

% hAxes_Text Start
hAxes_Text = axes('parent',hFigure);
width_hAxes_Text = 400;
height_hAxes_Text = 60;
posX_hAxes_Text = width_hFigure/2-width_hAxes_Text/2;
posY_hAxes_Text = height_hFigure/2-height_hAxes_Text/2-200;
set(hAxes_Text, 'units','pixels', 'position',[posX_hAxes_Text posY_hAxes_Text width_hAxes_Text height_hAxes_Text]);
set(hAxes_Text, 'color',bkgColor, 'xtick',[], 'ytick',[], 'xcolor',bkgColor, 'ycolor',bkgColor);
axis([1 width_hAxes_Text 1 height_hAxes_Text]);
text(width_hAxes_Text/2,height_hAxes_Text/2,'Hit the Hammer to Start the Game', 'HorizontalAlign','center', 'color','k', 'fontsize',24);

在坐标轴上用text就可以写指导语,这里是通过点击让指导语消失+开启Game的。点击的机制后边我们会介绍,这里有一个技巧,就是点击让指导语消失的方法,我们用的是把坐标轴移到窗口之外,通过下面这句代码:

set(hAxes_Text, 'position',[width_hFigure+1 height_hFigure+1 width_hAxes_Text height_hAxes_Text]);

我们之所以设定trialIndex = 0,就是希望在点击的时候,有一个判断 if trialIndex == 0这段代码就是专门为指导语准备的;等trialIndex = trialIndex + 1之后,就正式进入到trial实验试次阶段;每次还会判断trialIndex的上限, if trialIndex < trialNum,如果是符合的就按照正常流程走,如果不符合,说明程序到头了,请出结束指导语坐标轴。

·其次,刺激矩阵,我们本来是要写一个函数来完成的,现在先虚拟一个只有两列信息的刺激矩阵:

trialID_Array = [1;2;3];
pos_Array = [2;1;3]; % rand virtually
cjMatrix = [trialID_Array pos_Array]; % get cjMatrix virtually

·再次,实验的大框架是:实验指导语 + trial的循环 + 结束语;trial的循环并不是按照传统的for循环,或者while循环来实现trialIndex递进的,这部分需要专门解释一下:

Matlab GUI,本身是事件驱动的,因此每次的点击相当于一个触发事件,我们用的恰恰就是这个事件来实现trialIndex的递增。

一开始

% trialNum
trialIndex = 0;
trialNum = 3;

这里的trialIdnex设定为0代表的是指导语,而trialNum设定trial总数是3个。

在整个程序中是会绑定hFigure和windowbuttondownfcn函数:

% Binding Mechanism
set(hFigure, 'WindowButtonDownFcn',@hFigure_WindowButtonDownFcn);

这样就可以在hFigure_WindowButtonDownFcn函数中实现每次点击鼠标trialIndex = trialIndex + 1;

·没有最后,因为第4步暂时还不需要做 下面把代码晒出来:

function y = guiGame_HitHamster(~)
 
% clear
% clc; clear; close all;
 
% column
trialID_Column = 1;
pos_Column = 2;
 
% trialNum
trialIndex = 0;
trialNum = 3;
 
trialID_Array = [1;2;3];
pos_Array = [2;1;3]; % rand virtually
cjMatrix = [trialID_Array pos_Array]; % get cjMatrix virtually
 
% state zone
mState_Hammer = 0;  % 0 == Off vs. 1 == Hit
 
% prepare bkground color
bkgColor = [196, 222, 82]/255;
 
% get the screen size, for the iMac Pro, it is [1 1 2560 1440]
rect = get(0 , 'ScreenSize');
width_Screen = rect(3);
height_Screen = rect(4);
 
% prepare image Hole + image HammerOff
materialFolderName = 'Materials';
 
% Hole
pngFileName_Hole = 'Hole.png';
pngPathName_Hole = sprintf('%s/%s', materialFolderName, pngFileName_Hole);
[imgMat_Hole colorMap_Hole alphaData_Hole] = imread(pngPathName_Hole);
 
% get the row number, column number for the imgMat_Hole
width_imgMat_Hole = size(imgMat_Hole,2);
height_imgMat_Hole = size(imgMat_Hole,1);
 
 
% HamsterOK
pngFileName_HamsterOK = 'HamsterOK.png';
pngPathName_HamsterOK = sprintf('%s/%s', materialFolderName, pngFileName_HamsterOK);
[imgMat_HamsterOK colorMap_HamsterOK alphaData_HamsterOK] = imread(pngPathName_HamsterOK);
 
% get the row number, column number for the HamsterOK
width_imgMat_HamsterOK = size(imgMat_HamsterOK,2);
height_imgMat_HamsterOK = size(imgMat_HamsterOK,1);
 
 
% HamsterDizzy
pngFileName_HamsterDizzy = 'HamsterDizzy.png';
pngPathName_HamsterDizzy = sprintf('%s/%s', materialFolderName, pngFileName_HamsterDizzy);
[imgMat_HamsterDizzy colorMap_HamsterDizzy alphaData_HamsterDizzy] = imread(pngPathName_HamsterDizzy);
 
% get the row number, column number for the HamsterOK
width_imgMat_HamsterDizzy = size(imgMat_HamsterDizzy,2);
height_imgMat_HamsterDizzy = size(imgMat_HamsterDizzy,1);
 
 
 
% HammerOff
pngFileName_HammerOff = 'HammerOff.png';
pngPathName_HammerOff = sprintf('%s/%s', materialFolderName, pngFileName_HammerOff);
[imgMat_HammerOff colorMap_HammerOff alphaData_HammerOff] = imread(pngPathName_HammerOff);
 
% get the row number, column number for the imgMat_HammerOff
width_imgMat_HammerOff = size(imgMat_HammerOff,2);
height_imgMat_HammerOff = size(imgMat_HammerOff,1);
 
% HammerHit
pngFileName_HammerHit = 'HammerHit.png';
pngPathName_HammerHit = sprintf('%s/%s', materialFolderName, pngFileName_HammerHit);
[imgMat_HammerHit colorMap_HammerHit alphaData_HammerHit] = imread(pngPathName_HammerHit);
 
% get the row number, column number for the imgMat_HammerHit
width_imgMat_HammerHit = size(imgMat_HammerHit,2);
height_imgMat_HammerHit = size(imgMat_HammerHit,1);
 
 
% create a figure
% prepare the width and height for the current fig
width_hFigure = 1024;
height_hFigure = 768;
posX_hFigure = (width_Screen - width_hFigure)/2 + 1;
posY_hFigure = (height_Screen - height_hFigure)/2 + 1;
 
hFigure = figure(1);
set(hFigure, 'position',[posX_hFigure posY_hFigure width_hFigure height_hFigure]);
set(hFigure, 'MenuBar','none', 'numbertitle','off', 'toolbar','none', 'name', 'Psychology Game: Hit Hamster'); %
 
% Hide the pointer cursor
% set(gcf, 'Pointer', 'custom', 'PointerShapeCData', NaN(16,16));
 
% create an axes for bkground picture, with bkground color
hAxes_BKGround = axes('parent',hFigure);
set(hAxes_BKGround, 'units','pixels', 'position',[1 1 1024 768], 'color',bkgColor, 'xtick',[], 'ytick',[]);
 
% hAxes_Text Start
hAxes_Text = axes('parent',hFigure);
width_hAxes_Text = 400;
height_hAxes_Text = 60;
posX_hAxes_Text = width_hFigure/2-width_hAxes_Text/2;
posY_hAxes_Text = height_hFigure/2-height_hAxes_Text/2-200;
set(hAxes_Text, 'units','pixels', 'position',[posX_hAxes_Text posY_hAxes_Text width_hAxes_Text height_hAxes_Text]);
set(hAxes_Text, 'color',bkgColor, 'xtick',[], 'ytick',[], 'xcolor',bkgColor, 'ycolor',bkgColor);
axis([1 width_hAxes_Text 1 height_hAxes_Text]);
text(width_hAxes_Text/2,height_hAxes_Text/2,'Hit the Hammer to Start the Game', 'HorizontalAlign','center', 'color','k', 'fontsize',24);
 
% hAxes_Text Start
hAxes_Text_Bye = axes('parent',hFigure);
width_hAxes_Text_Bye = 400;
height_hAxes_Text_Bye = 60;
% posX_hAxes_Text_Bye = width_hFigure/2-width_hAxes_Text_Bye/2;
posX_hAxes_Text_Bye = width_hFigure + 1;
% posY_hAxes_Text_Bye = height_hFigure/2-height_hAxes_Text_Bye/2-200;
posY_hAxes_Text_Bye = height_hFigure + 1;
set(hAxes_Text_Bye, 'units','pixels', 'position',[posX_hAxes_Text_Bye posY_hAxes_Text_Bye width_hAxes_Text_Bye height_hAxes_Text_Bye]);
set(hAxes_Text_Bye, 'color',bkgColor, 'xtick',[], 'ytick',[], 'xcolor',bkgColor, 'ycolor',bkgColor);
axis([1 width_hAxes_Text_Bye 1 height_hAxes_Text_Bye]);
text(width_hAxes_Text_Bye/2,height_hAxes_Text_Bye/2,'Good Job!', 'HorizontalAlign','center', 'color','k', 'fontsize',24);
 
 
 
 
 
% draw the BKGround Holes first
horizontal_Interval = 50;
vertical_Interval = 50;
 
 
% create an axes for the hole01
% prepare the posX and posY for hAxes_Hole01
posX_hAxes_Hole01 = (width_hFigure - width_imgMat_Hole)/2 + 1 - horizontal_Interval - width_imgMat_Hole;
posY_hAxes_Hole01 = (height_hFigure - height_imgMat_Hole)/2 + 1;
%
hAxes_Hole01 = axes('parent',hFigure);
set(hAxes_Hole01, 'units','pixels', 'position',[posX_hAxes_Hole01 posY_hAxes_Hole01 width_imgMat_Hole height_imgMat_Hole]);
hImage_Hole01 = imshow(imgMat_Hole,'parent',hAxes_Hole01);
set(hImage_Hole01, 'AlphaData', alphaData_Hole);
 
% create an axes for the hole02
% prepare the posX and posY for hAxes_Hole02
posX_hAxes_Hole02 = (width_hFigure - width_imgMat_Hole)/2 + 1;
posY_hAxes_Hole02 = (height_hFigure - height_imgMat_Hole)/2 + 1;
%
hAxes_Hole02 = axes('parent',hFigure);
set(hAxes_Hole02, 'units','pixels', 'position',[posX_hAxes_Hole02 posY_hAxes_Hole02 width_imgMat_Hole height_imgMat_Hole]);
hImage_Hole02 = imshow(imgMat_Hole,'parent',hAxes_Hole02);
set(hImage_Hole02, 'AlphaData', alphaData_Hole);
 
 
% create an axes for the hole03
% prepare the posX and posY for hAxes_Hole03
posX_hAxes_Hole03 = (width_hFigure - width_imgMat_Hole)/2 + 1 + horizontal_Interval + width_imgMat_Hole;
posY_hAxes_Hole03 = (height_hFigure - height_imgMat_Hole)/2 + 1;
%
hAxes_Hole03 = axes('parent',hFigure);
set(hAxes_Hole03, 'units','pixels', 'position',[posX_hAxes_Hole03 posY_hAxes_Hole03 width_imgMat_Hole height_imgMat_Hole]);
hImage_Hole03 = imshow(imgMat_Hole,'parent',hAxes_Hole03);
set(hImage_Hole03, 'AlphaData', alphaData_Hole);
 
 
 
% summarize the posInfos for all these holes
pos_Hole01 = [posX_hAxes_Hole01 posY_hAxes_Hole01 width_imgMat_Hole height_imgMat_Hole];
pos_Hole02 = [posX_hAxes_Hole02 posY_hAxes_Hole02 width_imgMat_Hole height_imgMat_Hole];
pos_Hole03 = [posX_hAxes_Hole03 posY_hAxes_Hole03 width_imgMat_Hole height_imgMat_Hole];
pos_Holes_Cells = {pos_Hole01; pos_Hole02; pos_Hole03};
 
 
 
 
% create an axes for the hamsterOK
posX_hAxes_HamsterOK = posX_hAxes_Hole01;
posY_hAxes_HamsterOK = posY_hAxes_Hole01;
 
hAxes_HamsterOK = axes('parent',hFigure);
set(hAxes_HamsterOK, 'units','pixels', 'position',[posX_hAxes_HamsterOK posY_hAxes_HamsterOK width_imgMat_HamsterOK height_imgMat_HamsterOK]);
hImage_HamsterOK = imshow(imgMat_HamsterOK,'parent',hAxes_HamsterOK);
set(hImage_HamsterOK, 'AlphaData', alphaData_HamsterOK);
 
set(hAxes_HamsterOK, 'position',[width_hFigure+1 height_hFigure+1 width_imgMat_HamsterOK height_imgMat_HamsterOK]);
 
% create an axes for the hamsterDizzy
posX_hAxes_HamsterDizzy = posX_hAxes_Hole01;
posY_hAxes_HamsterDizzy = posY_hAxes_Hole01;
 
hAxes_HamsterDizzy = axes('parent',hFigure);
set(hAxes_HamsterDizzy, 'units','pixels', 'position',[posX_hAxes_HamsterDizzy posY_hAxes_HamsterDizzy width_imgMat_HamsterDizzy height_imgMat_HamsterDizzy]);
hImage_HamsterDizzy = imshow(imgMat_HamsterDizzy,'parent',hAxes_HamsterDizzy);
set(hImage_HamsterDizzy, 'AlphaData', alphaData_HamsterDizzy);
 
set(hAxes_HamsterDizzy, 'position',[width_hFigure+1 height_hFigure+1 width_imgMat_HamsterDizzy height_imgMat_HamsterDizzy]);
 
% create an axes for HammerOff and HammerHit
posX_hAxes_HammerOff = width_hFigure + 1;
posY_hAxes_HammerOff = height_hFigure + 1;
 
hAxes_HammerOff = axes('parent',hFigure);
 
set(hAxes_HammerOff, 'units','pixels', 'position',[posX_hAxes_HammerOff posY_hAxes_HammerOff width_imgMat_HammerOff height_imgMat_HammerOff]);
hImage_HammerOff = imshow(imgMat_HammerOff,'parent',hAxes_HammerOff);
set(hImage_HammerOff, 'AlphaData', alphaData_HammerOff);
 
 
% create an axes for HammerOff and HammerHit
posX_hAxes_HammerHit = width_hFigure + 1;
posY_hAxes_HammerHit = height_hFigure + 1;
 
hAxes_HammerHit = axes('parent',hFigure);
 
set(hAxes_HammerHit, 'units','pixels', 'position',[posX_hAxes_HammerHit posY_hAxes_HammerHit width_imgMat_HammerHit height_imgMat_HammerHit]);
hImage_HammerHit = imshow(imgMat_HammerHit,'parent',hAxes_HammerHit);
set(hImage_HammerHit, 'AlphaData', alphaData_HammerHit);
 
% Binding Mechanism
set(hFigure, 'WindowButtonMotionFcn', @hFigure_WindowButtonMotionFcn);
set(hFigure, 'WindowButtonDownFcn',@hFigure_WindowButtonDownFcn);
set(hFigure, 'WindowButtonUpFcn',@hFigure_WindowButtonUpFcn);
 
 
% function 1 --> hFigure_WindowButtonMotionFcn
 function hFigure_WindowButtonMotionFcn(hObject, eventData, hs)
 posMouse = get(hAxes_BKGround,'CurrentPoint') ;%»ñµÃ¾ä±ú
 posX_Mouse = round(posMouse(1) * width_hFigure);
 posY_Mouse = round(posMouse(3) * height_hFigure);
 
 % let the hammer follow the mouse
 if ~mState_Hammer
 set(hAxes_HammerHit, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerHit height_imgMat_HammerHit]);
 set(hAxes_HammerOff, 'position',[posX_Mouse-80 posY_Mouse-70 width_imgMat_HammerOff height_imgMat_HammerOff]);
 else
 set(hAxes_HammerOff, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerOff height_imgMat_HammerOff]);
 set(hAxes_HammerHit, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerHit height_imgMat_HammerHit]);
 end
 
 
 end
 
% function 2 --> hFigure_WindowButtonDownFcn
 function hFigure_WindowButtonDownFcn(hObject, eventData, hs)
 posMouse = get(hAxes_BKGround,'CurrentPoint') ;%»ñµÃ¾ä±ú
 posX_Mouse = round(posMouse(1) * width_hFigure);
 posY_Mouse = round(posMouse(3) * height_hFigure);
 
 
 set(hAxes_HammerOff, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerOff height_imgMat_HammerOff]);
 set(hAxes_HammerHit, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerHit height_imgMat_HammerHit]);
 
 % state_Hammer from 0 to 1
 mState_Hammer = 1;
 
 %
 if trialIndex == 0
 % let the Start Game instruction disappear
 set(hAxes_Text, 'position',[width_hFigure+1 height_hFigure+1 width_hAxes_Text height_hAxes_Text]);
 pause(0.5);
 
 trialIndex = trialIndex + 1;
 
 % get the pos info. from the cjMatrix
 thisPosID = cjMatrix(trialIndex, pos_Column);
 thisPosInfo = pos_Holes_Cells{thisPosID};
 
 % show the HamsterOK
 set(hAxes_HamsterOK, 'position',thisPosInfo);
 
 else
 
 % get the pos info. from the cjMatrix .. again, not change ..
 thisPosID = cjMatrix(trialIndex, pos_Column);
 thisPosInfo = pos_Holes_Cells{thisPosID};
 
 inField_hAxes_Hole01 = posX_Mouse > posX_hAxes_Hole01 & posX_Mouse < posX_hAxes_Hole01 + width_imgMat_HamsterOK & posY_Mouse > posY_hAxes_Hole01 & posY_Mouse < posY_hAxes_Hole01 + height_imgMat_HamsterOK;
 inField_hAxes_Hole02 = posX_Mouse > posX_hAxes_Hole02 & posX_Mouse < posX_hAxes_Hole02 + width_imgMat_HamsterOK & posY_Mouse > posY_hAxes_Hole02 & posY_Mouse < posY_hAxes_Hole02 + height_imgMat_HamsterOK;
 inField_hAxes_Hole03 = posX_Mouse > posX_hAxes_Hole03 & posX_Mouse < posX_hAxes_Hole03 + width_imgMat_HamsterOK & posY_Mouse > posY_hAxes_Hole03 & posY_Mouse < posY_hAxes_Hole03 + height_imgMat_HamsterOK;
 
 inFields_hAxes_Holes_Cells = {inField_hAxes_Hole01; inField_hAxes_Hole02; inField_hAxes_Hole03};
 this_inField = inFields_hAxes_Holes_Cells{thisPosID};
 
 if this_inField  % hit
 
 set(hAxes_HamsterOK, 'position',[width_hFigure+1 height_hFigure+1 width_imgMat_HamsterOK height_imgMat_HamsterOK]);
 
 set(hAxes_HamsterDizzy, 'position',thisPosInfo);
 
 pause(0.5);
 
 set(hAxes_HamsterDizzy, 'position',[width_hFigure+1 height_hFigure+1 width_imgMat_HamsterOK height_imgMat_HamsterOK]);
 
 
 if trialIndex < trialNum
 % turn to the next trial
 trialIndex = trialIndex + 1;
 
 % get the pos info. from the cjMatrix
 thisPosID = cjMatrix(trialIndex, pos_Column);
 thisPosInfo = pos_Holes_Cells{thisPosID};
 
 % show the HamsterOK
 set(hAxes_HamsterOK, 'position',thisPosInfo);
 else
 
 % show the bye bye
 posX_hAxes_Text_Bye = width_hFigure/2-width_hAxes_Text_Bye/2;
 %  posX_hAxes_Text_Bye = width_hFigure + 1;
 posY_hAxes_Text_Bye = height_hFigure/2-height_hAxes_Text_Bye/2-200;
 %  posY_hAxes_Text_Bye = height_hFigure + 1;
 set(hAxes_Text_Bye, 'units','pixels', 'position',[posX_hAxes_Text_Bye posY_hAxes_Text_Bye width_hAxes_Text_Bye height_hAxes_Text_Bye]);
 
 
 end
 
 
 else % not hit
 
 
 
 
 end
 
 
 
 
 end
 
 end
 
 
% function 3 --> hFigure_WindowButtonUpFcn
 function hFigure_WindowButtonUpFcn(hObject, eventData, hs)
 posMouse = get(hAxes_BKGround,'CurrentPoint') ;%»ñµÃ¾ä±ú
 posX_Mouse = round(posMouse(1) * width_hFigure);
 posY_Mouse = round(posMouse(3) * height_hFigure);
 
 
 set(hAxes_HammerHit, 'position',[width_hFigure + 1 height_hFigure + 1 width_imgMat_HammerHit height_imgMat_HammerHit]);
 set(hAxes_HammerOff, 'position',[posX_Mouse - 80 posY_Mouse - 70 width_imgMat_HammerOff height_imgMat_HammerOff]);
 
 % state_Hammer from 1 to 0
 mState_Hammer = 0;
 end
 
 
 
 
 
% assign y
y = 1;
end
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值