MATLAB版贪吃蛇

思路:
界面,坐标轴
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

你可能感兴趣的:(MATLAB)