一、简介

基于matlab GUI贪吃蛇游戏(难度、地图、音乐)

二、源代码

function snake(cmd)
%SNAKE  Graphical User Interface for playing "Nokia Classic Game" Snake.
%
%   The Game:
%   Make the snake grow longer by directing it to the food.
%   Extra bonus points are given from hearts, eat them as fast as possible
%   as amount of bonus points decreases with time.
%   Higher level gives more points for the food but will also make it
%   tougher to steer a long snake as speed increaces.
%   Five different mazes as well as play w/o maze are possible.
%
%   Game Controls:
%   Steer snake using arrow keys. Pause game with 'p' or space.
%
%   Example:
%       snake    % Start Main Snake Interface

%   

global SNAKE MAZE LEVEL BOARD DIRECTION RUNNING FOOD SOUND BONUS PAUSE
if ~nargin
    cmd = 'init';
end
if ~(ischar(cmd)||isscalar(cmd))
    return;
end

switch cmd
    case 'init'
        scrsz = get(0,'ScreenSize');
        % Initialize figure window
        f = figure('Name','Snake',...
            'Numbertitle','off',...
            'Menubar','none',...
            'Color',[.95 .95 .95],...
            'DoubleBuffer','on',...
            'Position',[(scrsz(3)-400)/2 (scrsz(4)-300)/2 400 300],...
            'Colormap',[.58 .71 .65;.4 .4 .4;0 0 0;1 1 0],...
            'CloseRequestFcn',sprintf('%s(''Stop'');closereq;',mfilename),...
            'KeyPressFcn',sprintf('%s(double(get(gcbf,''Currentcharacter'')))',mfilename));
        % Create the Menu
        FileMenu = uimenu(f,'Label','&File');
        uimenu(FileMenu,'Label','New Game','Accelerator','N','Callback',sprintf('%s(''NewGame'')',mfilename));
        uimenu(FileMenu,'Label','Exit','Accelerator','Q','Separator','on','Callback',sprintf('%s(''Stop'');closereq',mfilename));
        LevelMenu = uimenu(f,'Label','&Level');
        uimenu(LevelMenu,'Label','|','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','|||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','||||','Callback',sprintf('%s(''Level'')',mfilename),'checked','on')
        uimenu(LevelMenu,'Label','|||||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','||||||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','|||||||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','||||||||','Callback',sprintf('%s(''Level'')',mfilename))
        uimenu(LevelMenu,'Label','|||||||||','Callback',sprintf('%s(''Level'')',mfilename))
        MazesMenu = uimenu(f,'Label','&Mazes');
        uimenu(MazesMenu,'Label','No maze','Callback',sprintf('%s(''Mazes'')',mfilename),'checked','on')
        uimenu(MazesMenu,'Label','Box','Callback',sprintf('%s(''Mazes'')',mfilename))
        uimenu(MazesMenu,'Label','Tunnel','Callback',sprintf('%s(''Mazes'')',mfilename))
        uimenu(MazesMenu,'Label','Spiral','Callback',sprintf('%s(''Mazes'')',mfilename))
        uimenu(MazesMenu,'Label','Blockade','Callback',sprintf('%s(''Mazes'')',mfilename))
        uimenu(MazesMenu,'Label','Twisted','Callback',sprintf('%s(''Mazes'')',mfilename))
        HelpMenu = uimenu(f,'Label','&Help');
        uimenu(HelpMenu,'Label','Help','Callback',sprintf('helpwin %s',mfilename))
        uimenu(HelpMenu,'Label','Show Score','Callback',sprintf('%s(''ShowScore'')',mfilename),'Separator','on','Checked','on')
        uimenu(HelpMenu,'Label','Play Sounds','Callback',sprintf('%s(''PlaySound'')',mfilename),'Checked','on')
        uimenu(HelpMenu,'Label','About','Callback',sprintf('%s(''About'')',mfilename),'Separator','on');
        % Create The axes
        axes('Units','normalized',...
            'Position', [0 0 1 1],...
            'Visible','off',...
            'DrawMode','fast',...
            'NextPlot','replace');
        % Add the board
        BOARD = image(getTitle,'CDataMapping','scaled');
        axis image
        set(gca,...
            'XTick',NaN,...
            'YTick',NaN)
        text(40,30,'0',...
            'FontUnits','normalized', ...
            'FontSize',0.03, ...
            'FontName','FixedWidth',...
            'FontWeight','bold',...
            'Color',[1 1 1],...
            'VerticalAlignment','baseline', ...
            'HorizontalAlignment','right',...
            'Tag','Score');
        SNAKE = [14,20;14,19;14,18;14,17;14,16];
        MAZE = zeros(30,40);
        LEVEL = 4;
        SOUND = true;
    case 28 % left
        if SNAKE(2,2)~=mod(SNAKE(1,2)-2,40)+1
            DIRECTION = cmd;
        end
    case 29 % right
        if SNAKE(2,2)~=mod(SNAKE(1,2),40)+1
            DIRECTION = cmd;
        end
    case 30 % up
        if SNAKE(2,1)~=mod(SNAKE(1,1)-2,30)+1
            DIRECTION = cmd;
        end
    case 31 % down
        if SNAKE(2,1)~=mod(SNAKE(1,1),30)+1
            DIRECTION = cmd;
        end
    case 'Level' % Change of Level
        set(get(get(gcbo,'Parent'),'Children'),'checked','off')
        set(gcbo,'checked','on')
        LEVEL = length(get(gcbo,'Label'));
    case 'Mazes' % Change of Maze
        set(get(get(gcbo,'Parent'),'Children'),'checked','off')
        set(gcbo,'checked','on')
        MAZE = zeros(30,40);
        switch get(gcbo,'Label')
            case 'No maze'
            case 'Box'
                MAZE([1 30],:) = 1;
                MAZE(:,[1 40]) = 1;
            case 'Tunnel'
                MAZE([1:4 26:30],[1 40]) = 1;
                MAZE([1 30],[1:4 36:40]) = 1;
                MAZE([10 20],15:25) = 1;
            case 'Spiral'
                MAZE(1:15,15) = 1;
                MAZE(15:30,25) = 1;
                MAZE(25,1:15) = 1;
                MAZE(5,25:40) = 1;
            case 'Blockade'
                MAZE([1:10 end-10:end],[1 end]) = 1;
                MAZE([1 end],:) = 1;
                MAZE([8 22],15:25) = 1;
                MAZE(5:10,[10 30]) = 1;
                MAZE(20:25,[10 30]) = 1;
            case 'Twisted'
                MAZE([1 2 3 9 16 31 39 46 61 69 76 91 99 106 121 129    ...
                    136 159 166 189 196 219 226 249 256 279 286 301 309 ...
                    316 331 339 346 361 369 376 391 399 406 421 429 436 ...
                    451 459 466 481 489 496 511 512 513 514 515 516 517 ...
                    518 519 526 541 556 571 586 601 616 631 646 661 676 ...
                    677 678 679 680 681 682 683 684 685 686 687 688 689 ...
                    690 691 699 706 721 729 736 751 759 766 781 789 796 ...
                    811 819 826 841 849 856 871 879 886 901 909 916 931 ...
                    939 946 969 976 999 1006 1029 1036 1059 1066 1089 ...
                    1096 1119 1126 1149 1156 1179 1186]) = 1;
        end
        feval(mfilename,'Stop')
    case 'ShowScore' % Change of Show Score
        switch get(gcbo,'checked')
            case 'on'
                set(gcbo,'checked','off')
                set(findobj(gcbf,'Tag','Score'),'Visible','off')
            case 'off'
                set(gcbo,'checked','on')
                set(findobj(gcbf,'Tag','Score'),'Visible','on')
        end
    case 'PlaySound' % Change of Play Sounds
        switch get(gcbo,'checked')
            case 'on'
                set(gcbo,'checked','off')
                SOUND = false;
            case 'off'
                set(gcbo,'checked','on')
                SOUND = true;
        end
    case 'NewGame' % New Game N or Ctrl-N
        set(findobj(gcbf,'Tag','Score'),'String','0')
        SNAKE = [14,20;14,19;14,18;14,17;14,16];
        DIRECTION = 29; % right
        BONUS = 0;
        PAUSE = false;
        feval(mfilename,'Food')
        feval(mfilename,'Start')
    case 'Start' % Start Game
        RUNNING = true;
        bonusCounter = 0;
        foodCounter = 0;
        while(RUNNING)
            if ~PAUSE
                SNAKE = circshift(SNAKE,1);
               
                switch DIRECTION
                    case 28 % left
                        SNAKE(1,2) = mod(SNAKE(1,2)-2,40)+1;
                    case 29 % right
                        SNAKE(1,2) = mod(SNAKE(1,2),40)+1;
                    case 30 % up
                        SNAKE(1,1) = mod(SNAKE(1,1)-2,30)+1;
                    case 31 % down
                        SNAKE(1,1) = mod(SNAKE(1,1),30)+1;
                end
                % Check if snake hits any barrier
                if MAZE(SNAKE(1,1),SNAKE(1,2)) || ...
                        sum(ismember(SNAKE(2:end,1),SNAKE(1,1))+...
                        ismember(SNAKE(2:end,2),SNAKE(1,2))==2)
                    %If play sound
                    if SOUND
                        soundsc(sin(1:100),1000)
                    end
                    pause(.3)
                    delete(findobj(gcbf,'Tag','Bonus'))
                    feval(mfilename,'Stop')
                    set(BOARD,'CData',getGameOver)
                else
                    % Check if snake eats bonus
                    if isequal(SNAKE(1,:),BONUS)
                        % Update score
                        scorehandle = findobj(gcbf,'Tag','Score');
                        set(scorehandle,'String',...
                            num2str(LEVEL*ceil(bonusCounter/3)+...
                            str2double(get(scorehandle,'String'))))
                        %If play sound
                        if SOUND
                            soundsc(sin(1:100),5000)
                        end
                        bonusCounter = 1;
                    end
                    if BONUS
                        bonusCounter = bonusCounter-1;
                        if bonusCounter<=0
                            delete(findobj(gcbf,'Tag','Bonus'))
                           
                        end
                    end
                    % Check if snake eats food
                    if isequal(SNAKE(1,:),FOOD)
                        % Snake Grows!
                        SNAKE(end+1,:) = SNAKE(end,:);
                        % Update score
                        scorehandle = findobj(gcbf,'Tag','Score');
                        set(scorehandle,'String',...
                            num2str(LEVEL+str2double(get(scorehandle,'String'))))
                        %If play sound
                        if SOUND
                            soundsc(sin(1:100),10000)
                        end
                        % Spawn new food
                        feval(mfilename,'Food')
                        if ~BONUS % only update if no bonus exist
                            bonusCounter = bonusCounter+15;
                            foodCounter = foodCounter+1;
                        end

三、运行结果

【游戏】基于matlab GUI贪吃蛇游戏(难度、地图、音乐)【含Matlab源码 1160期】_matlab
【游戏】基于matlab GUI贪吃蛇游戏(难度、地图、音乐)【含Matlab源码 1160期】_贪吃蛇_02

四、备注

版本:2014a