MATLAB 图形界面编程——实现游戏“走迷宫”

MATLAB图形界面编程——实现游戏“走迷宫”

使用MATLABApp设计工具实现能够进行基本交互功能的图形界面程序,内容为走迷宫游戏。

一、准备工作

我们需要一个App项目并设计一个并不糟糕的布局,通过MATLABApp设计工具能够很快的实现这些。

1、设计视图

使用两栏式App,我们能很方便的将操作部分和显示部分分开。在左边,我们可以放置操作按钮和其他控件,在右边,我们可以通过函数动态创建组件,以实现迷宫的创建。

  • 使用MATLABApp设计工具创建一个“可自动调整布局的两栏式App

  • 设计操作面板

示例布局:

按钮属性设置参考:

旋钮属性设置参考:

开关属性设置参考:

菜单栏属性设置参考:

2、设置走迷宫游戏的游戏范围和背景(非必须,只是有个边框会好看一点,而且容易定位)
  • 可网上找图片
  • 使用MATLAB制作

新建一个脚本文件( .m ),运行以下代码,可得到一个简单的背景图片。

% 定义迷宫尺寸和墙的宽度
mazeWidth  =  400;  % 迷宫宽度
mazeHeight  =  400;  % 迷宫高度
wallWidth  =  10;  % 墙的宽度

% 创建空白图像
mazeImage  =  ones(mazeHeight, mazeWidth);  % 使用白色背景
size(mazeImage)

% 绘制墙
mazeImage(1:wallWidth, :)  =  0;  % 顶部墙
mazeImage(end-wallWidth+1:end, :)  =  0;  % 底部墙
mazeImage(:, 1:wallWidth)  =  0;  % 左侧墙
mazeImage(:, end-wallWidth+1:end)  =  0;  % 右侧墙

% 保存迷宫图像为文件
imwrite(mazeImage, 'maze_image.png');

% 显示迷宫图像
imshow(mazeImage);

得到的图片:

二、实现代码

通过以上的准备工作,我们得到了一个简单的操作面板,和游戏背景,接下来我们需要实现迷宫的生成,玩家的移动等功能。下面就是愉快的敲代码时间了~~

1、添加需要的属性

properties (Access  =  private)       
       % 存放迷宫矩阵
        Maze
        
        % 默认矩阵
        % 6x6迷宫矩阵
        maze6  =  [
            0, 0, 0, 0, 0, 0;
            1, 1, 1, 0, 1, 0;
            0, 0, 0, 0, 1, 1;
            0, 1, 1, 0, 0, 0;
            1, 0, 0, 0, 1, 1;
            0, 0, 1, 0, 0, 0
            ];
        % 12x12迷宫矩阵
        maze12  =  [
            0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0;
            0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0;
            1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0;
            0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0;
            1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1;
            0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0;
            0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0;
            1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0;
            0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0;
            0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0;
            0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1;
            0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0;
            ];
        % 18x18迷宫矩阵
        maze18  =  [
            0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0;
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0;
            1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0;
            0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0;
            1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1;
            0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0;
            0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1;
            0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0;
            0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0;
            0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1;
            0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1;
            1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0;
            1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0;
            1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0;
            0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0;
            1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1;
            0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0;
            1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0;
            ];
        % 36x36 复杂迷宫矩阵
        maze36  =  [
            0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0;
            0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0;
            0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0;
            1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0;
            1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0;
            1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0;
            1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1;
            0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0;
            0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0;
            1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0;
            1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0;
            0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1;
            0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0;
            1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0;
            1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0;
            1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0;
            1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0;
            0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1;
            0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0;
            1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0;
            1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0;
            1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0;
            1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0;
            0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0;
            0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0;
            1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0;
            1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0;
            0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0;
            0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0;
            1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0;
            1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1;
            1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0;
            1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0;
            0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0;
            0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0;
            ];

		%墙壁和玩家均使用按钮表示
        Button	%存放动态添加的按钮
        Img		%存放动态添加的图片

        Player	%玩家
        exit	%出口

        btn_size	%按钮大小

        isLoad = 0;	%是否打开存档,默认为否(0)
        loadData	%存放加载的存档数据,【玩家按钮的位置[x ,y ,宽 ,高],迷宫的大小,是否为随机迷宫】
        
end
2、添加功能函数
  • 初始化游戏

    创建玩家按钮,并设置它的属性。

            function initGame(app)
    
                app.Player = uibutton(app.RightPanel);	%在RightPanel中创建按钮
                app.Player.Text = '玩';	%设置按钮文本
                %判断是否打开存档
                if app.isLoad
                    bsize = app.loadData(3);
                    PosX = app.loadData(1);
                    PosY = app.loadData(2);
                else
                    bsize = app.btn_size;
                    PosX = 20;
                    PosY = 70;
                end
                %设置玩家按钮的位置
                app.Player.Position = [PosX,PosY,bsize,bsize];
    
            end
    
  • 初始化迷宫

    只要获取到旋钮的当前值就能知道用户想要多大的迷宫,由于我们在属性中添加了4个已经准备好的迷宫矩阵,所以我们可以根据旋钮的当前值判断选择那个迷宫矩阵(注意:在游戏范围不变的情况下,迷宫越大,按钮的大小应该变小,防止超出背景边框范围),当然也可以随机生成迷宫矩阵,看你自己。

    	    % 获取默认迷宫
    	    function getMaze(app)
        
                if ~app.isLoad
                    value = str2double(app.Knob.Value);	% 获取旋钮的当前值(将字符串转化为数值)
                               
                    switch value
                    case 6
                        app.Maze = app.maze6;
                        app.btn_size = 60;
                    case 12
                        app.Maze = app.maze12;
                        app.btn_size = 30;
                    case 18
                        app.Maze = app.maze18;
                        app.btn_size = 20;
                    case 36
                        app.Maze = app.maze36;
                        app.btn_size = 10;
                    end
                end
                
            end
            % 创建迷宫
            function initMaze(app)
    
                getMaze(app);
                % 创建游戏背景
                Mazeimg = uiimage(app.RightPanel);	 % 在RightPanel中创建图片组件
                Mazeimg.ImageSource = './maze_image.png';	%设置图片路径
                Mazeimg.Position = [10,60,380,380];	%设置图片位置
                app.Img(end+1) = Mazeimg;
                % 获取迷宫矩阵的尺寸
                [rows, cols] = size(app.Maze);
                bsize = app.btn_size;
                
                % % 检查是否创建随机迷宫 (可缺省)
                % if app.Switch.Value ==  "On" && ~app.isLoad
                %     [rows,cols] = size(app.Maze);
                %     app.Maze = getRendMaze(app,rows,cols);	% 得到迷宫随机矩阵
                % end
                
                % 循环遍历迷宫矩阵并添加按钮(墙壁)
                for i = 1:rows
                    for j = 1:cols
                        if app.Maze(i, j) ==  1
                            % 创建黑色按钮
                            button = uibutton(app.RightPanel);
                            % 根据入口按钮位置设置按钮位置
                            button.Position = [20 + (j - 1)*bsize,70 + (rows - i)*bsize, bsize, bsize]; 
                            button.BackgroundColor = [0, 0, 0]; % 设置按钮背景颜色为黑色
                            app.Button(end + 1) = button;
                            %else
                            %    % 创建白色按钮
                            %    button = uibutton(app.UIFigure);
                            % 	 % 根据入口按钮位置设置按钮位置
                            %    button.Position = [20 + (j-1)*bsize, 70+(rows - i)*bsize, bsize, bsize]; 
                            %    button.BackgroundColor = [1, 1, 1]; % 设置按钮背景颜色为白色
                        end
                    end
                end
                % 确定入口按钮的位置
                entranceButton = uibutton(app.RightPanel);
                entranceButton.Text = '入口';
                entranceButton.Position = [20,70, bsize, bsize]; % 入口按钮的位置
                entranceButton.BackgroundColor = [1, 0, 0]; % 设置入口按钮的背景颜色为红色
    
                app.Button(end+1) = entranceButton;
    
                % 确定出口按钮的位置
                exitButton = uibutton(app.RightPanel);
                exitButton.Text = '出口';
                exitButton.Position = [20 + (cols-1)*bsize,70+ (rows - 1)*bsize,bsize,bsize]; % 出口按钮的位置
                exitButton.BackgroundColor = [0, 1, 0]; % 设置出口按钮的背景颜色为绿色
    
                app.exit = exitButton;
    
            end
    
  • 移动玩家(判断是否撞墙、判断是否胜利)

          function movePlayer(app, dx, dy)
    
                bsize = app.btn_size;
                %得到新位置(newPosX,newPosY)
                Position = app.Player.Position;
                newPosX  =  Position(1) + dx*Position(3);
                newPosY  =  Position(2) + dy*Position(4);
                
                if ~isWin(app,Position(1),Position(2))	%判断是否胜利,是则不可移动
                    if isValidMove(app, newPosX, newPosY) % 检查新位置是否合法,不撞墙
                        app.Player.Position  =  [newPosX, newPosY, bsize, bsize];	%设置新位置,实现移动
                        if isWin(app, newPosX,newPosY)
                            wined(app);
                        end
                    end
                end
            end
    
            function valid  =  isValidMove(app, newPosX, newPosY)
                % 获取迷宫地图和迷宫大小
                maze  =  app.Maze;
                [mazeRows, mazeCols]  =  size(maze);
    
                bsize = app.btn_size;
    
                % 检查新位置是否在迷宫边界内 初始位置(20,70,30,30)
                if newPosX > =  20 && newPosX < =  20 + bsize * (mazeCols - 1) && newPosY > =  70 && newPosY < =  70 + bsize * (mazeRows - 1)
                    % 计算新位置在迷宫矩阵中的行列坐标
                    newRow  =  mazeRows - ((newPosY -70)/ bsize);
                    newCol  =  ((newPosX - 20)/ bsize) + 1;
                    % 检查新位置是否是墙壁
                    if maze(newRow, newCol)  =  =  0
                        valid  =  true; % 移动有效
                    else
                        valid  =  false; % 移动被阻止,撞墙
                    end
                else
                    valid  =  false; % 移动被阻止,超出边界
                end
            end
    
            function valid  =  isWin(app, PosX, PosY)
            	% 获取出口按钮位置
                btn  =  app.exit;
                Position  =  btn.Position;
                % 检查当前位置是否与出口按钮位置一致
                if PosX  =  =  Position(1) && PosY  =  =  Position(2)
                    valid  =  true;
                else
                    valid  =  false;
                end
            end
    
            function wined(app)
            	% 关闭操作按钮
                app.Up.Enable = "off";
                app.Down.Enable = "off";
                app.Left.Enable = "off";
                app.Right.Enable = "off";
               
                winingImg = uiimage(app.RightPanel);	 % 在RightPanel中创建图片组件
                winingImg.ImageSource  =  './wining1.png';	% 设置图片路径
                winingImg.Position  =  [40,140,300,180];	% 设置图片位置
                app.Img(end+1)  =  winingImg;	%存入Img中
    
            end
    
  • 清除组件

            function clearAllComponents(app)
                % 清空RightPanel的子组件
                delete(app.RightPanel.Children);
    
                % 清空app对象中的其他组件
                app.Button  =  [];
                app.Img  =  [];
                app.exit  =  [];
    
                drawnow; % 刷新图形界面
            end
    

3、添加回调函数

在对应组件 “回调”栏中添加对应回调函数

  • 方向按钮的回调函数

            % Button pushed function: Up
            function ButtonUp(app, event)
                movePlayer(app, 0, 1); % 向上移动
            end
    
            % Button pushed function: Right
            function ButtonRight(app, event)
                movePlayer(app, 1, 0); % 向右移动
            end
    
            % Button pushed function: Left
            function ButtonLeft(app, event)
                movePlayer(app, -1, 0); % 向左移动
            end
    
            % Button pushed function: Down
            function ButtonDown(app, event)
                movePlayer(app, 0, -1); % 向下移动
            end
    
  • 开始、结束、重置按钮的回调函数

            % Button pushed function: Start
            function start(app, event)	%开始按钮
    
                clearAllComponents(app);	%清除右边部分的所有组件
    
                initMaze(app);	%初始化迷宫
                initGame(app);	%初始化游戏
    
                app.Up.Enable = "on";
                app.Down.Enable = "on";
                app.Left.Enable = "on";
                app.Right.Enable = "on";
                
                app.Finish.Enable = "on";
                app.Restart.Enable = "on";
                app.Switch.Enable = 'off';
                app.Start.Text  =  '新的开始';
                
            end
    
            % Button pushed function: Finish
            function finish(app, event)	%结束按钮
    
                clearAllComponents(app);
    
                app.isLoad = 0;
    
                app.Start.Text = '开始';
                app.Switch.Value = 'Off';
                app.Knob.Value = '12';
                
                app.Up.Enable = "off";
                app.Down.Enable = "off";
                app.Left.Enable = "off";
                app.Right.Enable = "off";
                
                app.Switch.Enable = 'on';
                app.Start.Enable = 'on';
                app.Restart.Enable = 'off';
                app.Finish.Enable = 'off';
    
            end
            % Callback function: Restart, RightPanel
            function restart(app, event)	%重置按钮
                
                bsize = app.btn_size;
                app.Player.Position = [20,70,bsize,bsize];
    
            end
    
  • 保存、打开菜单项的回调函数

    		% Menu selected function: Menu
            function Save(app, event)
                % 获取用户选择的保存文件路径和名称
                [filename, filepath] = uiputfile('*.mat', '保存数据文件');
                % 如果用户取消操作,uiputfile 会返回 0
                if isequal(filename,0) || isequal(filepath,0)
                    % 用户取消保存操作
                    return;
                end
                % 获取迷宫大小
                if app.isLoad
                    value=app.loadData(5);
                else
                    value = str2double(app.Knob.Value);
                end
                % 选择需要保存的数据
                data = [app.Player.Position,value,(app.Switch.Value=="On")];
                mazeData = app.Maze;
                % 保存数据到用户选择的文件
                save(fullfile(filepath, filename), 'data','mazeData');
                
            end
    
            % Menu selected function: Menu_2
            function Load(app, event)
                % 获取用户选择的数据文件
                [filename, filepath] = uigetfile('*.mat', '选择数据文件');
                % 如果用户取消操作,uigetfile 会返回 0
                if isequal(filename,0) || isequal(filepath,0)
                    % 用户取消选择文件
                    return;
                end
                % 加载数据文件
                load(fullfile(filepath, filename), 'data','mazeData');
                % 此时,data 、mazeData 变量中包含了从文件中加载的数据
                app.loadData=data;
                app.Maze=mazeData;
                app.isLoad=1;
                % 获取开关的当前值
                if data(5)
                    switchValue='On';
                else
                    switchValue='Off';
                end
    
                app.Switch.Value=sprintf("%s",switchValue); % 设置开关的当前值
                app.Knob.Value = sprintf("%d",app.loadData(5));	% 设置旋钮的当前值
                app.btn_size=app.loadData(3);
                app.Start.Text="开始";
                
                start(app);	
    
            end
    

三、运行结果

好了,一个能够实现基本交互功能的App图形界面程序就完成了。

posted @ 2023-11-18 22:37  末雨摸鱼  阅读(620)  评论(0)    收藏  举报