Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码

更多Java全套学习资源均在专栏,持续更新中↑↑戳进去领取~

🍅2022年全新Java学习路线图,含源码+笔记,另附在职提升课
🍅跟我20天学Java:01-计算机基础以及JDK、IDEA等安装详解
🍅跟我20天学Java:02-自动类型转换,表达式的自动类型转换,强制类型转换
🍅跟我20天学Java:03-6个案例手把手带你学循环结构

🍉Maven简介以及手把手教你下载安装

🍨Java《石头迷阵01》黑马程序员官方出版教程+源码
🍨Java《石头迷阵02》黑马程序员官方出版万字教程+源码


1,事件机制

​ 在游戏中,用户可以进行很多不同的操作。

当用户按左键时,那么空白右边的9就需要往左移。

如图所示:

在这里插入图片描述

当用户按右键时,那么空白左边的4就需要往右移。

在这里插入图片描述

当用户按上键时,那么空白下面的5就需要往上移。

在这里插入图片描述

当用户按下键时,那么空白上面的8就需要往下移。

在这里插入图片描述

当用户点击了菜单里面的重新开始时,游戏里面的数字就需要重新打乱顺序。重开一局游戏。

在这里插入图片描述

当用户点击了联系我们的时候,就需要弹出一个黑马官方公众号的二维码

在这里插入图片描述

也就是说,当用户进行不同的操作,我们要执行的代码就不一样了。

所以,此时就需要有监听机制。监听机制可以监听到用户进行的不同操作。针对于不同的操作我们可以写不同的代码。而监听到用户的操作,也叫做事件。

在刚刚的分析中:用户在键盘上进行的按键操作,就是键盘事件。

​ 用户点击不同的按钮,就是点击事件。

那么在代码中如何写呢?就要用到下面学习的接口了。

2,接口

  • Java 接口是一系列方法的声明,是一些方法特征的集合。
  • 用于制定 规则

2.1接口定义

​ 我们可以定义两个方法,当键盘按下的时候,执行按下方法里面的代码。当键盘按键松开的时候。执行松开的代码。

public class KeyListener {
   public void 按下(){
   		...     
   }
   public void 松开(){
        ...
   }
}

但是因为不同的项目中,所操作的业务逻辑是不一样的。所以这个方法里面的代码就是谁用谁写。

所以,在定义接口的时候,干脆里面的方法就不写大括号。那一旦不写大括号,上面的class也要变一下,变成interface。

所以,接口定义格式如下:

public interface KeyListener {
	public void 按下();
    public void 松开();
}

2.2接口使用

在使用一个接口时,可以定义一个类实现这个接口,并补全里面所有的方法。

此时,实现这个接口的类,叫做该接口的实现类。

代码如下:

public class MainFrame implements KeyListener {
    public void 按下() {
       ...
    }
    
    public void 松开() {
       ...
    }    
}

此时,如果我想监听键盘按键的时候,就可以使用这个接口。

当键盘任意一个按键被按下的时候,会自动调用按下这个方法。

当键盘任意一个按键松开的时候,会自动调用松开这个方法。

2.3Java中的接口

​ 这些接口,都不需要我们自己写。Java已经帮我们写好了。

如果我们想监听键盘事件,就实现KeyListener这个接口。

如果我们想监听游戏中哪个东西被点击了,就实现ActionListener接口。

​ 不管实现哪个接口,接口里面所有的方法我们都要写一遍。

3,KeyListener接口

​ 现在,我想按上下左右键之后,图片可以移动起来。那么此时必须要实现Java已经写好的KeyListener。

示例代码如下:

public class MyJFrame extends JFrame implements KeyListener {
	...
}

​ 然后把里面所有的方法自己补全。但是不需要自己手写,用鼠标点击一下红色波浪线,按下快捷键:alt+enter。这样就可以自动生成。

public class MyJFrame extends JFrame implements KeyListener {
	
    ...
    
    @Override
    public void keyTyped(KeyEvent e) {
        ...
    }

    //按下
    @Override
    public void keyPressed(KeyEvent e) {
        ...
    }

    //松开
    @Override
    public void keyReleased(KeyEvent e) {
        ...
    }
}

​ 其中有两个方法要知道,当键盘上按键被按下的时候,系统会自动调用keyPressed方法,当按键松开的时候,会自动调用keyReleased方法。所以我们可以在方法中分别写输出语句实现一下。

public class MyJFrame extends JFrame implements KeyListener {
	
    ...
    
    @Override
    public void keyTyped(KeyEvent e) {}

    //按下
    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("键盘上按键被按下了");
    }

    //松开
    @Override
    public void keyReleased(KeyEvent e) {
        System.out.println("键盘上按键松开了");
    }
}

​ 最后还要让整个界面绑定一下键盘监听事件。

​ 此时就相当于有一个人在监听界面的键盘事件,如果此时键盘按下了,则会自动调用对应的方法

public void initFrame() {
    ...
    //让界面添加键盘监听
    this.addKeyListener(this);
    ...
}

​ 游戏启动后,如果没有按键盘上的键,那么这两个方法不会被调用。
如果我们按下任意一个键,会发现。控制台输出:

键盘上按键被按下了
键盘上按键松开了

这可以说明三件事情:

  • 按键时,会有多个动作。先是按下动作,最后是松开动作。
  • 按下按键时,keyPressed自动被调用。不需要我们自己调用。
  • 松开按键时,keyReleased自动被调用。不需要我们自己调用。

细节:当我们要写代码实现按某一个键实现对应的逻辑时,一般会把代码写在松开的方法中。

4,键位与数字的对应关系

​ 在刚刚我们已经监听到了键盘事件了。但是有一个问题,不管我们按下什么键,都会去自动调用keyPressed方法,不管我们松开什么键,都会自动调用keyReleased方法。

​ 所以我们还要对按键进行一个判断。

​ 在Java中,键盘上的每一个键位都会跟一个数字一一对应。

  • 左键 — 37
  • 上键 — 38
  • 右键 — 39
  • 下键 — 40

这些数字不需要我们记住。可以通过getKeyCode方法获取到。

代码示例:

public class MyJFrame extends JFrame implements KeyListener {
	
    ...
    
    @Override
    public void keyTyped(KeyEvent e) {}

    //按下
    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("键盘上按键被按下了");
    }

    //松开
    @Override
    public void keyReleased(KeyEvent e) {
        //获取按键对应的数字
        int keyCode = e.getKeyCode();
        //打印数字
        System.out.println(keyCode);
        System.out.println("键盘上按键松开了");
    }
}

那么这样,我们通过对这些数字判断就可以实现移动效果了。

5,图片移动

​ 咱们已经学习了事件机制的相关知识,那么下面我们就让图片动起来。

我们可以获取到按键对应的数字,然后对数字进行判断。

针对于不同的按键,执行不同的代码逻辑。

步骤:

​ 1,在keyReleased方法中获取按键对应的数字

​ 2,定义一个move方法。在move方法中对上下左右进行判断。

​ 3,在keyReleased中调用move方法,并传递按键对应的数字。

​ 4,移动之后要重新绘制整个游戏界面。

代码示例:

public class MyJFrame extends JFrame implements KeyListener {
	
    ...
    
    @Override
    public void keyTyped(KeyEvent e) {}

   //松开
    @Override
    public void keyReleased(KeyEvent e) {
        //获取按键的数字
        int keyCode = e.getKeyCode();
        //调用move方法并传递数字
        move(keyCode);
    }

    //判断上下左右,来执行不同的代码
    public void move(int keyCode) {
        if (keyCode == 37) {
            //左
            //表示空格右边的图片要向左移动
            datas[x0][y0] = datas[x0][y0 + 1];
            datas[x0][y0 + 1] = 0;
            y0++;
        } else if (keyCode == 38) {
            //上
            //表示空格下面的图片要向上移动
            datas[x0][y0] = datas[x0 + 1][y0];
            datas[x0 + 1][y0] = 0;
            x0++;
        } else if (keyCode == 39) {
            //右
            //表示空格在左边的图片要向右移动
            datas[x0][y0] = datas[x0][y0 - 1];
            datas[x0][y0 - 1] = 0;
            y0--;
        } else if (keyCode == 40) {
            //下
            //表示空格在上面的图片要向下移动
            datas[x0][y0] = datas[x0 - 1][y0];
            datas[x0 - 1][y0] = 0;
            x0--;
        } else {
            System.out.println("只能按上下左右");
        }
    }
    
    public void initImage() {
        //表示将界面中原来所有的图片全部删除
        this.getContentPane().removeAll();

        ...//中间的代码不用动

        //将整个界面重新绘制
        this.getContentPane().repaint();
    }

    
}

6,作弊码

​ 到目前为止,游戏的主体功能都已经全部写完了。那么下面,我们再添加一些额外的小功能。首先是作弊码。

​ 当我们在玩游戏的时候,觉得自己可能无法通关了。那么就可以按这个作弊码一键通关,惊呆你的小伙伴。

首先,咱们得定一个按键是作弊码。假设,我定w为作弊码。当我按下w的时候,就可以一键通关。

但是此时我还不知道w按键对应的数字怎么办啊?其实没关系,打印一下就可以了。

public class MyJFrame extends JFrame implements KeyListener {
	
    ...
    
    @Override
    public void keyTyped(KeyEvent e) {}

   //松开
    @Override
    public void keyReleased(KeyEvent e) {
        //获取按键的数字
        int keyCode = e.getKeyCode();
        //打印数字
        System.out.println(keyCode);
        //调用move方法并传递数字
        move(keyCode);
    }
    ...
}

​ 我们可以在keyReleased方法中获取按键对应的数字,再把数字打印出来。启动游戏之后,我们按下w键。

控制台输出:

87

此时就证明,w按键对应的数字为87。

​ 在move方法中,加上对87的判断就可以了。如果按下87的时候,直接将二维数组中的数字变成最终的数字。

代码示例:

public void move(int keyCode) {
        ...
        } else if (keyCode == 87) {
            //w 表示作弊码
            datas = new int [][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
        }
		...
    }

7,判断胜利

​ 现在游戏可以正常玩耍了,也可以用作弊码一键通关。但是有一个小问题。当游戏成功通关之后,根本没有胜利提示,这让我绞尽脑汁之后总感觉少了一点成就感(如下左图所示)。我想着如果游戏成功通关后,在界面上有成提示,那么玩起来也有一点动力。很多人玩单机游戏,都想看看通关之后的画面是什么样的。所以,我就要在通关之后,加上一个胜利标志(如下右图所示)。

在这里插入图片描述

其实胜利标志就是一张图片而已。在资料的image文件中有一张win.png。在游戏通关之后,把他显示出来即可。如下图所示:

在这里插入图片描述

所以,我们在每次绘制整个页面之前,都要判断一下二维数组中的数字是否已经排列成功,如果已经排列成功,那么就显示胜率图标,如果没有排列成功,就不显示胜利图标。

步骤:

​ 1,定义一个方法victory,需要判断datas数组中数字是否排列成功,将判断结果返回。

​ 2,对victory方法的结果进行判断。

​ 3,如果为真,则加载胜利图标,如果为假,则不加载。

7.1带有返回值的方法

​ 其中带有返回值的方法,跟之前学习的方法是一样的。

7.1.1定义格式:
public 返回值类型 方法名(){
    //方法执行的代码
    return xxx;
}

在以前的方法中,不需要方法的执行结果。所以我们一律写成public void。其中void表示该方法没有返回值。

现在我们要定义victory方法,在方法中要判断二维数组中的数据。所以需要把方法比较的结果返回给调用者。

7.1.2return关键字

​ victory方法中,用了一个关键字return。

return关键字的两个使用地点:

  • 没有返回值的方法中的作用

    结束方法

  • 有返回值的方法中的作用

    1,结束方法

    2,后面紧跟方法的最终结果,将方法的最终结果返回给调用者。

注意点:

​ 方法实际返回的值,要跟返回值类型保持一致即可。

举例:

​ 如果返回整数,那么返回值类型就写int

​ 如果返回小数,那么返回值就写double

​ 如果返回字符串,那么返回值就写String

​ 现在我返回一个判断结果,要么是true,要么是false。在Java中这叫做布尔类型,用boolean表示。

7.2代码实现

判断的二维数组元素的步骤如下:

1,在类的上面定义一个新的二维数组,该二维数组中的元素是按照正确方式排列的。

2,在victory方法中,对两个二维数组进行比较即可。

​ 如果完全一致,那么返回true。

​ 只要有一个不一样,那么返回false

3,在initImage方法中对victory的结果进行判断。

​ 如果为真,表示游戏通关,显示胜利图标。

​ 如果为假,表示游戏未通关,不显示胜利图标。

public class MyJFrame extends JFrame implements KeyListener {

   ...
       
   //定义一个二维数组,元素是最终胜利的元素。
   int [][] victory = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
	
   public void initImage() {
        ...
        //判断游戏是否胜利
        if(victory()){
            //如果该方法的结果是true
            //那么就表示游戏胜利
            ImageIcon imageIcon = new ImageIcon("image\\win.png");
            JLabel jLabel = new JLabel(imageIcon);
            jLabel.setBounds(514/2-266/2,230,266,88);
            this.add(jLabel);
        }
		...
    }
    
    //判断两个数组中元素是否相同
    public boolean victory(){    
        //datas  和 victory
        for (int i = 0; i < datas.length; i++) {
            for (int j = 0; j < datas[i].length; j++) {
                if(datas[i][j] != victory[i][j]){
                    //return --- 可以写在方法当中
                        //  1,停止方法
                        //  2,将return后面的数据,返回给调用者。
                    return false;
                }
            }
        }
        return true;
    }
    ...
}

8,计步功能

​ 我们在玩游戏的时候,为了体现我们很厉害,通常都会看多少步完成了这个游戏。所以,我们也要加一个计步功能。

​ 计步功能其实就是定义一个变量,每移动一步就自增一次。将这个变量的最新值显示在界面上就可以了。

实现步骤:

​ 1,因为在多个方法中使用,所以在类的上面定义一个变量step

​ 2,在move方法中,按上下左右的时候,按一次step需要++一次。

​ 3,讲step显示在界面上。

public class MyJFrame extends JFrame implements KeyListener {
    //第一步:统计走了多少步的变量
    int step = 0;

    //第二步:move方法中step自增。
    public void move(int keyCode) {
        if (keyCode == 37) {
            //左
            //表示空格右边的图片要向左移动
            datas[x0][y0] = datas[x0][y0 + 1];
            datas[x0][y0 + 1] = 0;
            y0++;
            step++;
        } else if (keyCode == 38) {
            //上
            //表示空格下面的图片要向上移动
            datas[x0][y0] = datas[x0 + 1][y0];
            datas[x0 + 1][y0] = 0;
            x0++;
            step++;
        } else if (keyCode == 39) {
            //右
            //表示空格在左边的图片要向右移动
            datas[x0][y0] = datas[x0][y0 - 1];
            datas[x0][y0 - 1] = 0;
            y0--;
            step++;
        } else if (keyCode == 40) {
            //下
            //表示空格在上面的图片要向下移动
            datas[x0][y0] = datas[x0 - 1][y0];
            datas[x0 - 1][y0] = 0;
            x0--;
            step++;
        } else if (keyCode == 87) {
            //w 表示作弊码
            datas = new int [][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};
        }else {
            System.out.println("只能按上下左右");
        }
    }

    //第三步:将step的值显示到界面上
     public void initImage() {
	    ...
        JLabel label_step = new JLabel("步数:" + step);
        label_step.setBounds(50,20,100,20);
        this.add(label_step);
     	...
     }
}

9,重新开始

当一局游戏结束了,想重新开始玩第二局的时候,可以点击菜单里面的功能—重新游戏。

在这里插入图片描述

重新游戏,顾名思义,一切从头开始。

  • 1-15张数字图片要重新打乱顺序。
  • 计步器的值要清0。

9.1ActionListener接口

我们点击重新游戏按键是没有任何反应的,因为我们还没有监听他。

所以,我们还要学习一个接口,ActionListener接口。这个接口就可以监听用户按了游戏里面的哪些组件。

示例代码如下:

​ 如果实现多个接口,那么接口之间要用逗号隔开。

public class MyJFrame extends JFrame implements KeyListener, ActionListener {
	...
}

​ 然后把里面所有的方法自己补全。但是不需要自己手写,用鼠标点击一下红色波浪线,按下快捷键:alt+enter。这样就可以自动生成。

public class MyJFrame extends JFrame implements KeyListener, ActionListener {
	...
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("用户点击了重新开始");
    }
}   

​ 最后,还要让重新开始这个jMenuItem的去绑定一下动作监听事件。

此时就相当于有一个人在监听重新开始这个jMenuItem的动作事件,如果这个条目被点击了,就会自动的调用对应的方法。

public void initMenu() {
	jMenuItem1.addActionListener(this);
}

​ 游戏启动后,只要用户点击菜单里面的重新游戏,那么都会自动调用actionPerformed方法。

方法中的代码就会自动执行。

此时控制台输出:

用户点击了重新开始

每点一下,都会输出一次。

9.2代码实现

​ 在上面,我们已经实现了用户点击重新开始这个jMenuItem能自动的调用actionPerformed方法了。那么下面,我们只要把重新开始的逻辑代码写在actionPerformed方法中就可以了。

实现步骤:

​ 1,重新打乱数据的顺序

​ 2,计步变量清零

​ 3,重新绘制整个界面

因为上面的三步我们都已经写在单独的方法中,所以此处不需要额外再写代码。直接调用对应的方法就可以了。

代码示例:

@Override
public void actionPerformed(ActionEvent e) {
    	//重新数据打乱数据的顺序
        initData();
        //计步的变量必须清零
        step = 0;
        //绘制整个界面
        initImage();
}

10,联系我们

​ 我们继续添加一个联系我们的功能,要把这个功能放到菜单当中。

所以,我们要在菜单的JMenuBar中再添加一个JMenu,在JMenu中添加一个JMenuItem即可。

为了让我们点击这个新加的有效果,所以也要让他去绑定一个动作事件。

当点击了联系我们时,会出现一个弹框。

10.1JDialog

​ 弹框是通过JDialog实现的,我们可以把图片交给JDialog,当联系我们被点击时,JDialog自动弹出来,那么图片也就随之出现了。

实现步骤如下:

1,创建JDialog对象

2,创建ImageIcon对象

3,创建JLabel对象,并将ImageIcon交给JLabel

4,利用JLabel设置图片的大小位置。

5,把JLabel添加到JDialog中。

6,对JDialog进行一些设置。

代码示例:

 //创建了一个弹框对象
JDialog jDialog = new JDialog();
//创建了一个图片对象
ImageIcon imageIcon = new ImageIcon("image\\about.png");
JLabel jLabel = new JLabel(imageIcon);
jLabel.setBounds(0,0,344,344);
//把图片放到弹框当中
jDialog.add(jLabel);
//给弹框设置大小
jDialog.setSize(344,344);
//要把弹框在设置为顶层 -- 置顶效果
jDialog.setAlwaysOnTop(true);
//要让jDialog居中
jDialog.setLocationRelativeTo(null);
//让jDialog显示出来
jDialog.setVisible(true);

10.2代码实现

我们已经学会了JDialog,他表示一个弹框,弹框里面可以放图片,可以放文字。

现在我们想出现一张黑马公众号二维码的图片,所以我们希望让JDialog弹出一张图片。

实现步骤如下:

1,创建JMenu(关于)

2,创建JMenuItem(联系我们)

3,给JMenuItem(联系我们)绑定一个动作事件。

​ 当我们点击他时,可以自动调用actionPerformed方法。

4,在actionPerformed方法中添加判断,判断当前是点击什么。

5,如果点击的是联系我们,那么JDialog出现。

代码实现:

 @Override
    public void actionPerformed(ActionEvent e) {
        //判断,
        //如果点击的是重新开始,那么才执行下面的代码
        //如果点击的是关于我们,弹出一个对话框
        if(e.getSource() == jMenuItem1){
            //重新数据打乱数据的顺序
            initData();
            //计步的变量必须清零
            step = 0;
            //绘制整个界面
            initImage();
        }else if(e.getSource() == jMenuItem2){
            //点击了联系我们
            System.out.println("点击了联系我们");
            //创建了一个弹框对象
            JDialog jDialog = new JDialog();
            //创建了一个图片对象
            ImageIcon imageIcon = new ImageIcon("image\\about.png");
            JLabel jLabel = new JLabel(imageIcon);
            jLabel.setBounds(0,0,344,344);
            //把图片放到弹框当中
            jDialog.add(jLabel);
            //给弹框设置大小
            jDialog.setSize(344,344);
            //要把弹框在设置为顶层 -- 置顶效果
            jDialog.setAlwaysOnTop(true);
            //要让jDialog居中
            jDialog.setLocationRelativeTo(null);
            //让jDialog显示出来
            jDialog.setVisible(true);
        }else{
            System.out.println("没有这个案按键");
        }
    }

11,最终优化

11.1分包

11.1.1作用

​ 游戏的主体代码和一个额外的功能,我们已经写完了。写完之后发现,idea左侧的类太多了。我们想找非常的麻烦。其中只有两个类是跟游戏相关的,其他所有的类,都是学习一些知识点时新建的。

如下图所示:

在这里插入图片描述

​ 所以,为了方便管理这些java文件,我们会再次新建文件夹。在Java中,文件夹也称之为包。针对不同功能的文件夹会新建不同的包来进行管理。

​ 我们现在可以新建两个包,一个用来放游戏相关的,一个用来放学习时候用来演示的类。

11.1.2创建包的步骤:
  • 右键点击src,选择new,再选择Package
  • 给包起个名字,名字要见名知意。
  • 新建两个包。
    • 一个起名gamecode:里面存放跟游戏相关的两个java文件。
    • 一个起名demo:里面都是讲解知识点时用来演示的Java文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YW98CXJH-1646910262429)(img\新建包.png)]

11.2游戏异常

​ 到目前为止,游戏还剩下最后一个问题。

如下图所示:

在这里插入图片描述

在控制台上出现了很多红色文字,但是游戏在玩的时候不受影响。

出现了红色文字,代表我们代码出现了异常,也就是某些地方写错了。

这个问题在四种情况下会出现。

  • 当空白区域出现在最右侧时,再按左键。
  • 当空白区域出现在最左侧时,再按右键。
  • 当空白区域出现在最上侧时,再按下键。
  • 当空白区域出现在最下侧时,再按上键。

这是为什么呢?其实很简单,我们以图中的情况为例。

此时,当空白区域出现在最右侧时,再按左键,控制台出现异常。

那是因为,按下左键时,需要把空白区域右侧的数字图片左移,而图中空白区域右侧没有数字图片可以移动了,所以出错了。同理,其他三种情况也是一样的。没有东西可以移动了,你还硬要让他移,肯定就出错了。

所以,我们就要针对这四种情况进行优化。

  • 当空白区域出现在最右侧时,再按左键时,不再移动。
  • 当空白区域出现在最左侧时,再按右键时,不再移动。
  • 当空白区域出现在最上侧时,再按下键时,不再移动。
  • 当空白区域出现在最下侧时,再按上键时,不再移动。

代码示例:

public void move(int keyCode) {
    if (keyCode == 37) {
        //左
        //表示空格右边的图片要向左移动
        if(y0 == 3){
            //1,结束方法
            //2,如果我要把方法的结果进行返回,那么可以在return写上对应的值。
            return;
        }
        datas[x0][y0] = datas[x0][y0 + 1];
        datas[x0][y0 + 1] = 0;
        y0++;
        step++;

    } else if (keyCode == 38) {
        if(x0 == 3){
            return;
        }
        //上
        //表示空格下面的图片要向上移动
        datas[x0][y0] = datas[x0 + 1][y0];
        datas[x0 + 1][y0] = 0;
        x0++;
        step++;
    } else if (keyCode == 39) {
        if(y0 == 0){
            return;
        }
        //右
        //表示空格在左边的图片要向右移动
        datas[x0][y0] = datas[x0][y0 - 1];
        datas[x0][y0 - 1] = 0;
        y0--;
        step++;
    } else if (keyCode == 40) {
        if(x0 == 0){
            return;
        }
        //下
        //表示空格在上面的图片要向下移动
        datas[x0][y0] = datas[x0 - 1][y0];
        datas[x0 - 1][y0] = 0;
        x0--;
        step++;
    } else if (keyCode == 87) {
        //w 表示作弊码
        datas = new int [][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,0}};

    }else {
        System.out.println("只能按上下左右");
    }
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值