用App Designer 制作2048小游戏

本文详细介绍了如何使用MATLAB的AppDesigner制作2048小游戏,包括APP界面设计、游戏规则设计、矩阵操作、事件处理以及界面更新等关键步骤。此外,还涉及到了游戏结束条件判断、音乐播放功能和文件读写操作。通过循环创建控件的方法,实现了界面元素的批量生成。
摘要由CSDN通过智能技术生成

用App Designer 制作2048小游戏

用App Designer制作的2048,MATLAB版本是2020b。记录下创作思路,以免日后忘记。

APP界面设计

APP界面如下,为了好玩,还加入了游戏进行时播放音乐的功能。
下面是游戏结束界面:

除了按钮和开关部分,其余都可用标签控件制作。游戏结束界面在制作时将其Visible属性设为Off(确保在主界面上层),当判定游戏结束时再将Visible属性修改为On即可。

               app.gameOverLabel.Visible = 'on';
               app.gameOverLabel2.Visible = 'on';
               app.gameOverLabel3.Visible = 'on';

标签和按钮上的文字通过其Text属性修改
按钮上的图案可通过修改其Icon属性改变

规则设计

游戏每一步可以选择“上、下、左、右”中的一项操作,每项操作需关注三点,一是数字格向空白格的转移,二是相同数字格的合并相加,三是移动完成后会随机将一个空白格变为2。

我们不可能直接对方格进行操作,考虑将其与一个 4 × 4 4\times4 4×4矩阵对应起来,则数字格向空白格的转移可以这样做:
设有 2 × 3 2\times3 2×3矩阵 A \bm{A} A
[ 1 0 2 3 4 5 ] \left[\begin{array}{l} 1 &0 &2 \\ 3 &4 &5 \end{array}\right] [130425]
现要把第二行“向上推”,即要使数字“4”的位置由 ( 2 , 2 ) (2,2) (2,2)变为 ( 1 , 2 ) (1,2) (1,2),而 ( 2 , 2 ) (2,2) (2,2)在数字“4”被“推走”后变为0,矩阵 A \bm{A} A变为 A ′ \bm{A^{'}} A
[ 1 4 2 3 0 5 ] \left[\begin{array}{l} 1 &4 &2 \\ 3 &0 &5 \\ \end{array}\right] [134025]
设有一个 1 × 3 1\times3 1×3的临时矩阵 T \bm{T} T A \bm{A} A从第二行取出 T \bm{T} T加到第一行得到 A ′ \bm{A^{'}} A
A ′ = A − ( 0 T ) + ( T 0 ) \bm{A^{'}}= \bm{A}- \left(\begin{array}{l}\bm{0} \\ \bm{T}\end{array}\right) + \left(\begin{array}{l}\bm{T} \\ \bm{0}\end{array}\right) A=A(0T)+(T0)
那么不难得到 T = [ 0 4 0 ] \bm{T}=[0\quad4\quad0] T=[040]
如何计算呢?
只需用 A ( 2 , : ) \bm{A}(2,:) A(2,:)点乘 [ 0 1 0 ] [0\quad1\quad0] [010] [ 0 1 0 ] [0\quad1\quad0] [010] 就是将 A ( 1 , : ) \bm{A}(1,:) A(1,:)非零元素变为 0 0 0,零元素变为 1 1 1得到的。
T = A ( 2 , : ) ⊙ ∼ A ( 1 , : ) \bm{T} = \bm{A}(2,:)\odot \thicksim\bm{A}(1,:) T=A(2,:)A(1,:)

            temp = ~app.theMatrix(4-i,:).*app.theMatrix(5-i,:);
            app.theMatrix(4-i,:) = app.theMatrix(4-i,:) + temp;
            app.theMatrix(5-i,:) = app.theMatrix(5-i,:) - temp;

相同数字格的合并相加也有类似的计算方法。
在空白格随机生成数字“2”怎么实现呢?
首先要确定空白格的位置,即矩阵中零元素的位置。在MATLAB中用find()函数来获取目标元素的索引。

			zeroIndex = find(app.theMatrix == 0);

然后用randperm()生成一个随机整数,这个随机整数不能大于矩阵零元素的个数。我们利用这个随机整数来确定一个零元素的位置,然后以“2”替换该零元素。
当矩阵中没有零元素,并且相邻元素也各不相同时,应当判定游戏结束。

后端到前端

要把矩阵映射到游戏主界面,有两个需求:一是对应位置的数字显示,其中“0”不显示;二是不同数字对应着不同的背景颜色。这个只需要对每个方格的Text属性和BackGroundColor属性依次赋值就行,注意Text属性应当用字符串类型赋值,为此可以使用string()函数将数值矩阵转换为字符串矩阵。

            strMatrix = string(app.theMatrix);

特别地,零元素应当转换成空字符串。

            strZeroIndex = strMatrix == "0";
            strMatrix(strZeroIndex) = "";

每进行一步操作都要将主界面更新一遍,在此更新中分数界面应当一并更新。

按钮回调

按前面所说的方式分别设计向上键、向下键、向左键和向右键的回调函数,包含两部分:一是对矩阵进行修改,二是将修改后的矩阵映射到主界面。点击按钮的任务用键盘也能完成,我们可以添加键盘回调,并在其中关联按钮回调。使用WindowKeyRelease将会按键释放时执行回调。

        function UIFigureWindowKeyRelease(app, event)
            key = event.Key;
            switch(key)
                case {"uparrow","w"}
                   app.buttonUpButtonPushed();
                case {"downarrow","s"}
                   app.buttonDownButtonPushed(); 
                case {"leftarrow","a"}
                   app.buttonLeftButtonPushed();
                case {"rightarrow","d"}
                   app.buttonRightButtonPushed(); 
            end
         end

除了上下左右键,这里还设计了“重新游戏”和“清除”。“重新游戏”将会清零所得分,使游戏主界面恢复到初始状态。游戏中的最高分将会保存到文件中,下次打开APP时,程序会读取文件记录的最高分。使用“重新游戏”并不会清除最高分记录,而使用“清除”将会修改文件记录的最高分为0。
如果使用fread()和fwrite()读写文件,注意读写格式。若使用默认的读写格式,可能会因位数不够而无法读写较大的游戏分数。

            f = fopen(app.dataPath,'r');
            if f>0
                app.bestScore = fread(f,'int32');
                fclose(f);
            end

运行方式

在我们运行程序后,首先APP界面及我们添加的控件会被加载出来,然后执行startupFcn()函数。在此之后,程序会等待我们触发回调,当回调对应的event发生时,执行回调。
以本项目为例,startupFcn()函数如下

        function startupFcn(app)
            app.loadMusic(); 
            app.scoreStart();
            app.nextStep();
            app.nextStep();
        end

首先,用loadMusic()函数加载音乐,之后我们可以用开关来控制音乐的暂停和播放。接下来用scoreStart()将得分清零,并从文件中读取最高分。然后使用nextStep()刷新界面,因为游戏初始有两个“2”,而nextStep()只能产生一个,所以使用两次。


关于批量创建控件

App Designer可以使用代码快速创建控件。如本例的16个数字方格,我们可以通过循环的方式快速创建控件并完成配置。
首先在properties中添加控件名,如

        Num                 matlab.ui.control.Label 

其中,Num是控件名,后面的 matlab.ui.control.Label 表明了Num是Label控件。之后,我们写一个创建控件的函数。

        function  createNum(app)
            for i=1:4
                for j=1:4
                    app.Num(i,j) = uilabel(app.UIFigure);
                    app.Num(i,j).BackgroundColor = [0.902 0.902 0.8];
                    app.Num(i,j).HorizontalAlignment = 'center';
                    app.Num(i,j).FontName = 'Calibri';
                    app.Num(i,j).FontSize = 40;
                    app.Num(i,j).Position = [-60+100*j 440-100*i 90 90];
                    app.Num(i,j).Text = ''; 
                end
            end
        end

注意需要在properties中声明Num的类型才能对控件的属性进行点索引。


对应的工程文件包
2048小游戏——基于MATLAB App Designer
因为包含了音乐文件,所以比较大。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值