思路:
界面,坐标轴
snake,数组
移动,更新snake坐标
操作:
上、下、左、右,移动
Esc,重新开始
function snake(m, varargin)
% 贪吃蛇,m*n
y = m;
if nargin == 1
x = y;
else
x = varargin{1};
end
if y<4 || x<4
return
end
%% 迷宫框
figure('KeyPressFcn', @keyevent, 'CloseRequestFcn', @closeCallBack);
bgcolor = get(gcf, 'color');
hold on
periodTime = 0.2;
snakeClass = struct;
htimer = timer('StartDelay', periodTime, 'Period', periodTime, ...
'ExecutionMode', 'fixedRate',...
'TimerFcn',@timerCallBack);
iniSnake();
%% 初始化
% 界面初始化
% snake初始化
function iniSnake()
% 清屏
clf
line([0 x x 0 0], [0 0 y y 0])
axis equal
axis off
set(gca, 'xlim', [0 x])
set(gca, 'ylim', [0 y])
for i = 1: (x-1)
line([i i], [0 y], 'Color', [1 1 1])
end
for j = 1: (y-1)
line([0 x], [j j], 'Color', [1 1 1])
end
snakeText = zeros(x, y);
stackArr = zeros(x*y, 2);
for i = 1: x
for j = 1: y
snakeText(i,j) = text(i-0.5, j-0.6, '*',...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'middle',...
'FontSize', 16,...
'Color', bgcolor);
end
end
% 随机
nx = randperm(x-1, 1) + 1;
ny = randperm(y-1, 1) + 1;
set(snakeText(nx,ny), 'Color', [0 1 0])
stackInx = 1;
stackArr(stackInx, :) = [nx, ny];
while (stackInx < 4)
switch randperm(4, 1)
case 1 % 上
if nyisequal(get(snakeText(nx,ny+1),'Color'), bgcolor)
ny = ny + 1;
if stackInx == 1
snakeClass.orientation = 'down';
end
else
continue
end
case 2 % 右
if nxisequal(get(snakeText(nx+1,ny),'Color'), bgcolor)
nx = nx + 1;
if stackInx == 1
snakeClass.orientation = 'left';
end
else
continue
end
case 3 % 下
if ny>1 && isequal(get(snakeText(nx,ny-1),'Color'), bgcolor)
ny = ny - 1;
if stackInx == 1
snakeClass.orientation = 'up';
end
else
continue
end
case 4 % 左
if nx>1 && isequal(get(snakeText(nx-1,ny),'Color'), bgcolor)
nx = nx - 1;
if stackInx == 1
snakeClass.orientation = 'right';
end
else
continue
end
end
set(snakeText(nx,ny), 'Color', [0 0 0])
stackInx = stackInx + 1;
stackArr(stackInx, :) = [nx, ny];
end
snakeClass.stackArr = stackArr;
snakeClass.stackInx = stackInx;
snakeClass.snakeText = snakeText;
randomStar();
% 启动定时器
start(htimer);
end
%% 随机star
function randomStar()
while 1
nx = randperm(x, 1);
ny = randperm(y, 1);
if isequal(get(snakeClass.snakeText(nx,ny),'Color'), bgcolor)
set(snakeClass.snakeText(nx,ny), 'Color', [1 0 0])
break
end
end
end
%% 定时
% 刷新界面,动画
function timerCallBack(~, ~)
nx = snakeClass.stackArr(1,1);
ny = snakeClass.stackArr(1,2);
switch snakeClass.orientation
case 'right'
if nxisequal(get(snakeClass.snakeText(nx+1,ny),'Color'),[0 0 0])
set(snakeClass.snakeText(nx,ny), 'Color', [0 0 0])
nx = nx + 1;
else
stop(htimer);
disp('over')
return
end
case 'up'
if nyisequal(get(snakeClass.snakeText(nx,ny+1),'Color'),[0 0 0])
set(snakeClass.snakeText(nx,ny), 'Color', [0 0 0])
ny = ny + 1;
else
stop(htimer);
disp('over')
return
end
case 'left'
if nx>1 && ~isequal(get(snakeClass.snakeText(nx-1,ny),'Color'),[0 0 0])
set(snakeClass.snakeText(nx,ny), 'Color', [0 0 0])
nx = nx - 1;
else
stop(htimer);
disp('over')
return
end
case 'down'
if ny>1 && ~isequal(get(snakeClass.snakeText(nx,ny-1),'Color'),[0 0 0])
set(snakeClass.snakeText(nx,ny), 'Color', [0 0 0])
ny = ny - 1;
else
stop(htimer);
disp('over')
return
end
end
if isequal(get(snakeClass.snakeText(nx,ny),'Color'), bgcolor)
endArr = snakeClass.stackArr(snakeClass.stackInx, :);
set(snakeClass.snakeText(endArr(1),endArr(2)), 'Color', bgcolor)
newArr = [nx, ny; snakeClass.stackArr(1:snakeClass.stackInx-1,:)];
snakeClass.stackArr(1:snakeClass.stackInx,:) = newArr;
else
newArr = [nx, ny; snakeClass.stackArr(1:snakeClass.stackInx,:)];
snakeClass.stackInx = snakeClass.stackInx + 1;
snakeClass.stackArr(1:snakeClass.stackInx,:) = newArr;
randomStar();
end
set(snakeClass.snakeText(nx,ny), 'Color', [0 1 0])
end
%% 按键
function keyevent(~, event)
switch event.Key
case 'rightarrow'
if ~strcmp(snakeClass.orientation, 'left')
snakeClass.orientation = 'right';
end
case 'uparrow'
if ~strcmp(snakeClass.orientation, 'down')
snakeClass.orientation = 'up';
end
case 'leftarrow'
if ~strcmp(snakeClass.orientation, 'right')
snakeClass.orientation = 'left';
end
case 'downarrow'
if ~strcmp(snakeClass.orientation, 'up')
snakeClass.orientation = 'down';
end
case 'escape'
iniSnake();
return
otherwise
return
end
end
%% Close
function closeCallBack(obj, ~)
stop(htimer)
delete(htimer)
delete(obj)
end
end