用App designer制作数字华容道

用App designer制作数字华容道

做完2048后突然想到华容道,但是华容道比较难做,就先做个数字华容道试试。

UI设计

主要控件就是16个展示数字的方块、1个计时用的面板、1个游戏胜利的界面以及1个新游戏按钮。如下图所示。


与2048不同的是,这次的数字方块用的是Button控件,创建该控件代码如下(注意在properties中声明Num类型为matlab.ui.control.Button):

function createNum(app)
            for i=1:4
                for j=1:4
                    app.Num(i,j) = uibutton(app.NumHuaRongUIFigure,'push');
                    app.Num(i,j).ButtonPushedFcn = createCallbackFcn(app, @NumButtonPushed,true);
                    app.Num(i,j).BackgroundColor = [0.91 0.77 0.66];
                    app.Num(i,j).Position = [-47.5+j*100 442.5-i*100 95 95];
                    app.Num(i,j).Text = '';
                    app.Num(i,j).FontName = 'Segoe UI Historic';
                    app.Num(i,j).FontSize = 40;
                    app.Num(i,j).FontColor = [1,1,1];
                    app.Num(i,j).Tag = num2str(sub2ind([4 4],i,j));
                end
            end
        end

创建对应的回调函数:

        function NumButtonPushed(app,event)  
        end  

创建胜利面板函数:

        function createGameOverLabel(app)
            app.gameOverLabel = uilabel(app.NumHuaRongUIFigure);
            app.gameOverLabel.BackgroundColor = [0.59,0.66,0.64];
            app.gameOverLabel.Position = [50,140,400,200];
            app.gameOverLabel.FontName = 'Ink Free';
            app.gameOverLabel.FontSize = 70;
            app.gameOverLabel.FontColor = [1,1,1];
            app.gameOverLabel.HorizontalAlignment = 'center';
            app.gameOverLabel.Text = "YOU WIN";
            app.gameOverLabel.Visible = 'off';
        end

其余控件建议直接使用用户界面创建。

规则设计

  • 游戏初始矩阵

我们需要一个打乱的矩阵才能开始游戏。要实现这个功能可以使用randperm()函数,其可以生成一组各不相同的整数。

            m = randperm(16,16)-1;
            m = reshape(m,4,4);
            app.theMatrix = m;
  • 点击空格旁边的方块可以使方块移动到空格

实现这个规则主要有两点:一是判断点击的方块在不在空格周围,二是交换位置。首先,空白格对应矩阵元素为0,利用find()函数可以快速确定其位置,而在空格周围可移动的最多有4个位置。我们可以将点击的方块位置索引传入,并与空白格索引比较。如果两个位置的行索引相等且列索引相差1,或者列索引相等而行索引相差1,则该方块可以与空白格交换。

        function f = isMovable(app,i,j)
            [x,y] = find(app.theMatrix == 0);
            if (i==x)&&(abs(j-y)==1)
                f = true;
            elseif  (j==y)&&(abs(i-x)==1)
                f = true;
            else
                f = false;
            end
        end

其次,交换位置就是把矩阵两个位置的值修改一下。

function moveNum(app,i,j)
            if app.isMovable(i,j)
            [x,y] = find(app.theMatrix == 0);
            app.theMatrix(x,y) = app.theMatrix(i,j);
            app.theMatrix(i,j) = 0;
            end
end  
  • 使方块按顺序排列,并且最后一格是空格即宣布游戏胜利

这个规则的实现只需用isequal()函数判断两个矩阵是否相等。

        function y = isGameWin(app)
            if isequal(app.theMatrix,app.desMatrix)
                y = true;
            else
                y = false;
            end
        end 

计时器

为了评估游戏成绩,我们可以加入一个计时器。

  • 在properties中创建一个timer
	theTimer = timer 
  • 创建一个timer的初始化函数
        function timerInit(app)
            app.theTimer.StartDelay = 1;
            app.theTimer.Period = 1;
            app.theTimer.ExecutionMode = 'fixedSpacing';
            app.theTimer.TimerFcn = @(~,~)timerCallback(app);
        end

上述代码表明timer会有1s的开始延迟,且其每隔1s会执行回调

  • 别忘了创建timer的回调函数
        function timerCallback(app)
        end
  • 在回调中修改计时器面板的值实现计时功能
            t = str2double(app.TimerPanel.Value);
            t = t+1;
            app.TimerPanel.Value = string(t);
  • 使用start()和stop()分别开始和停止计时器,别忘了在关闭APP前先删除计时器(在UIFigure的回调函数中)
        function NumHuaRongUIFigureCloseRequest(app, event)
            stop(app.theTimer)
            delete(app.theTimer)
            delete(app)            
        end

完善各回调,一个简单的数字华容道就完成了。


工程文件
用App Designer制作的数字华容道

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值