一、简介
基于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
三、运行结果
四、备注
版本:2014a