image thumbnail

VirusShooter

by

 

VirusShooter allows user to play a simple webcam-based shooting game.

VirusShooter
function VirusShooter

%--------------------------------------------------------------------------
%VirusShooter
%Version 1.00
%Created by Stepen
%Created 10 June 2012
%Last modified 31 July 2012
%--------------------------------------------------------------------------
%VirusShooter starts a GUI for a webcam-based shooting game
%--------------------------------------------------------------------------
%How to play VirusShooter:
%Player uses his/her webcam and move it around to find a virus and then
%shoot it by pressing spacebar when the virus is within the crosshair.
%--------------------------------------------------------------------------
%Caution!
%Please make sure that a webcam or a supported image acquisition device is
%connected to your computer before starting the game.
%--------------------------------------------------------------------------

%CodeStart-----------------------------------------------------------------
%Reseting MATLAB environment
    close all
    clear all
    imaqreset
%Declaring global variable
    global adaptorID devideID IMAQformat
    global playstat VidRes newImage
    global x y Vx Vy ax ay
    score=0;
    n_virus=50;
    virus_image=imread('VirusShooter_Virus.png');
    virus_size=size(virus_image);
    xhair_image=imread('VirusShooter_Xhair.png');
    xhair_size=size(xhair_image);
    trackpixel=32;
    dt=0.1;
    fieldratio=2;
%Finding IMAQ hardware information
    imaqreset
    HWinfo=imaqhwinfo;
    IMAQadaptorlist=HWinfo.InstalledAdaptors;
    n_adaptor=numel(IMAQadaptorlist);
    IMAQdevicelist=cell(1,n_adaptor);
    IMAQformatlist=cell(1,n_adaptor);
    for count=1:n_adaptor
        IMAQdata=imaqhwinfo(IMAQadaptorlist{count});
        IMAQdevicelist{count}=IMAQdata.DeviceIDs;
        if numel(IMAQdevicelist{count})==0
            IMAQformatlist{count}={};
        else
            IMAQformatlist{count}=IMAQdata.DeviceInfo(1).SupportedFormats;
        end
    end
%Generating startup window
    begin=0;
    ScreenSize=get(0,'ScreenSize');
    startupwindow=figure('Name','Virus Shooter Start Up',...
                         'WindowStyle','modal',...
                         'NumberTitle','Off',...
                         'Menubar','none',...
                         'Resize','off',...
                         'Units','pixels',...
                         'Position',[0.5*(ScreenSize(3)-300),...
                                     0.5*(ScreenSize(4)-100),...
                                     300,100],...
                         'DeleteFcn',@quitvirusscannerfcn);
    uicontrol('Parent',startupwindow,...
              'Style','text',...
              'String','IMAQ Device Adaptor',...
              'HorizontalAlignment','left',...
              'BackgroundColor',[0.8,0.8,0.8],...
              'Units','normalized',...
              'Position',[0.05,0.765,0.55,0.15])
    IMAQadaptorpopup=uicontrol('Parent',startupwindow,...
                               'Style','popup',...
                               'String',HWinfo.InstalledAdaptors,...
                               'Value',1,...
                               'Units','normalized',...
                               'Position',[0.7,0.85,0.25,0.1],...
                               'Callback',@updatestartupwindowfcn);
    uicontrol('Parent',startupwindow,...
              'Style','text',...
              'String','IMAQ Device ID',...
              'HorizontalAlignment','left',...
              'BackgroundColor',[0.8,0.8,0.8],...
              'Units','normalized',...
              'Position',[0.05,0.54,0.55,0.15])
    IMAQdevicepopup=uicontrol('Parent',startupwindow,...
                              'Style','popup',...
                              'Value',1,...
                              'Units','normalized',...
                              'Position',[0.7,0.625,0.25,0.1]);
    uicontrol('Parent',startupwindow,...
              'Style','text',...
              'String','Adaptor Acquisition Format',...
              'HorizontalAlignment','left',...
              'BackgroundColor',[0.8,0.8,0.8],...
              'Units','normalized',...
              'Position',[0.05,0.315,0.55,0.15])
    IMAQformatpopup=uicontrol('Parent',startupwindow,...
                              'Style','popup',...
                              'Value',1,...
                              'Units','normalized',...
                              'Position',[0.7,0.4,0.25,0.1]);
    uicontrol('Parent',startupwindow,...
              'Style','pushbutton',...
              'String','Run Game',...
              'Units','normalized',...
              'Position',[0.2,0.05,0.25,0.2],...
              'Callback',@startvirusscannerfcn);
    uicontrol('Parent',startupwindow,...
              'Style','pushbutton',...
              'String','Quit',...
              'Units','normalized',...
              'Position',[0.55,0.05,0.25,0.2],...
              'Callback',@quitvirusscannerfcn);
%Initiating start up window
    updatestartupwindowfcn
%Holding user interface generation
    keep=true;
    begin=false;
    while keep
        pause(0.1)
    end
    if ~begin
        return
    end
%Generating GUI
    ScreenSize=get(0,'ScreenSize');
    mainwindow=figure('Name','Virus Shooter',...
                      'NumberTitle','Off',...
                      'Menubar','none',...
                      'Resize','off',...
                      'Units','pixels',...
                      'Position',[0.5*(ScreenSize(3)-384),...
                                  0.5*(ScreenSize(4)-400),...
                                  384,400],...
                      'WindowKeyPressFcn',@keypressfcn,...
                      'DeleteFcn',@closegamefcn);
    mainaxes=axes('Parent',mainwindow,...
                  'Units','normalized',...
                  'Position',[0.1,0.25,0.8,0.7]);
    imshow(uint8(zeros(100)),'Parent',mainaxes)
    lscoretext=uicontrol('Parent',mainwindow,...
                         'Style','text',...
                         'String','0',...
                         'FontSize',15,...
                         'HorizontalAlignment','center',...
                         'BackgroundColor',[0.8,0.8,0.8],...
                         'Units','pixels',...
                         'Position',[10,220,25,25]);
    rscoretext=uicontrol('Parent',mainwindow,...
                         'Style','text',...
                         'String','0',...
                         'FontSize',15,...
                         'HorizontalAlignment','center',...
                         'BackgroundColor',[0.8,0.8,0.8],...
                         'Units','pixels',...
                         'Position',[349,220,25,25]);
    startgamebutton=uicontrol('Parent',mainwindow,...
                              'Style','pushbutton',...
                              'String','Start Game',...
                              'Enable','on',...
                              'Visible','on',...
                              'Units','normalized',...
                              'Position',[0.15,0.15,0.2,0.05],...
                              'Callback',@startgamefcn);
    stopgamebutton=uicontrol('Parent',mainwindow,...
                             'Style','pushbutton',...
                             'String','Stop Game',...
                             'Enable','off',...
                             'Visible','off',...
                             'Units','normalized',...
                             'Position',[0.15,0.15,0.2,0.05],...
                             'Callback',@stopgamefcn);
    uicontrol('Parent',mainwindow,...
              'Style','pushbutton',...
              'String','Close Game',...
              'Units','normalized',...
              'Position',[0.65,0.15,0.2,0.05],...
              'Callback',@closegamefcn);
    instructionbox=uicontrol('Parent',mainwindow,...
                             'Style','text',...
                             'String',['Click Start Game button to',...
                                       ' begin the game...'],...
                             'Units','normalized',...
                             'Position',[0.1,0.05,0.8,0.04]);
%Declaring CallbackFunction
    %Start of startvirusscannerfcn 
    function startvirusscannerfcn(~,~)
        begin=true;
        adaptorID=get(IMAQadaptorpopup,'Value');
        devideID=get(IMAQdevicepopup,'Value');
        IMAQformat=get(IMAQformatpopup,'Value');
        delete(startupwindow)
    end
    %End of startvirusscannerfcn
    %Start of quitvirusscannerfcn 
    function quitvirusscannerfcn(~,~)
        keep=false;
        delete(startupwindow)
    end
    %End of quitvirusscannerfcn
    %Start of updatestartupwindowfcn
    function updatestartupwindowfcn(~,~)
        tempadaptorID=get(IMAQadaptorpopup,'Value');
        if numel(IMAQdevicelist{tempadaptorID})==0
            set(IMAQdevicepopup,'Enable','off');
            set(IMAQdevicepopup,'String','N/A');
            set(IMAQdevicepopup,'Value',1);
            set(IMAQformatpopup,'Enable','off');
            set(IMAQformatpopup,'String','N/A');
            set(IMAQformatpopup,'Value',1);
        else
            set(IMAQdevicepopup,'Enable','on');
            set(IMAQdevicepopup,'String',IMAQdevicelist{tempadaptorID});
            set(IMAQdevicepopup,'Value',1);
            set(IMAQformatpopup,'Enable','on');
            set(IMAQformatpopup,'String',IMAQformatlist{tempadaptorID});
            set(IMAQformatpopup,'Value',1);
        end
    end
    %End of updatestartupwindowfcn
    %Start of stargamefcn
    function startgamefcn(~,~)
        %Disabling startgamebutton and enabling stopgamebutton
        set(startgamebutton,'Enable','off')
        set(startgamebutton,'Visible','off')
        set(stopgamebutton,'Enable','on')
        set(stopgamebutton,'Visible','on')
        %Reseting IMAQ
        imaqreset
        %Creating new IMAQ object
        IMAQobj=videoinput(IMAQadaptorlist{adaptorID},...
                           IMAQdevicelist{adaptorID}{devideID},...
                           IMAQformatlist{adaptorID}{IMAQformat});
        %Setting up IMAQ parameter
        triggerconfig(IMAQobj,'manual');
        set(IMAQobj,'ReturnedColorSpace','rgb')
        set(IMAQobj,'TriggerRepeat',Inf)
        set(IMAQobj,'FramesPerTrigger',1)
        set(IMAQobj,'FrameGrabInterval',1)
        VidRes=get(IMAQobj,'VideoResolution');
        %Resetting score
        score=0;
        set(lscoretext,'String',score)
        set(rscoretext,'String',score)
        %Creating newvirus
        [x,y,Vx,Vy,ax,ay]=createnewvirus(n_virus);
        %Displaying instruction
        set(instructionbox,'String',['Move your camera and use space',...
                                     ' bar to shoot the virus!'])
        %Starting IMAQ
        start(IMAQobj)
        %Getting the first image for pool initialization
        trigger(IMAQobj)
        oldImage=getdata(IMAQobj,1,'uint8');
        %Displaying game
        playstat=true;
        timer=1;
        while playstat
            %Trigerring IMAQ object
            trigger(IMAQobj)
            %Acquiring new image and calculating virus movement
            newImage=getdata(IMAQobj,1,'uint8');
            try
                [dx,dy]=findcammove(oldImage,newImage);
            catch
                dx=0;
                dy=0;
            end
            [x,y,Vx,Vy,ax,ay]=movevirus(x,y,Vx,Vy,ax,ay,dx,dy);
            %Finding closest virus to crosshair
            S=(x.^2)+(y.^2);
            virusID=find(S==min(S(:)));
            %Clearing image
            cla(mainaxes)
            hold(mainaxes,'on')
            %Displaying image
            displayimage=putvirus(newImage,x,y);
            imshow(displayimage,'Parent',mainaxes)
            %Drawing guidance arrow
            length=norm([x(virusID),y(virusID)]);
            x_dir=x(virusID)/length;
            y_dir=y(virusID)/length;
            quiver(0.5*VidRes(1),0.5*VidRes(2),...
                   0.2*VidRes(2)*x_dir,0.2*VidRes(2)*y_dir,'r',...
                   'Parent',mainaxes)
            %Adjusting image axis
            axis(mainaxes,[0,VidRes(1),0,VidRes(2)])
            %Refreshing loop
            oldImage=newImage;
            timer=timer+1;
            %Delaying loop
            pause(dt)
        end
        delete(IMAQobj)
        clear('IMAQobj')
    end
    %End of startgamefcn
    %Start of stopgamefcn
    function stopgamefcn(~,~)
        %Stopping game
        playstat=false;
        %Displaying black screen
        cla(mainaxes)
        imshow(uint8(zeros(VidRes(2),VidRes(1))),'Parent',mainaxes)
        %Re-enabling stargamebutton and disabling stopgamebutton
        set(startgamebutton,'Enable','on')
        set(startgamebutton,'Visible','on')
        set(stopgamebutton,'Enable','off')
        set(stopgamebutton,'Visible','off')
    end
    %End of stopgamefcn
    %Start of keypressfcn
    function keypressfcn(~,event)
        switch event.Key
            case 'space'
                %Flashing image
                imshow(newImage+uint8(128*ones(size(newImage))),...
                       'Parent',mainaxes)
                %Calculating virus distance to crosshair
                virusID=find((abs(x)<virus_size(2))&...
                             (abs(y)<virus_size(1)));
                %Updating player score
                score=score+numel(virusID);
                set(lscoretext,'String',score)
                set(rscoretext,'String',score)
                %Displaying instruction
                if numel(virusID)==0
                    set(instructionbox,...
                        'String','No virus was shot, aim carefully!')
                else
                    set(instructionbox,...
                        'String',[num2str(numel(virusID)),' virus has',...
                                  ' been eliminated! Keep going!'])
                end
                %Eliminating virus inside crosshair range and respawning
                [x,y,Vx,Vy,ax,ay]=respawnvirus(x,y,Vx,Vy,ax,ay,virusID);
        end
    end
    %End of keypressfcn
    %Start of closegamefcn
    function closegamefcn(~,~)
        %Stopping current game
        if playstat
            playstat=false;
            pause(1)
            imaqreset
        end
        %Clearing IMAQobject
        delete(mainwindow)
    end
    %End of closegamefcn
%Declaring LocalFunction
    %Start of createvirus
    function [x,y,Vx,Vy,ax,ay]=createnewvirus(n_virus)
        x=zeros(n_virus,1);
        y=zeros(n_virus,1);
        Vx=zeros(n_virus,1);
        Vy=zeros(n_virus,1);
        ax=zeros(n_virus,1);
        ay=zeros(n_virus,1);
        for virusID=1:n_virus
            x(virusID)=(2*fieldratio*VidRes(1)*rand)-...
                       (fieldratio*VidRes(1));
            y(virusID)=(2*fieldratio*VidRes(2)*rand)-...
                       (fieldratio*VidRes(2));
            Vx(virusID)=(0.2*fieldratio*VidRes(1)*rand)-...
                        (0.1*fieldratio*VidRes(1));
            Vy(virusID)=(0.2*fieldratio*VidRes(2)*rand)-...
                        (0.1*fieldratio*VidRes(2));
            ax(virusID)=0;
            ay(virusID)=0;
        end
    end
    %End of createvirus
    %Start of respawnvirus
    function [x,y,Vx,Vy,ax,ay]=respawnvirus(x,y,Vx,Vy,ax,ay,virusID)
        for spawnID=1:numel(virusID)
            decision1=rand;
            decision2=rand;
            x(virusID(spawnID))=((decision1<0.5)*...
                                 (fieldratio*VidRes(1)*(rand+1)))-...
                                ((~(decision1<0.5))*...
                                 (fieldratio*VidRes(1)*(rand+1)));
            y(virusID(spawnID))=((decision2<0.5)*...
                                 (fieldratio*VidRes(2)*(rand+1)))-...
                                ((~(decision2<0.5))*...
                                 (fieldratio*VidRes(2)*(rand+1)));
            Vx(virusID(spawnID))=(0.2*fieldratio*VidRes(1)*rand)-...
                                 (0.1*fieldratio*VidRes(1));
            Vy(virusID(spawnID))=(0.2*fieldratio*VidRes(2)*rand)-...
                                 (0.1*fieldratio*VidRes(2));
            ax(virusID(spawnID))=0;
            ay(virusID(spawnID))=0;
        end
    end
    %End of respawnvirus
    %Start of movevirus
    function [x,y,Vx,Vy,ax,ay]=movevirus(x,y,Vx,Vy,ax,ay,dx_cam,dy_cam)
        for virusID=1:n_virus
            %%Creating chance that virus will change its movement
            %decision=rand;
            %if decision<0.01
            %    virus_ax(virusID)=rand;
            %    virus_ay(virusID)=rand;
            %end
            %Integrating movement speed
            Vx(virusID)=Vx(virusID)+(ax(virusID)*dt);
            Vy(virusID)=Vy(virusID)+(ay(virusID)*dt);
            %Integrating position
            x(virusID)=x(virusID)+(Vx(virusID)*dt);
            y(virusID)=y(virusID)+(Vy(virusID)*dt);
            %Adjusting position based on camera movement
            x(virusID)=x(virusID)+dx_cam;
            y(virusID)=y(virusID)+dy_cam;
            %Recircling position
            x(x>fieldratio*VidRes(1))=x(x>fieldratio*VidRes(1))-...
                                      (2*fieldratio*VidRes(1));
            x(x<-fieldratio*VidRes(1))=x(x<-fieldratio*VidRes(1))+...
                                       (4*fieldratio*VidRes(1));
            y(y>fieldratio*VidRes(1))=y(y>2*VidRes(1))-...
                                      (4*fieldratio*VidRes(2));
            y(y<-fieldratio*VidRes(1))=y(y<-fieldratio*VidRes(1))+...
                                       (4*fieldratio*VidRes(2));
        end
    end
    %End of movevirus
    %Start of putvirus
    function displayimage=putvirus(BGimage,x,y)
        %Padding image
        paddedimage=uint8(zeros(size(BGimage)+...
                                [2*virus_size(1),2*virus_size(1),0]));
        paddedimage(:,:,1)=padarray(BGimage(:,:,1),...
                                    [virus_size(1),virus_size(1)],'both');
        paddedimage(:,:,2)=padarray(BGimage(:,:,2),...
                                    [virus_size(1),virus_size(1)],'both');
        paddedimage(:,:,3)=padarray(BGimage(:,:,3),...
                                    [virus_size(1),virus_size(1)],'both');
        %Adding virus to image
        for virusID=1:n_virus
            if (x(virusID)<-0.5*(VidRes(1)+virus_size(2)))||...
               (x(virusID)>0.5*(VidRes(1)+virus_size(2)))||...
               (y(virusID)<-0.5*(VidRes(2)+virus_size(1)))||...
               (y(virusID)>0.5*(VidRes(2)+virus_size(1)))
                
            else
                paddedimage((0.5*VidRes(2))+round(y(virusID))-...
                            (0.5*virus_size(1))+1+virus_size(1):...
                            (0.5*VidRes(2))+round(y(virusID))+...
                            (0.5*virus_size(1)+virus_size(1)),...
                            (0.5*VidRes(1))+round(x(virusID))-...
                            (0.5*virus_size(2))+1+virus_size(2):...
                            (0.5*VidRes(1))+round(x(virusID))+...
                            (0.5*virus_size(2))+virus_size(2),:)=...
                        paddedimage((0.5*VidRes(2))+round(y(virusID))-...
                                    (0.5*virus_size(1))+1+virus_size(1):...
                                    (0.5*VidRes(2))+round(y(virusID))+...
                                    (0.5*virus_size(1))+virus_size(1),...
                                    (0.5*VidRes(1))+round(x(virusID))-...
                                    (0.5*virus_size(2))+1+virus_size(2):...
                                    (0.5*VidRes(1))+round(x(virusID))+...
                                    (0.5*virus_size(2))+virus_size(1),...
                                    :)+...
                        (10*virus_image(:,:,:));
            end
        end
        %Drawing crosshair
        paddedimage((0.5*VidRes(2))-(0.5*xhair_size(1))+1+virus_size(1):...
                    (0.5*VidRes(2))+(0.5*xhair_size(1))+virus_size(1),...
                    (0.5*VidRes(1))-(0.5*xhair_size(2))+1+virus_size(2):...
                    (0.5*VidRes(1))+(0.5*xhair_size(2))+virus_size(2),...
                    :)=...
                    paddedimage((0.5*VidRes(2))-(0.5*xhair_size(1))+1+...
                                virus_size(1):...
                                (0.5*VidRes(2))+(0.5*xhair_size(1))+...
                                virus_size(1),...
                                (0.5*VidRes(1))-(0.5*xhair_size(2))+1+...
                                virus_size(1):...
                                (0.5*VidRes(1))+(0.5*xhair_size(2))+...
                                virus_size(1),:)+...
                    xhair_image(:,:,:);
        %Cutting image
        displayimage=paddedimage(virus_size(1)+1:...
                                 virus_size(1)+VidRes(2),...
                                 virus_size(2)+1:...
                                 virus_size(2)+VidRes(1),:);
    end
    %End of putvirus
    %Start of findcammove
    function [u,v]=findcammove(image1,image2)
        %Converting image to grayscale
        image1=rgb2gray(image1);
        image2=rgb2gray(image2);
        %Sampling image1 for template
        template=cell(4,1);
        template{1}=image1((0.5*trackpixel)+1:...
                           (0.5*trackpixel)+1+trackpixel,...
                           (0.5*trackpixel)+1:...
                           (0.5*trackpixel)+1+trackpixel);
        template{2}=image1(VidRes(2)-(0.5*trackpixel)+1-trackpixel:...
                           VidRes(2)-(0.5*trackpixel),...
                           (0.5*trackpixel)+1:...
                           (0.5*trackpixel)+1+trackpixel);
        template{3}=image1((0.5*trackpixel)+1:...
                           (0.5*trackpixel)+1+trackpixel,...
                           VidRes(1)-(0.5*trackpixel)+1-trackpixel:...
                           VidRes(1)-(0.5*trackpixel));
        template{4}=image1(VidRes(2)-(0.5*trackpixel)+1-trackpixel:...
                           VidRes(2)-(0.5*trackpixel)+1,...
                           VidRes(1)-(0.5*trackpixel)+1-trackpixel:...
                           VidRes(1)-(0.5*trackpixel)+1);
        %Sampling image2 for search area
        search{1}=image2(1:2*trackpixel,...
                         1:2*trackpixel);
        search{2}=image2(VidRes(2)-(2*trackpixel)+1:....
                         VidRes(2),...
                         1:2*trackpixel);
        search{3}=image2(1:2*trackpixel,...
                         VidRes(1)-(2*trackpixel)+1:....
                         VidRes(1));
        search{4}=image2(VidRes(2)-(2*trackpixel)+1:....
                         VidRes(2),...
                         VidRes(1)-(2*trackpixel)+1:....
                         VidRes(1));
        %Performing cross-correlation
        u=zeros(4,1);
        v=zeros(4,1);
        for imID=1:4
            cmap=normxcorr2(template{imID},search{imID});
            [r,c]=find(cmap==max(cmap(:)));
            u(imID)=c(1)-(1.5*trackpixel);
            v(imID)=-r(1)+(1.5*trackpixel);
        end
        %Averaging camera speed
        %u=round(mean2(u))-1;
        %v=round(mean2(v))+1;
        u=u(abs(u)==min(abs(u)));
        v=-v(abs(v)==min(abs(v)));
        if numel(u)<1
            u=0;
        elseif numel(u)>1
            u=u(1);
        end
        if numel(v)<1
            v=0;
        elseif numel(v)>1
            v=v(1);
        end
    end
    %End of findcammove
%CodeEnd-------------------------------------------------------------------

end

Contact us